Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
    });
like image 884
Murphy1976 Avatar asked Mar 01 '17 17:03

Murphy1976


People also ask

How do you collapse the accordion bootstrap?

Just add data-toggle="collapse" and a data-target to the element to automatically assign control of one or more collapsible elements. The data-target attribute accepts a CSS selector to apply the collapse to. Be sure to add the class collapse to the collapsible element.

How do you collapse an accordion by default?

To create an accordion that is collapsed by default, we need to set the 'active' property of the jQuery Accordion as false. Syntax: $("#demoAccordion"). accordion({ collapsible: true, active: false});

How does collapse work in bootstrap?

How it works. The collapse JavaScript plugin is used to show and hide content. Buttons or anchors are used as triggers that are mapped to specific elements you toggle. Collapsing an element will animate the height from it's current value to 0 .

How do I know if Bootstrap accordion is open?

Bootstrap uses the aria-expanded attribute to show true or false if the region is collapsed or not.


2 Answers

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.

like image 121
Zim Avatar answered Sep 29 '22 22:09

Zim


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>
like image 45
artemisian Avatar answered Sep 29 '22 23:09

artemisian