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>