Search code examples
javascripthtmltwitter-bootstrap-3accordion

How to manipulate a Bootstrap Accordion panel using JavaScript without jQuery?


I have a panel with fields inside an Bootstrap accordion. I need my button to toggle the accordion into expanding and collapsing. Using the click() is not working.

  1. How to use pure vanilla JS to manipulate the accordion into expanding and collapsing?
  2. How to make set the default state of the accordion on page loading?

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Bootstrap Example</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
    />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  </head>
  <body>
    <button
      type="button"
      class="btn btn-info"
      onclick="
      alert('Hello');
      document.getElementById('sample-module').click();
    "
    >
      Toggle Accordian
    </button>
    <br /><br />
    <div class="row">
      <div class="col-xs-12">
        <div class="panel-group accordion">
          <div id="sample-module" class="panel panel-default">
            <div class="panel-heading">
              <h4 class="panel-title">
                <a
                  class="accordion-toggle"
                  data-toggle="collapse"
                  href="#sample"
                  aria-expanded="false"
                >
                  <i class="glyphicon glyphicon-chevron-down"></i>
                  <strong>Sample Accordian</strong></a
                >
              </h4>
            </div>
            <div
              id="sample"
              class="panel-collapse collapse in"
              aria-expanded="false"
              style=""
            >
              <div class="panel-body">
                <div class="row">
                  <div class="col-xs-6">
                    <div class="form-group">
                      <label class="control-label" for="sample-field-1">
                        Sample Field 1:
                      </label>
                      <div class="controls">
                        <input
                          id="sample-field-1"
                          class="form-control"
                          name="sample-field-1"
                          type="text"
                        />
                      </div>
                    </div>
                  </div>
                  <div class="col-xs-6">
                    <div class="form-group">
                      <label class="control-label" for="sample-field-2">
                        Sample Field 2:
                      </label>
                      <div class="controls">
                        <input
                          id="sample-field-2"
                          class="form-control"
                          name="sample-field-2"
                          type="text"
                        />
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>


Solution

  • Sadly, you can't use Bootstrap 3 or 4 without jQuery, and funnily, this was a problem for many years. Thankfully, Bootstrap 5 doesn't need jQuery anymore therefore in your case, since you don't want to use jQuery, you'll need to use Bootstrap 5.

    Actually, I'm not quite sure why you're still using Bootstrap 3. It's an outdated version that's not supported anymore, so? Upgrade to Bootstrap 4, and preferably Bootstrap 5.

    See Bootstrap Release Working Group for more information about the support of Bootstrap versions.

    Also, I'm not sure if onclick="alert('Hello');document.getElementById('sample-module').click();" will work and actually, this is known as Unobtrusive JavaScript. And it's a not good approach, you should assign an id on the <button> and manage clicks through addEventListener() method like:

    const click = document.getElementById("click");
    click.addEventListener("click", function () {
        alert("Yay! Clicked!");
    });
    <button id="click">Click!</button>

    And according to the documentation of Bootstrap 3, you need to use .collapse() method not .click() (unless I was missing something about old Bootstrap versions):

    $('.collapse').collapse();
    

    So your final code will be:

    const click = document.getElementById("click");
    click.addEventListener("click", function () {
        $('#sample-module').collapse('toggle');
    });
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>Bootstrap Example</title>
            <meta charset="utf-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1" />
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
            <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
        </head>
        <body>
            <button type="button" id="click" class="btn btn-info">
                Toggle Accordion
            </button>
            <br />
            <br />
            <div class="row">
                <div class="col-xs-12">
                    <div class="panel-group accordion">
                        <div id="sample-module" class="panel panel-default">
                            <div class="panel-heading">
                                <h4 class="panel-title">
                                    <a class="accordion-toggle" data-toggle="collapse" href="#sample" aria-expanded="false">
                                        <i class="glyphicon glyphicon-chevron-down"></i>
                                        <strong>Sample Accordian</strong>
                                    </a>
                                </h4>
                            </div>
                            <div id="sample" class="panel-collapse collapse in" aria-expanded="false" style="">
                                <div class="panel-body">
                                    <div class="row">
                                        <div class="col-xs-6">
                                            <div class="form-group">
                                                <label class="control-label" for="sample-field-1">
                                                    Sample Field 1:
                                                </label>
                                                <div class="controls">
                                                    <input id="sample-field-1" class="form-control" name="sample-field-1" type="text" />
                                                </div>
                                            </div>
                                        </div>
                                        <div class="col-xs-6">
                                            <div class="form-group">
                                                <label class="control-label" for="sample-field-2">
                                                    Sample Field 2:
                                                </label>
                                                <div class="controls">
                                                    <input id="sample-field-2" class="form-control" name="sample-field-2" type="text" />
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </body>
    </html>

    And to set the default state of the accordion change collapse in to collapse. So according to your code, you will change:

    <div id="sample" class="panel-collapse collapse in" aria-expanded="false" style="">
    

    To:

    <div id="sample" class="panel-collapse collapse" aria-expanded="false" style="">
    

    Where .collapse hides content, and .collapse.in shows content.

    There's also another class called .collapsing which is applied during transitions.