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

Verify if a fresh message has been added using AJAX

Is it possible to create a notification system similar to Facebook, where the tab title displays the number of new messages without refreshing the entire page? Below is a snippet of code from my website's message box feature that I am working on. < ...

Transmit information to PHP via JSON with Cross Domain communication

My code is server1 and PHP code is server2. These servers are not connected. What issues can arise from this setup? var req = new XMLHttpRequest(); req.open("POST", "http://www.example.com/form/data.php", true); req.setRequestHeader("Content-type", "ap ...

Decoding JSON using JavaScript

I am dealing with a webservice that uses RestEasy to return a JSON object with a List element. When I try to parse the results in a JavaScript loop, everything works fine if there are two or more elements in the List. However, if there is only one element, ...

Dynamic loading of XML data into a DIV when hovering over it

The main idea behind my project is quite simple. I have a grid of company logos extracted from an XML document using XSLT, each logo with its own unique link to the respective company profile. On the same page, I have a separate div that serves as a "prev ...

Nested SetTimeout function fails to execute

Attempting to implement a button that provides feedback for its actions, I am faced with a challenge in Angular. After sending a put request to the server, the button's state changes to show this action. Upon receiving a response, the button's st ...

Invoking a function from a separate JavaScript file and finding out that an object is considered null

The source code for a word game is stored in Main.js file. Currently, I am attempting to introduce another file called Bookmarks.js (included on the web page prior to the Main.js file). This new file will contain an object var bookmarks = {}; that stays s ...

Why is my update with upsert: true not working in Express and Mongoose?

var logs = [{ mobilenumber: '1', ref: 3, points: 1000, ctype: 'mycredit', entry: 'sdfsdf', entry: 0 }, { mobilenumber: '1', ref: 6, points: 2000, ctype: 'mycredit', ...

Implement lazy loading functionality in Django to dynamically load data as the user scrolls

Currently, I am developing a web application using Django to showcase the interface and how content is loaded. In my database, there could potentially be thousands of entries, and I am looking for a way to load only a certain number at a time to minimize ...

Embracing the Unknown: Exploring Wildcard Values

I have a code snippet below that has a wildcard * in it. I'm looking for suggestions on how to make the * accept any number. Any thoughts on this? $('body').on('click', '.custom_295_*-row', function(){ var href = "htt ...

Adjust div elements to fit the size of the window

I'm currently working on designing a new web application's skeleton layout. I have come across some issues, particularly with CSS layouts and DIV. 1) Boxes 1 and 2 in the first column do not align with boxes 3 and 4 in the second and third colum ...

Combining AddClass and RemoveClass Functions in Mootools Event Handlers

I am currently in the process of creating a CSS animation, and one aspect involves changing the class name of the body at specific intervals. Since I am relatively new to Mootools (and JavaScript in general), my approach has been to add/remove classes to ...

jQuery dynamically updating calculations on a single row consecutively

Currently, I am in the process of developing a small table to calculate potential winnings from betting on a rubber duck race with specific odds for each duck. I have managed to get most of it working but have encountered an issue... Upon loading the pag ...

Tips for getting rid of the glowing effect on MUI slider thumbs when they are in focus

import * as React from "react"; import Box from "@mui/material/Box"; import Slider from "@mui/material/Slider"; function valuetext(value) { return `${value}°C`; } export default function RangeSlider() { const [value, se ...

Using Python with Selenium and JavaScript for Logging in

When using Selenium and Python, I am attempting to log in to a website but encountering difficulties. The issue is that the source code does not display the necessary Id=apple_Id required for sending login information, although it can be seen when inspecti ...

Leverage the power of integrating Power BI with Javascript to easily retrieve an

I have embarked on a mission to integrate PowerBI into my web application. Below is the code snippet that I have implemented: window.config = { instance: 'https://login.microsoftonline.com/', tenant: 'common', //COMMON OR YOU ...

A guide on incorporating Vue.js into a Hexo static site generator

Exploring the use of vue.js within my hexo theme has sparked my interest. Can anyone guide me on how to compile my .vue files for both development and production environments? It's worth mentioning that I intend for vue.js to operate on the client sid ...

jquery dialog box displaying a webpage

I am looking to implement a feature where, upon clicking the edit link in the last column of my dataTable, a separate page for editing should open within a jQuery dialog box. The goal is to seamlessly submit data while providing a user-friendly experienc ...

Display or conceal fields depending on custom object specifications

I am attempting to centralize my show/hide functionality for fields in one object (like vm.foo) that contains key-value pairs. For example, I could add another pair like 1502: true to hide a field with the key 1502. Is there a way to pass variables from t ...

Why isn't the selected option appearing first?

I have written a PHP code to display the specified div <div id="main_catsel"> <select id="maincat" > <option value="1">none</option> <option value="2">Computer</option> <option value="4">Refrigerator& ...

Top div click causes bottom div to slide

I'm currently working on a project that involves using CSS and jQuery, but I've encountered an issue that I haven't been able to solve. Here is the demo link: . When the second div is clicked, why does the third div slide? How can this prob ...