What is the best way to close all other accordion tabs when selecting one?

A simple HTML code was created with the full pen accessible here.

<div class="center">
    <div class="menu">
        <div class="item">
            <button class="accordionBtn"><i class="fas fa-user"></i> Profile</button>
            <div class="accordionContent">
                <a href="#">Posts</a>
                <a href="#">Pictures</a>
            </div>
        </div>
        <div class="item">
            <button class="accordionBtn"><i class="far fa-envelope"></i> Message</button>
            <div class="accordionContent">
                <a href="#">New</a>
                <a href="#">Sent</a>
                <a href="#">Spam</a>
            </div>
        </div>
        <div class="item">
            <button class="accordionBtn"><i class="fas fa-cog"></i> Settings</button>
            <div class="accordionContent">
                <a href="#">Password</a>
                <a href="#">Language</a>
            </div>
        </div>
        <div class="item">
            <button class="accordionBtn"><i class="fas fa-sign-out-alt"></i> Sign out</button>
        </div>
    </div>
</div>

Additionally, JavaScript was used to toggle the respective accordion content:

const btns = document.querySelectorAll(".accordionBtn");

    btns.forEach((btn) => {
        btn.addEventListener("click", () => {
           
            const sibling = btn.nextElementSibling;
            if (sibling) {
                sibling.classList.toggle("show");
            }
        });
    });

When clicking on an accordion, it was desired for others to collapse. The following solution was implemented:

const btns = document.querySelectorAll(".accordionBtn");
const acc_contents = document.querySelectorAll(".accordionContent");

btns.forEach((btn) => {
    btn.addEventListener("click", () => {
        // new
        acc_contents.forEach(acc => {
            if(acc.classList.contains('show')) {
                acc.classList.remove('show');
            }
        })
        
        const sibling = btn.nextElementSibling;
        if (sibling) {
            sibling.classList.toggle("show");
        }
    });
});

However, this implementation disabled the toggle functionality. Assistance from anyone who can provide a solution would be greatly appreciated.

Answer №1

When you hide the element, it also hides the clicked element if it was open. Then when you toggle it later on, this negates the effect and there is no change. To prevent this, you need to add a check to ensure the current one is not hidden.

Here's how:

const buttons = document.querySelectorAll(".accordionBtn");
const contents = document.querySelectorAll(".accordionContent");

buttons.forEach((button) => {
    button.addEventListener("click", (e) => {
        contents.forEach((content) => {
            if (content.classList.contains("show") && content !== e.target.nextElementSibling) {
                content.classList.remove("show");
            }
        });

        const siblingElement = button.nextElementSibling;
        if (siblingElement) {
            siblingElement.classList.toggle("show");
        }
    });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Angular to Toggle Visibility with Button Directives

Within my main view, I have three directives that each display different sets of data. <div> <sales-view></sales-view> </div> <div> <units-view></units-view> </div> Addi ...

A comprehensive guide on troubleshooting the toggleComplete functionality for React Todo applications

When you click on an item in the to-do list, it should show a strikethrough to indicate completion. However, when I try clicking on an item, nothing happens. Here is my toggleComplete function and where I am attempting to implement it: class ToDoForm exten ...

What is the best way to adjust the placement of a component to remain in sync with the v-model it is connected to?

I am encountering an issue with 2 sliders in my project. I have set it up so that when the lower slider's value is greater than 0, the top slider should automatically be set to 5. I am using a watcher function for this purpose. However, if I manually ...

Is it feasible to dynamically incorporate various versions of Bootstrap within the head tag?

The CMS I'm currently working with has a strict dependency on a specific version of Bootstrap. However, there are features from Bootstrap 3.3.6 that I need based on the page being loaded in the browser. I initially considered using JavaScript or jQue ...

What is the best way to send a file to a JavaScript function within Django?

I am in the process of integrating the PhylD3 library into a Django Template. The CSS and JS files have been integrated into the Django static directory. However, I am unsure about the most efficient way to load the XML file in the template. Template - ...

There are a couple of issues here: specifically, the `this.myMethod` function is not recognized as a function, and the click event added by the `addEventListener` function

I am currently attempting to create a timer using vue.js, but I am encountering some issues with my methods section: methods: { saveRunningMethod() { var runningData = { duration: `${this.hour} : ${this.minute} : ${this.se ...

Ways to ensure the title changer works seamlessly for everyone

Having a title changer for elements visible in the viewport is crucial. However, the current setup only works for a single division and fails to function with multiple divisions. Click Here for Live Testing and Viewing Check out the jsFiddle for Code V ...

Difficulty Clicking Links with CSS 3D Transformation

I'm currently working on implementing a CSS 3D transform effect on my website. However, I am encountering some issues with clicking the links once the card has been flipped over. Question Why is this happening? How can I resolve this so that I can ...

Issues with clearRect() function in HTML5 canvas

Recently, I developed a function with the goal of redrawing a square line block that covers the entire page whenever the window size is adjusted. For reference, you can view my code at http://jsfiddle.net/9hVnZ/ However, I encountered an issue: bgCtx.cl ...

Facebook has broadened the scope of permissions for canvas applications

I am in the process of developing a Facebook canvas application that requires extended permissions for managing images (creating galleries and uploading images) as well as posting to a user's news feed. I am currently facing challenges with obtaining ...

When typing in the textarea, pressing the return key to create a line break does not function as expected

Whenever I hit the return key to create a new line in my post, it seems to automatically ignore it. For example, if I type 'a' press 'return' and then 'b', it displays 'ab' instead of 'a b'. How can I fi ...

Is there a way to enable my progressBar to be draggable so that when clicked, it adjusts to a new currentTime position

I am trying to create a seekable audio progress bar in React, but I am facing issues with the seek function not working as intended. Below is my main play buttons file where all the code related to the progress bar is located. import React, { Component } ...

Chrome on IOS: Experiencing screen freezing while scrolling

1) I'm working with Material UI in React JS. I have added a simple scrollable code, but when I reach the bottom of the screen/scroll, it freezes. 2) I also tried it with a simple HTML page and it worked correctly. <div style={{ ...

`CSS animation for vanishing line effect`

I want to create an animated logo that gives the illusion of being pulled up by a rope, represented by a vertical black line, from the bottom of the page to the top. As the logo moves upwards, I would like the rope to disappear behind it, but I'm uns ...

Utilizing Sessions Across Several PHP Forms

Hey there! I've got a query for you. When you kick off your PHP code with session_start(), do you need to keep adding the prior variables on subsequent form pages? I'm contemplating using the session() function for my GYM Sign UP Webpage. The f ...

The number of TH elements does not match the number of columns in the table

Is there a way to make only one th span the full width of the table, even with 5 columns below? I want to color the background of the th to cover the entire width. However, since the rest of the table contains 5 columns, the single th only stretches acros ...

Can someone guide me on how to align text to the bottom border of a page?

Is there a way to adjust the position of the header text ("bottom text") so that it appears just above the bottom border of the page? I have attempted modifying styles and classes within the footer, style, and h3 tags but have not had any success. Below ...

A method for automatically refreshing a webpage once it switches between specific resolutions

On my page www.redpeppermedia.in/tc24_beta/, it functions well at a resolution of over 980px. However, when the resolution is brought down to 768px, the CSS and media queries alter the layout. But upon refreshing the page at 768px, everything corrects itse ...

Displaying the unique values based on the key attribute

I'm developing a category filter and struggling to showcase the duplicate options. Within my array of objects: filterData = [ { name: 'Aang', bender: 'yes', nation: 'Air', person: 'yes', show: 'ATLA&apo ...

How can I make a drop-down field in AngularJS show the current value after populating options in a select control using ng-options?

This conversation centers around an app that can be visualized as, https://i.stack.imgur.com/Y1Nvv.png When a user clicks on one of the stories on the left side, the corresponding content is displayed on the right-hand side. Each story includes a title ...