简体   繁体   中英

Bootstrap Accordion Expand/Collapse All not functioning properly

Here's the process to break this:

  1. click Music Notation
  2. click Expand/Collapse All
  3. click Music Notation
  4. click Expand/Collapse All
  5. click Expand/Collapse All again

Notice how Music Notation will NOT open back up, even though, you should be able to see in the function, that the logic says that ALL panels are closed and should open. WHY? What am I doing wrong?

HTML:

<button class="btn btn-default btn-sm btn-exp" id="expandAllFormats">Expand/Collapse All</button>
<div class="panel-group checkbox-group" id="accordionFormat" role="tablist" aria-multiselectable="true">

<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a id="accordionformatText" role="button" data-toggle="collapse" data-parent="#accordionFormat" href="#formatText">
<i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Text
</a>
</h4>
</div>
<div id="formatText" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">ALPHA</div>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a id="accordionformatArt" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionFormat" href="#formatArt">
<i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Art
</a>
</h4>
</div>
<div id="formatArt" class="panel-collapse collapse" aria-expanded="false" role="tabpanel">
<div class="panel-body">BETA</div>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a id="accordionformatAudio" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionFormat" href="#formatAudio">
<i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Audio
</a>
</h4>
</div>
<div id="formatAudio" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">GAMMA</div>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a id="accordionformatNotation" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionFormat" href="#formatNotation">
<i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Music Notation
</a>
</h4>
</div>
<div id="formatNotation" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">DELTA</div>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a id="accordionformatVideo" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionFormat" href="#formatVideo">
<i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Video
</a>
</h4>
</div>
<div id="formatVideo" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">EPSILON</div>
</div>
</div>

<div class="panel panel-default">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a id="accordionformatInteractive" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordionFormat" href="#formatInteractive">
<i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Digital Interactive
</a>
</h4>
</div>
<div id="formatInteractive" class="panel-collapse collapse" role="tabpanel">
<div class="panel-body">ZETA</div>
</div>
</div>
</div>

JS:

var toggleFormat = false;
$('#expandAllFormats').on('click', function(e) {
        e.preventDefault();
        console.log(toggleFormat);
        $("#accordionFormat .panel-collapse").each(function(index, value){
            if (toggleFormat){
                if($(this).hasClass('in')){
                    $(this).collapse('toggle');
                    console.log("This panel is open. it will be closed");
                } else {
                    console.log("This panel is closed. it will stay closed");
                }
            } else {
                if(!$(this).hasClass('in')){
                    $(this).collapse('toggle');
                    console.log("This panel is closed. it will be open");
                } else {
                    console.log("This panel is open. it will stay open");
                }
            }

        });
        toggleFormat = toggleFormat ? false : true;
    });

The problem is that the state of all panels is different than the state of any single panel because of the way accordion works with data-parent . Your expand/collapse all button handler needs to completely override that normal accordion behavior.

The expand/collapse all click handler must keep track of the last state (expand all or collapse all ), because the Bootstrap Collapse component is seperately handing the state of each single panel (only one open at a time). Otherwise, there would be no way to know whether to open or close the individually toggled panels.

$('#expandAllFormats').on('click', function () {

   if ($(this).data("lastState") === null || $(this).data("lastState") === 0) {

        // close all
        $('.collapse.in').collapse('hide');

        // next state will be open all
        $(this).data("lastState",1);
        $(this).text("Expand All");

    }
    else {

        // initial state...
        // override accordion behavior and open all
        $('.panel-collapse').removeData('bs.collapse')
        .collapse({parent:false, toggle:false})
        .collapse('show')
        .removeData('bs.collapse')
         // restore single panel behavior
        .collapse({parent:'#accordionFormat', toggle:false});

        // next state will be close all
        $(this).data("lastState",0);
        $(this).text("Collapse All");
    }

});

http://codeply.com/go/76Hl6s49rb

OFC, another way is to simply remove the data-parent= attributes and completely disable the accordion behavior.

If you can afford to remove the data-parent attribute data-parent="#accordionFormat" from all elements where it exists it will solve your issue.

Why? I'm not sure but it seems that attribute triggers some logic that messes up with the collapse functionality.

 var toggleFormat = false; $('#expandAllFormats').on('click', function (e) { e.preventDefault(); console.log(toggleFormat); $("#accordionFormat .panel-collapse").each(function (index, value) { if (toggleFormat) { if ($(this).hasClass('in')) { $(this).collapse('toggle'); console.log("This panel is open. it will be closed"); } else { console.log("This panel is closed. it will stay closed"); } } else { if (!$(this).hasClass('in')) { $(this).collapse('toggle'); console.log("This panel is closed. it will be open"); } else { console.log("This panel is open. it will stay open"); } } }); toggleFormat = toggleFormat ? false : true; });
 <html> <head> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> </head> <body> <button class="btn btn-default btn-sm btn-exp" id="expandAllFormats">Expand/Collapse All</button> <div class="panel-group checkbox-group" id="accordionFormat" role="tablist" aria-multiselectable="true"> <div class="panel panel-default"> <div class="panel-heading" role="tab"> <h4 class="panel-title"> <a id="accordionformatText" role="button" data-toggle="collapse" href="#formatText"> <i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Text </a> </h4> </div> <div id="formatText" class="panel-collapse collapse" role="tabpanel"> <div class="panel-body">ALPHA</div> </div> </div> <div class="panel panel-default"> <div class="panel-heading" role="tab"> <h4 class="panel-title"> <a id="accordionformatArt" class="collapsed" role="button" data-toggle="collapse" href="#formatArt"> <i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Art </a> </h4> </div> <div id="formatArt" class="panel-collapse collapse" aria-expanded="false" role="tabpanel"> <div class="panel-body">BETA</div> </div> </div> <div class="panel panel-default"> <div class="panel-heading" role="tab"> <h4 class="panel-title"> <a id="accordionformatAudio" class="collapsed" role="button" data-toggle="collapse" href="#formatAudio"> <i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Audio </a> </h4> </div> <div id="formatAudio" class="panel-collapse collapse" role="tabpanel"> <div class="panel-body">GAMMA</div> </div> </div> <div class="panel panel-default"> <div class="panel-heading" role="tab"> <h4 class="panel-title"> <a id="accordionformatNotation" class="collapsed" role="button" data-toggle="collapse" href="#formatNotation"> <i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Music Notation </a> </h4> </div> <div id="formatNotation" class="panel-collapse collapse" role="tabpanel"> <div class="panel-body">DELTA</div> </div> </div> <div class="panel panel-default"> <div class="panel-heading" role="tab"> <h4 class="panel-title"> <a id="accordionformatVideo" class="collapsed" role="button" data-toggle="collapse" href="#formatVideo"> <i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Video </a> </h4> </div> <div id="formatVideo" class="panel-collapse collapse" role="tabpanel"> <div class="panel-body">EPSILON</div> </div> </div> <div class="panel panel-default"> <div class="panel-heading" role="tab"> <h4 class="panel-title"> <a id="accordionformatInteractive" class="collapsed" role="button" data-toggle="collapse" href="#formatInteractive"> <i class="fa fa-chevron-circle-right" aria-hidden="true"></i> Digital Interactive </a> </h4> </div> <div id="formatInteractive" class="panel-collapse collapse" role="tabpanel"> <div class="panel-body">ZETA</div> </div> </div> </div> <script src="//ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM