Bootstrap 3 collapse can have multiple panels open after programmatically opening a panel

Bootstrap 3 collapse can have multiple panels open after programmatically opening a panel

I have a problem with bootstrap 3 collapse, after opening a panel programmatically it is possible to keep another panel open while reopening the first panel.
My HTML:




Contents panel 1

Contents panel 2

Contents panel 3

And some JavaScript:
$(“.hidepanel”).on(“click”, function() {
$(“#panel3”).parent().hide();
});
$(“.showpanel”).on(“click”, function() {
$(“#panel3”).parent().show();
});
$(“.openpanel”).on(“click”, function() {
$(“#panel3”).collapse(‘show’);
});
$(“.closepanel”).on(“click”, function() {
$(“#panel3”).collapse(‘hide’);
});

My jsfiddle that demonstrates this issue
To reproduce:

Click the button ‘Open panel 3’.
Click ‘Panel 2’ to open it. So far no problems.
Click ‘Panel 3’ to open it again. Panel 2 remains open!

So opening a panel programmatically seems to mess up bootstraps internal registration about panel states? I don’t see anything visibly wrong with the ‘state change’ of the third panel (it’s class changes from ‘collapse’ to ‘in’ and back as you would expect).

Related:  Hide and show depending on screen size bootstrap 3 classes

Solutions/Answers:

Solution 1:

You can create a handler for the collapse show event which occurs just before any panels are displayed.

Add this to ensure any other open panels are closed before the selected one is shown:

$('#accordion').on('show.bs.collapse', function () {
    $('#accordion .in').collapse('hide');
});

Bootply demo

You can read more about the collapse events here: http://getbootstrap.com/javascript/#collapse

Solution 2:

I think the problem is due to the way you are changing the open panel. Rather than using the ‘show’ feature you need to fire the click event on the appropriate panel link. For example with an accordion with an id “accordion”, with three panels, if you want to show the 2 panel then use:

$("a[href=#accordion-2]").click()

Or whatever ID you have given your second panel (I use twitterboostrapmvc so the panel ids are auto-generated from the accordion ID).

Solution 3:

For anyone using data-target attributes to control the accordion (rather than the href attribute), this is an adaptation of ProfNimrod’s answer which will click the relevant element if the target is currently hidden. (Note that the if check relies on setting up the accordion with the collapsed class applied by default, which I find useful anyway to take advantage of using css to put a chevron icon on the accordions).

var expandAccordion = function() {
    var header = $('[data-target="#accordion-0"]');
    if (header.hasClass('collapsed')) {
        header.click();
    }
}

References

Related:  twitter bootstrap 3 input-group-addon with btn-group not the same size