How can I create an accordion panel that can be toggled using

I've been working on creating an accordion panel using CSS with a touch of JavaScript.

Everything seems to be functioning correctly except for the toggling of the panels.

Essentially, when one panel is clicked, I want all other open panels to close.

Check out this fiddle:

FIDDLE

I attempted to achieve this by keeping all panels closed all the time with the following code:

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
    acc[i].onclick = function(){
        this.classList.toggle("active");
        $('.panel').addClass('hide');
        this.nextElementSibling.classList.toggle("hide");
        this.nextElementSibling.classList.toggle("show");
  }
}

and in the CSS section:

.panel.hide {
    opacity: 0;
    height: 0;  
}

I also tried:

$(this).removeClass('hide');

I understand that jQuery was used and not pure JavaScript but it didn't seem to work as expected. Any advice on how to fix this issue would be greatly appreciated.

Thank you in advance.

Answer №1

Retrieve the active item in the click handler - if it is not the current item, remove the active state from it.

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].onclick = function() {
    var active = document.querySelector(".accordion.active");
    if (active && active != this) {
      active.classList.remove("active");
      active.nextElementSibling.classList.remove("show");
    }
    this.classList.toggle("active");
    this.nextElementSibling.classList.toggle("show");
  }
}
button.accordion {
  background-color: #CBF1F5;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: solid 1px #3CF;
  text-align: left;
  outline: none;
  font-size: 18px;
  transition: 0.4s;
  font-weight: 600;
}
button.accordion.active,
button.accordion:hover {
  background-color: #E1F7FB;
}
button.accordion:after {
  content: '\25bc';
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}
button.accordion.active:after {
  content: "\25b2";
  color: #FFF;
}
.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: 0.6s ease-in-out;
  opacity: 0;
}
.panel.show {
  opacity: 1;
  max-height: 500px;
}
.panel.hide {
  opacity: 0;
  height: 0;
}
<button class="accordion">Section 1</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>


<button class="accordion">Section 2</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>



<button class="accordion">Section 3</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>


Utilizing jQuery for the same functionality:

$('.accordion').click(function() {
  var $this = $(this).toggleClass('active');
  var $panel = $this.next().toggleClass('show');
  $('.accordion.active').not(this).removeClass('active').next().removeClass('show');
});
button.accordion {
  background-color: #CBF1F5;
  color: #444;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: solid 1px #3CF;
  text-align: left;
  outline: none;
  font-size: 18px;
  transition: 0.4s;
  font-weight: 600;
}
button.accordion.active,
button.accordion:hover {
  background-color: #E1F7FB;
}
button.accordion:after {
  content: '\25bc';
  font-size: 13px;
  color: #777;
  float: right;
  margin-left: 5px;
}
button.accordion.active:after {
  content: "\25b2";
  color: #FFF;
}
.panel {
  padding: 0 18px;
  background-color: white;
  max-height: 0;
  overflow: hidden;
  transition: 0.6s ease-in-out;
  opacity: 0;
}
.panel.show {
  opacity: 1;
  max-height: 500px;
}
.panel.hide {
  opacity: 0;
  height: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="accordion">Section 1</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>


<button class="accordion">Section 2</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>



<button class="accordion">Section 3</button>
<div id="foo" class="panel">
  <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
</div>

Answer №2

Try using the .not selector instead of a for loop in jQuery

JavaScript:

var acc = $(".accordion"); //using jQuery accordion

acc.click(function() //event listener for click on element
{ 
    $(this).toggleClass("active");  //toggle active class
    $('.panel').not($(this).next()).hide(); //hide all panels except the next one
    $(this).next().toggle(); //toggle visibility of next element
});

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

Array in JavaScript containing a replica set of Node.js and MongoDB

As a novice programmer with more experience in sysadmin work, I've been tasked with setting up a new HA environment for a node js application using MongoDB. The current setup utilizes mongojs and monq java classes with only one MongoDB instance. In or ...

Bootstrap 4 row featuring bottom-aligned buttons on both the left and right sides of the container

There is a row of buttons with two aligned on the left and one on the right: html { position: relative; min-height: 100%; } body { /* Margin bottom by footer height */ margin-bottom: 60px; } .footer { position: absolute; bottom: 0; w ...

The `$scope variable fails to update in another controller`

I am currently facing an issue with updating a value on my view. Let me walk you through my code along with a brief explanation of the situation. The code may look messy as I have been experimenting with different combinations lately. The controller in qu ...

Issue with Vue.js: Textarea not functioning properly within a v-for loop

The v-model value within the v-for loop is not unique. Here is the provided template: <template> <div id="FAQ" v-for="(question, index) in questions.slice().reverse()" :key="index" ...

Struggling to retrieve JSON response through Javascript

It seems there may be an issue with the API URL or headers in the code provided below. The isError function is always triggered, indicating a lack of response. However, testing the same API URL in Postman returns a successful response. Code: //loading Fl ...

Retrieve Files with Angular Framework

I'm looking to implement a file download or view button using Angular without making a call to the backend. The file is static and the same for all users, so I want to avoid unnecessary server requests. Many solutions involve using the "download" att ...

Image of outer space enclosed by a circular boundary

Check out this fiddle I created here. It's a simple concept of an image inside a red circle. Is there a way to add some spacing around the image within the circle? This is the markup I currently have: <div style=" width: 50px; he ...

What could be causing the SyntaxError with JavascriptExecutor: Unexpected identifier?

Python PythonExecutor py = (PythonExecutor) driver; Boolean ready = (Boolean)py.executeScript("the following Python code"); Python Code var ready = False; window.onload = def check_ready(): ready = True def sleep(): return new Promise(resolve = ...

"Phraseapp is in the process of refreshing the primary language document

I currently have a locale file that contains various text keys that need to be translated. Each key corresponds to a specific text that needs to be translated into different languages: { key1: "Text to translate", key2: "Another text to translate", ...

Calculating the width of fluctuating DOM elements in AngularJS

It seems like most of my Angular questions are just me overlooking something really silly, so let's hope that's the case here too. Currently, I am working on a directive to manage the scrolling of a wide list of thumbnails. While it was working ...

How can NodeJS functions leverage parameters such as req, res, and result?

As a newcomer to JS, particularly Node and Express, I am in the process of learning how to build an API through tutorials. Along the way, I am also exploring various special features of JS such as let/const/var and arrow functions. One common pattern I no ...

Using Node.JS to retrieve values of form fields

I am working with Node.js without using any frameworks (specifically without express). Here is my current code snippet: const { headers, method, url } = req; let body = []; req.on('error', (err) => { console.error(err); }).on(&apos ...

Looking for a skilled JavaScript expert to help create a script that will automatically redirect the page if the anchor is changed. Any t

Seeking a Javascript expert, In my custom templates, I have used a link as shown below: <a href='http://www.allbloggertricks.com'>Blogging Tips</a> I would like the page to redirect to example.com if the anchor text is changed from ...

The CSS styles on my GitHub Pages website are not being reflected on the HTML page

I've been struggling for a while now to host my Portfolio CV on GitHub and I can't seem to get my CSS styles to apply correctly on the URL. - This is how I have linked it in the HTML document: <link rel="stylesheet" type="text/ ...

Application becomes unresponsive following database write caused by an infinite loop

I have a user_dict object that is generated by fetching data from a Firebase database. Once the user_dict object is created, I store a copy of it within a profile child under the uid. Although the necessary information is successfully saved to the databas ...

Troubleshooting: jQuery script encountering issues with loading Bodymovin JSON files

The animations for the slider and shuffle lottie are designed to go from 0 to 100 and then back to 0 when toggled, similar to the box animation. However, it appears that the slider animation disappears in the final frame while the shuffle animation appear ...

Tips for linking my TypeScript document to the server

Recently diving into the world of Angular 2 and seeking to grasp its intricacies. Currently utilizing Visual Studio Code. How can I have the server monitor changes in the TypeScript file? Do I need a compiler to convert it to JavaScript for this purpose? ...

Angular $mdDialog allowing for multiple instances to be created

Working with modal tabs, I have a notification pop-up window that is always displayed to the user upon logging into my application. This pop-up contains all events that occurred while the user was offline. The issue arises when clicking on any object from ...

Initiate keyframe animation after completion of the transition (CSS)

Can someone assist me with implementing my idea? I want the "anim" animation to start as soon as image1 finishes its transition. My attempted solution: I tried using "animation-delay," but that didn't work for me. The issue is that "animation-delay" ...

Issue with Jquery Slider Showing Empty Slide

Currently addressing issues with the slider on my site, which utilizes SlidesJS at . There seems to be a problem where it shows a blank slide inexplicably. After investigating, I noticed that a list element is being added to the pagination class, but I can ...