I'm currently developing a more complex accordion. The accordion should have 4 buttons (section 0-3) with individual content (lorem ipsum 0-3). By clicking on "section 0" it should display "lorem ipsum 0". By clicking "section 1" the content "lorem ipsum 0" would be replaced with "lorem ipsum 1".
The final website is going to have an unknown amount of rows, each containing 4 accordions. This means, the script must be kind of dynamic.
My approach was to generate IDs with JS, set this attribute to each panel and then call them back again to make the accordion work. But I'm only able to call all the content (like in the JSFiddle) or just the last one from the loop.
How can I display/replace the content for every accordion without losing the layout?
Maybe theres a better approach to achieve this at all?
HTML:
<div class="row">
<div class="three columns">
<button class="accordion">Section 0</button>
</div>
<div class="three columns">
<button class="accordion">Section 1</button>
</div>
<div class="three columns">
<button class="accordion">Section 2</button>
</div>
<div class="three columns">
<button class="accordion">Section 3</button>
</div>
</div>
<div class="row">
<div class="twelve columns">
<div class="panel">
<p>Lorem ipsum 0...</p>
</div>
</div>
<div class="twelve columns">
<div class="panel">
<p>Lorem ipsum 1...</p>
</div>
</div>
<div class="twelve columns">
<div class="panel">
<p>Lorem ipsum 2...</p>
</div>
</div>
<div class="twelve columns">
<div class="panel">
<p>Lorem ipsum 3...</p>
</div>
</div>
</div>
JS:
var acc = document.getElementsByClassName("accordion");
for (var i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
this.classList.toggle("active");
var writeID = document.getElementsByClassName("panel");
for (var y = 0; y < writeID.length; y++) {
var newID = "demo-"+y;
writeID[y].setAttribute("id", newID);
var panel = document.getElementById(newID);
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
}
}
}
I also created a JSFiddle.
Any help is kindly appreciated!
Cheers' Max
EDIT: I would really appreciate any kind of help here. I tried to solve the problem with closures and forEach, but nothing worked out. If I have to clarify anything above, I'm happy to answer any questions.
Here is the current status of the code. It gives me all the contents out, but I would like to get only one for each accordion:
var acc = document.getElementsByClassName("accordion");
for (var i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
this.classList.toggle("active");
for (var i = 0; i < acc.length; i++) {
var panel = document.getElementById("demo-"+i);
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
};
}
}
Or in other words, I try to achieve this, but in a dynamic way
var acc = document.getElementsByClassName("accordion");
acc[0].onclick = function() {
this.classList.toggle("active");
var panel = document.getElementById("demo-0");
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
}
acc[1].onclick = function() {
this.classList.toggle("active");
var panel = document.getElementById("demo-1");
if (panel.style.maxHeight){
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + "px";
}
}