Home > Mobile >  Accordion JS code: hide any open accordion on clicking another one and how to add a symbol for eac
Accordion JS code: hide any open accordion on clicking another one and how to add a symbol for eac

Time:08-11

The code below is added to create accordion elements in a page. Clicking on any of the accordions opens the accordion but it the accordion doesn't close when another one is clicked.

PHP&HTML:

setTimeout(function() {
  var acc = document.getElementsByClassName("accordion");
  console.log(acc.length);
  var i;
  for (i = 0; i < acc.length; i  ) {
    alert("In the loop!")
    acc[i].addEventListener("click", function() {
      console.log("Click event called!")
      this.classList.toggle("active");
      var panel = this.nextElementSibling;
      if (panel.style.display === "block") {
        panel.style.display = "none";
      } else {
        panel.style.display = "block";
      }
    });
  }
}, 500);
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 1.5rem;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.panel {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden;
}
      <?php 
        if ( have_rows( 'question_and_answer' ) ) :
          while ( have_rows( 'question_and_answer' ) ) : the_row();
          $label = get_sub_field( 'question' );
          $answer = get_sub_field( 'answer' );
      ?>
      <div >
        <button ><div ><?php echo $label; ?></div></button>
        <div ><p ><?php echo $answer; ?></p></br></div>
      </div>
      <?php 
        endwhile; 
      ?>

Here is the link to the page on the staging site. Please see the section with the heading "FREQUENTLY ASKED QUESTIONS"

CodePudding user response:

It's because you never remove the active class from any previously clicked items:

setTimeout(function() {
  var acc = document.getElementsByClassName("accordion");
  console.log(acc.length);
  var i;
  for (i = 0; i < acc.length; i  ) {
    acc[i].addEventListener("click", function() {
      const active = document.querySelector(".accordion.active");
      if (active) {
        active.classList.remove('active'); // remove active class from accordions
      }

      this.classList.add("active"); // add it to this one

      // do display using css
    });
  }
}, 500);
.accordion {
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 1.5rem;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.active,
.accordion:hover {
  background-color: #ccc;
}

.panel {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden;
  background: red;
}

.active .panel {
  display: block;
}
<div >
  <button ><div ><?php echo $label; ?></div></button>
  <div >
    <p >
      <?php echo $answer; ?>
    </p>
    </br>
  </div>
</div>
<div >
  <button ><div ><?php echo $label; ?></div></button>
  <div >
    <p >
      <?php echo $answer; ?>
    </p>
    </br>
  </div>
</div>

As an alternative, you don't actually need js to achieve this type of accordion, you can use radio buttons and css:

.accordion {
  display: block;
  background-color: #eee;
  color: #444;
  cursor: pointer;
  padding: 1.5rem;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
  transition: 0.4s;
}

.accordion:hover {
  background-color: #ccc;
}

.panel {
  padding: 0 18px;
  display: none;
  background-color: white;
  overflow: hidden;
  background: red;
}

.radio {
  display: none;
}

.radio:checked~.panel {
  display: block;
}
<div >
  <input type="radio" name="accordion" id="accordion1" >
  <div ><label  for="accordion1"><?php echo $label; ?></label></div>
  <div >
    <p >
      <?php echo $answer; ?>
    </p>
    <br>
  </div>
</div>
<div >
  <input type="radio" name="accordion" id="accordion2" >
  <div ><label  for="accordion2"><?php echo $label; ?></label></div>
  <div >
    <p >
      <?php echo $answer; ?>
    </p>
    <br>
  </div>
</div>

  • Related