最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Bootstrap Accordion ExpandCollapse All not functioning properly - Stack Overflow

programmeradmin11浏览0评论

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;
    });

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;
    });
Share edited May 1, 2017 at 14:59 Carol Skelly 363k92 gold badges736 silver badges647 bronze badges asked Mar 1, 2017 at 17:18 Murphy1976Murphy1976 1,4758 gold badges43 silver badges91 bronze badges 4
  • I should also note that if you click Music Notation to open that back up, it will open THAT panel, but close all the others... – Murphy1976 Commented Mar 1, 2017 at 17:22
  • Please check my answer and give it a try. – artemisian Commented Mar 1, 2017 at 19:16
  • Are you sure? I cannot reproduce the problem in the snippet on my answer. – artemisian Commented Mar 1, 2017 at 19:39
  • Maybe is b/c the bootstrap version of the snippet which is bootstrap/3.3.7 – artemisian Commented Mar 1, 2017 at 19:40
Add a ment  | 

2 Answers 2

Reset to default 3

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 pletely 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 ponent 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./go/76Hl6s49rb

OFC, another way is to simply remove the data-parent= attributes and pletely 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./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./ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn./bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

发布评论

评论列表(0)

  1. 暂无评论