37

I'm trying to create previous / next buttons on each accordion body.

I can't figure out a way to collapse / expand a certain section. I tried removing the class in from the accordion-body but that does not seem to collapse.

        $(".accordion-body").each(function(){
            if($(this).hasClass("in")) {
                $(this).removeClass("in");
            }
        });

Also whenever or whatever I use the .collapse method on, I get a javascript error saying that object has no method collapse.

Michael
  • 1,816
  • 7
  • 21
  • 35
  • 2
    @Nofel (editor) Please don't remove JavaScript from jQuery questions. jQuery is written in JavaScript and by removing the tag, you're removing a potential audience for these questions. – Heretic Monkey May 04 '17 at 18:39

7 Answers7

72

The in class is just an indicator that a section is open. The Javascript module applies the same inline styles as .in does, so removing the class is insufficient.

You need to use the module's API to programmatically interact with the accordion, via the .collapse() method:

$('.accordion-body').each(function(){
    if ($(this).hasClass('in')) {
        $(this).collapse('toggle');
    }
});

Or, you can condense this down to:

$('.accordion-body.in').collapse('toggle');

If you want only to collapse any open sections:

$('.accordion-body').collapse('hide');

If you want only to expanded any closed sections:

$('.accordion-body').collapse('show');
Daniel Wright
  • 4,584
  • 2
  • 27
  • 28
  • 3
    Bootstrap documentation for the above answer: http://getbootstrap.com/javascript/#collapse – Mike Richards Sep 04 '15 at 14:08
  • 10
    Doesn't work. Once you call 'collapse' on an accordion item, it stops functioning as an accordion. For example, if you had another one open and you then open the one you called 'collapse' on, the other one no longer closes as expected. See: "Bootstrap Collapse doesn't toggle after you show, hide or toggle from code" http://stackoverflow.com/questions/17750907/bootstrap-collapse-doesnt-toggle-after-you-show-hide-or-toggle-from-code – Triynko Jan 19 '16 at 19:55
  • `.collapse('show')` Works for me in v3.3.5. The docs say it requires collapse.js and the accordion plugin. – kristianp Jul 11 '18 at 01:03
5

Here is another solution:

/**
 * Make an accordion active
 * @param {String} id ID of the accordion
 */
var activateAccordion = function (id) {
    // Get the parents
    var parents = $('a[href="#' + id + '"]').parents('.panel-group').children('.panel');

    // Go through each of the parents
    $.each(parents, function (idx, obj) {
        // Check if the child exists
        var find = $(obj).find('a[href="#' + id + '"]'),
            children = $(obj).children('.panel-collapse');

        if (find.length > 0) {
            // Show the selected child
            children.removeClass('collapse');
            children.addClass('in');
        } else {
            // Hide the others
            children.removeClass('in');
            children.addClass('collapse');
        }
    });
};

The important part of the code is the combination, remembering the .collapse class, not just using .in:

// Show the selected child
children.removeClass('collapse');
children.addClass('in');

and

// Hide the others
children.removeClass('in');
children.addClass('collapse');

The above example has been tested in Twitter's Bootstrap v3.3.4

Cristi Draghici
  • 518
  • 7
  • 10
1

This works for accordions in Bootstrap 3:

var selector = $('.panel-heading a[data-toggle="collapse"]');
selector.on('click',function() {
  var self = this;
  if ($(this).hasClass('collapsed')) {
    $.each(selector, function(key, value) {
      if (!$(value).hasClass('collapsed') && value != self) {
        $(value).trigger('click');
      }
    });
  }
});

I'm simulating a click of the other accordion tabs with $(value).trigger('click');. According to the API you should just be able to use the .collapse() method i.e. $(value).collapse('hide');. But it doesn't work for some reason so trigger it is...

anthonygore
  • 4,722
  • 4
  • 31
  • 30
0

For this kind of problem use addClass("in"); only because of using ".collapse('toggle/Hide/Show');" will disturb the future toggle functionality.

Vikram
  • 179
  • 1
  • 7
0

Another related use case is when we have forms inside accordions & we want to expand accordion with validation errors. Extending the answer by Daniel Wright https://stackoverflow.com/a/12698720/6504104, we can do something like

/**
 * Expands accordions that have fields with errors
 *
 */
var _expandAccordions = function () {
    $form           = $('.my-input-form');
    // you can adjust the following lines to match your form structure / error classes
    var $formGroups = $form.find('.form-group.has-error');  
    var $accordions = $formGroups.closest('.accordion-body');

    $accordions.each(function () {
        $(this).collapse('show');
    });
};
Azhar Khattak
  • 835
  • 8
  • 11
0

I did,

$('.mb-0').click(function(){
  $('.collapse').collapse('hide');
  $('.collapse.in').collapse('show');
});

and this works for me

Failed Scientist
  • 1,977
  • 3
  • 29
  • 48
0

Using Bootstrap 4 add the following buttons inside the card body

<input type="button" class="btn btn-secondary btn-block btn-sm mt-3 text-center card-proceed-next" value="Proceed" />
<input type="button" class="btn btn-secondary btn-block btn-sm mt-3 text-center card-proceed-prev" value="Previous" />

Add the following javascript (includes Azhar Khattak show panels with validation errors):

$(function () {
    $('.card-proceed-next').click(function (e) {
        e.preventDefault();
        $(e.target).closest('.collapse').collapse('hide'); // hide current accordion panel
        $(e.target).closest('.card').next('.card').find('.collapse').addClass('show'); // show next accordion panel
    });

    $('.card-proceed-prev').click(function (e) {
        e.preventDefault();
        $(e.target).closest('.collapse').collapse('hide'); // hide current accordion panel
        $(e.target).closest('.card').prev('.card').find('.collapse').addClass('show'); // show previous accordion panel
    });

    var $elErrors = $('#accordion').find('.field-validation-error'); // elements with error class
    var $accordionsWithErrors = $elErrors.closest('.collapse'); // accordions with error elements 
    if ($accordionsWithErrors.length > 0) $('.collapse').collapse(); // collapse all accordion panels due to the first accordion panel shown as default
    $accordionsWithErrors.each(function () {
        $(this).addClass('show'); // show accordion panels with error messages
    });
});
Jodda
  • 25
  • 4