Rotating chevron in accordion in javascript

19 Views Asked by At

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';
                        }
                    }
                });
            });
        });
0

There are 0 best solutions below