Bootstrap: js .collapse() invocations don't toggle the .collapsed class for any of the collapse control elements

Created on 20 May 2014  路  9Comments  路  Source: twbs/bootstrap

Took me a while to track down a repro case, but I finally managed to pin it down.

Repro example: http://jsbin.com/jatatucojuru/1/edit

The docs say

If you'd like it to default open, add the additional class in.

And then to "Via JavaScript":

 $('.collapse').collapse()

If I do this (add "in" to the accordions's class, and then invoke $('.collapse').collapse() on load), the accordion elements lack the .collapsed class on the .panel-heading as you can see below:

google chrome

If you manually just trigger the same accordions by clicking on them a few times, everything starts working fine again:

google chrome

confirmed js

Most helpful comment

Partial solution:

$('body').on('click', '[data-toggle="collapse"]', function () {
var collapsedId = $(this).attr('href');
var isVisible = $(collapsedId + ' .panel-body').is(':visible');

    if (isVisible == true) {
        $(collapsedId).collapse('hide');
        return false;
    }
})

All 9 comments

It looks like this code: https://github.com/twbs/bootstrap/blob/master/js/collapse.js#L173 never gets called in any of the
.collapse('hide')/.collapse('show')/.collapse('toggle') javascript invocations - only when the element gets clicked on.

The corollary "show" bug also exists:

If the control element has the .collapsed class on it, and you call:

$("#collapseOne").collapse('show');

The control element will still have the .collapsed class on it:

google chrome

First invocation of collapse seems to only work properly with object literal syntax.
so instead of .collapse('hide'); use .collapse({toggle: false});
We used this as a work around in our code. hope this helps.

@cvrebert When I looked at the JS code I just wasn't familiar enough with the design to implement it myself, the help wanted might be a good label to add again perhaps, I believe it is a JS issue & need to work it into the current architecture somehow

@djihbril My work around was to add:

$("#accordion-blog-navigation .panel-heading").addClass('collapsed');

This seems like a documentation affair. The collapsed class isn't added because it isn't needed. Also, you don't actually need to call $.fn.collapse to initialize the plugin because there is nothing the initialization does except for setting some internal variables. If for whatever reason you want to call $.fn.collapse and don't expect any automatic toggling you'd need to pass toggle: false in the option object.
Edit: Interestingly, the unit tests for the collapsed class don't fail even though they check if it is present.

This still feels bugged to me, and not just a documentation oversight if I trigger .collapse('hide'); it seems reasonable it would add any necessary classes I need. For the record, we only call $.fn.collapse when we're trying to toggle the default behavior, there is no initialization invocation:

<% content_for("jquery") { %>
  if (matchMedia('only screen and (max-width: 992px)').matches) {
    $("#collapse-<%=Normalize.lowerAlphanumeric(title)%>").collapse('hide');
    $("#accordion-<%=Normalize.lowerAlphanumeric(title)%> .panel-heading").addClass('collapsed'); <%# This is a work around for a BS3 bug: https://github.com/twbs/bootstrap/issues/13636 %>
  }
<% } %>

Effectively, trying to use the matchMedia query to collapse some navigation elements on mobile/tablet, but have them defaulted to "in" on desktop. Maybe there is a better way to do that :)

You are right. I don't think I was getting what exactly the problem is.

@hnrch02 Thanks a bunch! Can't wait to remove my monkey-patch work around!

Partial solution:

$('body').on('click', '[data-toggle="collapse"]', function () {
var collapsedId = $(this).attr('href');
var isVisible = $(collapsedId + ' .panel-body').is(':visible');

    if (isVisible == true) {
        $(collapsedId).collapse('hide');
        return false;
    }
})
Was this page helpful?
0 / 5 - 0 ratings

Related issues

MrCsabaToth picture MrCsabaToth  路  3Comments

knownasilya picture knownasilya  路  3Comments

kamov picture kamov  路  3Comments

ziyi2 picture ziyi2  路  3Comments

bellwood picture bellwood  路  3Comments