web-dev-qa-db-fra.com

Comment faites-vous pour Twitter Bootstrap Accordion garder un groupe ouvert?

J'essaie d'imiter la barre Outlook en utilisant le bootstrap de Twitter en utilisant l'accordéon et le plugin collapse. Jusqu'à présent, la fermeture et l'accordéon fonctionnaient, mais cela permet actuellement de réduire toutes les sections.

Je voudrais le limiter afin qu’un seul et unique soit toujours affiché.

Voici celui sur lequel je travaille: http://jsfiddle.net/trajano/SMT9D/ et je pense que c'est quelque part dans le sens de

$('#accordions').on('hide', function (event) {
  console.warn("HIDE TRIGGERED, check if trying to hide the active one if so stop");
})
42
Archimedes Trajano

Voici un moyen facile de le faire:

Nouveau Bootstrap 3

JsFiddle pour Bootstrap 3.

Code pour Bootstrap 3:

$('.panel-heading a').on('click',function(e){
    if($(this).parents('.panel').children('.panel-collapse').hasClass('in')){
        e.stopPropagation();
    }
    // You can also add preventDefault to remove the anchor behavior that makes
    // the page jump
    // e.preventDefault();
});

Le code vérifie si l'élément cliqué est celui qui est actuellement affiché (par la classe "in") et s'il possède la classe "in", il arrête le processus de masquage.


Obsolète Bootstrap 2

JsFiddle pour Bootstrap 2.

Code pour Bootstrap 2:

$('.accordion-toggle').on('click',function(e){
    if($(this).parents('.accordion-group').children('.accordion-body').hasClass('in')){
        e.stopPropagation();
    }
    // You can also add preventDefault to remove the anchor behavior that makes
    // the page jump
    // e.preventDefault();
});

Remarque: _ ​​Faites attention si vous souhaitez associer davantage d'événements de clic sur l'accordéon, car e.stopPropagation() bloquera les événements qui se produiraient après la vérification.

70
Hugo Dozois

Je veux préciser la réponse de @ Hugo Dozois

http://jsfiddle.net/SMT9D/61/

Vous devez ajouter e.preventDefault();pour empêcher le comportement par défaut de # ancre HTML si vous avez un défilement dans votre page

$('.panel-heading a').on('click',function(e){
    if($(this).parents('.panel').children('.panel-collapse').hasClass('in')){
        e.preventDefault();
        e.stopPropagation();
    }
});
9
Aelios

Ou vous pouvez utiliser une astuce CSS simple comme suit:

/*
prevent the active panel from collapsing
 */
.panel-group [aria-expanded=true]{
  /*
  http://caniuse.com/#feat=pointer-events
  Works for MOST modern browsers. (- Opera Mobile)
  */
  pointer-events: none;
}

doit avoir les étiquettes appropriées sur les liens inactifs du panneau

 aria-expanded="false"
6
Heri Hehe Setiawan

Mise à jour 2018

Voici comment garder au moins ouvert dans Bootstrap v3 ou v4. Cela signifie que l'accordéon ouvert peut uniquement être fermé en en basculant un autre en mode open

Bootstrap 4

https://www.codeply.com/go/bbCcnl0jBB

// the current open accordion will not be able to close itself
$('[data-toggle="collapse"]').on('click',function(e){
    if ( $(this).parents('.accordion').find('.collapse.show') ){
        var idx = $(this).index('[data-toggle="collapse"]');
        if (idx == $('.collapse.show').index('.collapse')) {
            e.stopPropagation();
        }
    }
});

Aussi, voir cette réponse qui montre comment spécifier un accordéon "par défaut" à ouvrir lorsque tous les autres sont fermés.


Bootstrap 3

$('[data-toggle="collapse"]').on('click',function(e){
    if($(this).parents('.panel').find('.collapse').hasClass('in')){
        var idx = $(this).index('[data-toggle="collapse"]');
        var idxShown = $('.collapse.in').index('.accordion-body');
        if (idx==idxShown) {
            e.stopPropagation();
        }
    }
});

https://www.codeply.com/go/yLw944BrgA

<div class="accordion" id="myAccordion">
    <div class="panel">
        <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#collapsible-1" data-parent="#myAccordion">Question 1?</button>
        <div id="collapsible-1" class="collapse">
            ..
        </div>
    </div>
    <div class="panel">
        <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#collapsible-2" data-parent="#myAccordion">Question 2?</button>
        <div id="collapsible-2" class="collapse">
            ..
        </div>
    </div>
    <div class="panel">
        <button type="button" class="btn btn-danger" data-toggle="collapse" data-target="#collapsible-3" data-parent="#myAccordion">Question 3?</button>
        <div id="collapsible-3" class="collapse">
           ...
        </div>
    </div>
</div>

(Note: la classe panel est nécessaire dans Bootstrap 3 pour permet au comportement de l'accordéon de fonctionner )

3
Zim

J'ai un scénario qui ne correspond à aucune réponse postée: plusieurs accordéons sur la même page et quelques autres composants réductibles qui ne sont pas des accordéons (sans l'attribut data-parent).

$("[data-toggle=collapse][data-parent]").click(function (e) {
    var button = $(this);
    var parent = $(button.attr("data-parent"));
    var panel = parent.find(button.attr("href") || button.attr("data-target"));
    if (panel.hasClass("in")) {
        e.preventDefault();
        e.stopPropagation()
    }
});

Ce code ne déclenche que sur les accordéons, car vérifie l'attribut data-parent . Il n'assume pas non plus une structure card (ou panel pour bootstrap 3), il utilise les mêmes attributs que bootstrap api.

J'espère que ça aide.

0
kpull1

Comme toutes les autres réponses JS utilisent une fonction déconseilléestopPropagation(), voici ma solution utilisant uniquement les événements natifs Bootstrap (testés sur Bootstrap 4).

JsFiddle

$('#accordionExample').on('show.bs.collapse', function () {
    $(this).data('isShowing', true);
});

$('#accordionExample').on('hide.bs.collapse', function (event) {
    if (!$(this).data('isShowing')) {
        event.preventDefault();
    }

    $(this).data('isShowing', false);
});

Il tire parti du fait qu'un clic sur un élément réduit aboutira à un show.bs.collapse suivi d'un hide.bs.collapse. Considérant qu’un clic sur l’élément ouvert ne donnera qu’un hide.bs.collapse.

0
chris

Bootstrap 4.0

$('.card').click(function(e) {
  if (
    $(this)
      .find('.collapse')
      .hasClass('show')
  ) {
    e.stopPropagation();
  }
});

Ce bloc de code vérifie si la carte sur laquelle vous avez cliqué est réduite (en regardant le div avec la classe collapse). Lorsque la carte est actuellement shown, elle arrête propage l'événement .

0
Johannes Filter