Hi i am trying to make a nested accordion and I am almost done.
The code itself is werking fine, but I have added chevrons to the main-buttons in the accordion,
When clicking on the main-btn one, the icon rotate, if i than click on main-btn two the icon of main-btn two is rotating as expected, but the icon of main-btn is not rotating back.
Can you please assist?
I have been playing around with the toggling of rotate class on different places with if and else,
but getting it working:
This is mij code:
<div class="accordion-container">
<button class="accordion-btn main-btn one">Category 1 Questions
<span class="chevron"></span>
</button>
<div class="panel">
<button class="accordion-btn sub-btn">Category 1 Question 1</button>
<div class="panel sub-panel">
<p>Category 1 Answer 1</p>
</div>
<button class="accordion-btn sub-btn">Category 1 Question 2</button>
<div class="panel sub-panel">
<p>Category 1 Answer 2</p>
</div>
<button class="accordion-btn sub-btn">Category 1 Question 3</button>
<div class="panel sub-panel">
<p>Category 1 Answer 3</p>
</div>
</div>
<!-- Repeat similar structure for other sections -->
<button class="accordion-btn main-btn two">Category 2 Questions
<span class="chevron"></span>
</button>
<div class="panel">
<button class="accordion-btn sub-btn">Category 2 Question 1</button>
<div class="panel sub-panel">
<p>Category 2 Answer 1</p>
</div>
<button class="accordion-btn sub-btn">Category 2 Question 2</button>
<div class="panel sub-panel">
<p>Category 2 Answer 2</p>
</div>
<button class="accordion-btn sub-btn">Category 2 Question 3</button>
<div class="panel sub-panel">
<p>Category 2 Answer 3</p>
</div>
</div>
<!-- Repeat similar structure for other sections -->
<button class="accordion-btn main-btn three">Category 3 Questions
<span class="chevron"></span>
</button>
<div class="panel">
<button class="accordion-btn sub-btn">Category 3 Question 1</button>
<div class="panel sub-panel">
<p>Category 3 Answer 1</p>
</div>
<button class="accordion-btn sub-btn">Category 3 Question 2</button>
<div class="panel sub-panel">
<p>Category 3 Answer 2</p>
</div>
<button class="accordion-btn sub-btn">Category 3 Question 3</button>
<div class="panel sub-panel">
<p>Category 3 Answer 3</p>
</div>
</div>
</div>
My styles:
.accordion-container {
background: darkgreen;
overflow: hidden;
}
.accordion-btn {
width: 100%;
background: palegreen;
border-radius: 0;
padding: 1.5rem !important;
margin-bottom: 1px;
cursor: pointer;
color: #047223;
border: none;
font-size: 2.2rem;
text-align: left;
transition: background-color 0.3s ease-in-out;
}
.sub-btn {
background-color: aqua;
}
.panel {
background: blueviolet;
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-in-out;
}
.active {
background-color: red;
color: white;
}
.sub-btn.active {
background-color: blue;
}
.chevron::after{
content: "\25B3";
color: black;
font-size: 1.5rem;
position: absolute;
transform: rotate(180deg);
}
.rotate.chevron::after{
transform: rotate(0);
}
and my js:
document.addEventListener("DOMContentLoaded", function () {
const accButtons = document.querySelectorAll('.accordion-btn');
const accPanels = document.querySelectorAll('.panel');
function updateMainPanelHeight(mainPanel) {
const subPanels = mainPanel.querySelectorAll('.panel.sub-panel');
let totalHeight = 0;
subPanels.forEach(subPanel => {
totalHeight += subPanel.scrollHeight;
});
mainPanel.style.maxHeight = (mainPanel.scrollHeight + totalHeight) + 'px';
}
accButtons.forEach(function (clickedButton) {
clickedButton.addEventListener('click', function (event) {
const clickedButton = event.target.closest('.accordion-btn');
const activatePanel = clickedButton.nextElementSibling;
if (clickedButton.classList.contains('main-btn')) {
const mainPanel = activatePanel.closest('.panel');
const chevronicon = clickedButton.querySelector('span.chevron');
console.log(chevronicon);
if (chevronicon.classList.contains('rotate')) {
chevronicon.classList.toggle('rotate');
}
else {
chevronicon.classList.toggle('rotate');
}
// Check if the main button is currently active
const isMainBtnActive = clickedButton.classList.contains('active');
// Close all main and sub-panels
accPanels.forEach(panel => {
panel.classList.remove('active');
panel.style.maxHeight = '0';
});
accButtons.forEach(button => {
button.classList.remove('active');
});
// If the main button was not active, open the clicked main panel
if (!isMainBtnActive) {
clickedButton.classList.add('active');
activatePanel.classList.add('active');
updateMainPanelHeight(mainPanel);
}
} else {
// Sub button clicked
const mainPanel = clickedButton.closest('.panel');
const subButtons = mainPanel.querySelectorAll('.accordion-btn.sub-btn');
const subPanels = mainPanel.querySelectorAll('.panel.sub-panel');
const isSubBtnActive = clickedButton.classList.contains('active');
if (!isSubBtnActive) {
// Deactivate previously active sub-button and sub-panel
subButtons.forEach(subButton => {
if (subButton.classList.contains('active')) {
subButton.classList.remove('active');
subButton.nextElementSibling.classList.remove('active');
subButton.nextElementSibling.style.maxHeight = '0';
}
});
// Activate the clicked sub-button and its associated sub-panel
clickedButton.classList.add('active');
activatePanel.classList.add('active');
activatePanel.style.maxHeight = activatePanel.scrollHeight + 'px';
// Update the main panel height
updateMainPanelHeight(mainPanel);
} else {
// If the sub-button is already active, remove the 'active' class and close the sub-panel
clickedButton.classList.remove('active');
activatePanel.classList.remove('active');
activatePanel.style.maxHeight = '0';
}
}
});
});
});