Home > Software engineering >  Bootstrap 4 change accordion behaviour
Bootstrap 4 change accordion behaviour

Time:09-12

I'm using HTML templates, which are based on Bootstrap 4.3.1 to present my students with learning content. In the current templates, all accordion panels are closed on page load and each accordion panel can be opened regardless of how many others have also been opened. A workoing example can be found on this CodePen: https://codepen.io/hagelslag1001/pen/MWGeZJr

The HTML code is as follows:

<h2>Accordion: Group of 2</h2>
            <p >Accordion: start copy</p>
            <!-- Accordion headings should be changed to respect page hierarchy -->
            <div >
               <div >
                  <div >
                     <h2 >
                        Accordion 1 of 2
                     </h2>
                  </div>
                  <div >
                     <div >
                        <p>Insert Accordion 1 of 2 content here.</p>
                     </div>
                  </div>
               </div>
               <div >
                  <div >
                     <h2 >
                        Accordion 2 of 2
                     </h2>
                  </div>
                  <div >
                     <div >
                        <p>Insert Accordion 2 of 2 content here.</p>
                     </div>
                  </div>
               </div>
            </div>
            <p >Accordion: end copy</p>

Is it possible to change this default behaviour so that only one panel can be opened at a time (i.e. as soon as a new panel is opened, the previously opened panel will automatically close).

The Bootstrap examples use data-toggle="collapse" data-target="#collapseOne" (aria-expanded="true" aria-controls="collapseOne") to accomplish this for the accordions in these templates

I can't figure out how t accomplish this, since the HTML code for the accordions in these templates look different than the Bootstrap 4 examples, which use either an a or button tag to trigger the collapsible event.

Your help would be much appreciated.

CodePudding user response:

Here is a simpler answer based on your CodePen: https://codepen.io/mrtcntn/pen/MWGeZdP

According the Bootstrap 4 docs, you need id="accordion" on the top level div and you don't need to give ids like id="accordion_1" and id="accordion_2".

Therefore I removed the first portion from the JS and added id="accordion" at line 18 in the HTML.

CodePudding user response:

You can do this by letting javascript check for active classes and only allowing one at the time. Here's a simplified example.

// DOM here
let nav = document.querySelector(".nav");

// Handlers here
const clickHandler = function (e) {
  if (e.target.classList.contains("nav__link")) {
    const link = e.target;
    const siblings = link.closest(".nav").querySelectorAll(".nav__link");

    link.classList.toggle("active");

    // removes all actives except for the clicked one
    siblings.forEach((el) => {
      if (el !== link) el.classList.remove("active");
    });
  }
};

// Listeners here
nav.addEventListener("click", clickHandler);
body {
  font-family: sans-serif;
}

.nav__link {
  display: block;
  width: 100%;
}
.active {
  background: #0f0;
}
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div >
      <ul >
                <li >
                    <a  href="#accordeon--1">Accordeon 1</a>
                </li>
                <li >
                    <a  href="#accordeon--2">Accordeon 2</a>
                </li>
                <li >
                    <a  href="#accordeon--3">Accordeon 3</a>
                </li>
                <li >
                    <a  href="#accordeon--4"
                        >Accordeon 4</a
                    >
                </li>
            </ul>
      </div>
    </div>

    <script src="src/index.js"></script>
  </body>
</html>

  • Related