web-dev-qa-db-fra.com

Le bouton Bootstrap Accordion bascule "Data-parent" ne fonctionne pas

J'essaie de créer un accordéon à l'aide de Bootstrap 3 en utilisant le bouton compressible avec l'attribut data, sans le balisage accordéon. Cela me semble plus propre. 

Cependant, je ne peux pas faire fonctionner l'attribut data-parent. Je veux quand vous ouvrez une question, tous les autres à fermer. Je lis la documentation ( http://getbootstrap.com/javascript/#collapse-usage ), mais je n'arrive toujours pas à le faire fonctionner.

J'utilise le code suivant:

<div class="accordion" id="myAccordion">
    <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">
    <p>Etiam posuere quam ac quam. Maecenas aliquet accumsan leo. Nullam dapibus fermentum ipsum. Etiam quis quam. Integer lacinia. Nulla est.</p>
    </div>
    <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">
    <p>Etiam posuere quam ac quam. Maecenas aliquet accumsan leo. Nullam dapibus fermentum ipsum. Etiam quis quam. Integer lacinia. Nulla est.</p>
    </div>
    <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">
    <p>Etiam posuere quam ac quam. Maecenas aliquet accumsan leo. Nullam dapibus fermentum ipsum. Etiam quis quam. Integer lacinia. Nulla est.</p>
    </div>
</div>

Voici le JSFiddle: http://jsfiddle.net/twinsen/AEew4/

Je serai très heureux si quelqu'un me montre où je fais une erreur: \

53
Ziik

Bootstrap 4

Utilisez l'attribut data-parent="" sur l'élément collapse (au lieu de l'élément déclencheur)

<div id="accordion">
  <div class="card">
    <div class="card-header">
      <h5>
        <button class="btn btn-link" data-toggle="collapse" data-target="#collapseOne">
          Collapsible #1 trigger
        </button>
      </h5>
    </div>
    <div id="collapseOne" class="collapse show" data-parent="#accordion">
      <div class="card-body">
        Collapsible #1 element
      </div>
    </div>
  </div>
  ... (more cards/collapsibles inside #accordion parent)
</div>

Bootstrap 3

Voir ce numéro sur GitHub: https://github.com/twbs/bootstrap/issues/10966

Un "bogue" rend l'accordéon dépendant de la classe .panel lors de l'utilisation de l'attribut data-parent. Pour contourner ce problème, vous pouvez envelopper chaque groupe d'accordéon dans une division 'panel' ..

http://bootply.com/88288

<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>

Modifier

Comme mentionné dans les commentaires, chaque section ne doit pas obligatoirement être un .panel. Toutefois...

  • .panel doit être un enfant direct de l'élément utilisé en tant que data-parent=
  • chaque section d'accordéon (data-toggle=) doit être un enfant direct du .panel ( http://www.bootply.com/AbiRW7BdD6# )
124
Zim

Notez que non seulement il existe une dépendance sur .panel, mais également sur la structure DOM.

Assurez-vous que vos éléments sont structurés comme ceci:

    <div id="parent-id">
        <div class="panel">
            <a data-toggle="collapse" data-target="#opt1" data-parent="#parent-id">Control</a>
                <div id="opt1" class="collapse">
...

C'est essentiellement ce que @Blazemonger a dit, mais je pense que la hiérarchie de l'élément cible est également importante. Je n'ai pas fini d'essayer toutes les possibilités, mais au fond, cela devrait marcher si vous suivez cette hiérarchie.

Pour votre information, j'ai eu plus de couches entre le contrôle div & content div et cela n'a pas fonctionné.

13
jtlai

Essaye ça. Solution simple sans dépendances.

$('[data-toggle="collapse"]').click(function() {
  $('.collapse.in').collapse('hide')
});

10
Melih

Comme le dit Blazemonger, #parent, .panel et .collapse doivent être des descendants directs. Toutefois, si vous ne pouvez pas modifier votre code html, vous pouvez effectuer la solution de contournement à l'aide d'événements et de méthodes bootstrap à l'aide du code suivant:

$('#your-parent .collapse').on('show.bs.collapse', function (e) {
    var actives = $('#your-parent').find('.in, .collapsing');
    actives.each( function (index, element) {
        $(element).collapse('hide');
    })
})
8
Krzysztof Grzybek

Voici un correctif universel (espérons-le) que j'ai développé pour résoudre ce problème pour BootStrap V3. Aucune exigence particulière autre que de brancher le script.

$(':not(.panel) > [data-toggle="collapse"][data-parent]').click(function() {
    var parent = $(this).data('parent');
    var items = $('[data-toggle="collapse"][data-parent="' + parent + '"]').not(this);
    items.each(function() {
        var target = $(this).data('target') || '#' + $(this).prop('href').split('#')[1];
        $(target).filter('.in').collapse('hide');
    });
});

EDIT: Voici une réponse simplifiée qui répond toujours à mes besoins, et j'utilise maintenant un gestionnaire de clics délégué:

$(document.body).on('click', ':not(.panel) > [data-toggle="collapse"][data-parent]', function() {
    var parent = $(this).data('parent');
    var target = $(this).data('target') || $(this).prop('hash');
    $(parent).find('.collapse.in').not(target).collapse('hide');
});
2
craigrs84

Si trouvé cette modification à la réponse de Krzysztof a aidé mon problème

$('#' + parentId + ' .collapse').on('show.bs.collapse', function (e) {            
    var all = $('#' + parentId).find('.collapse');
    var actives = $('#' + parentId).find('.in, .collapsing');
    all.each(function (index, element) {
      $(element).collapse('hide');
    })
    actives.each(function (index, element) {                
      $(element).collapse('show');                
    })
})    

si vous avez des panneaux imbriqués, vous devrez peut-être également spécifier ceux-ci en ajoutant un autre nom de classe pour les distinguer et en ajoutant ceci au sélecteur dans le code JavaScript ci-dessus 

2
kernowcode

J'ai eu le même problème en changeant d'accordéon. Mais quand j'essaie de mettre le bloc de script dans le bloc d'en-tête, cela fonctionne dans mon cas !!

<head>   
...   
<link rel="stylesheet" href="../assets/css/bootstrap.css" />       
<script src="../assets/js/jquery-1.9.1.min.js" ></script>   
<script src="../assets/js/bootstrap.js" ></script> 
</head>
0
Enix