Collapse the accordion when opening another accordion that belongs to a different parent

I am currently working with an accordion setup that you can view here: https://jsfiddle.net/n4tmjaqd/1/

I am looking for guidance on how to modify the function so that when either tab 2 or tab 3 opens, tab 1 closes (and vice versa). Tab 1 has a different parent compared to tabs 2 and 3, although they share the same class. I'm wondering if it's possible to achieve this functionality with elements having different parents but the same class, or if I need to update the parent class of tab 1 and create a new function from there. Any help would be greatly appreciated.

$(function() {

  $('.accordion .accordion-title').on('click', toggleAccordion);

  function toggleAccordion(event) {
    var target = $(event.target).closest('.accordion-item');

    target.parent('.accordion').find('.accordion-item').not(target).removeClass('is-open');
    target.toggleClass('is-open');
  }

});
.accordion .accordion-item {
  border-bottom: 1px solid #000;
}

.accordion .accordion-title {
  position: relative;
  padding: 15px;
  cursor: pointer;
}

.accordion .accordion-content {
  display: none;
  padding: 0 15px 15px;
}

.accordion .accordion-item.is-open .accordion-content {
  display: block;
}

.accordion .arrow {
  position: absolute;
  display: inline-block;
  padding: 5px;
  top: 13px;
  right: 15px;
  background-color: inherit;
  border: solid #000;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  -webkit-transform: rotate(45deg);
}

.accordion .accordion-item.is-open .arrow {
  top: 20px;
  transform: rotate(-135deg);
  -webkit-transform: rotate(-135deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="accordion">
  <div class="accordion-item">
    <div class="accordion-title">
      TITLE 1
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      CONTENT 1
    </div>
  </div>
</div>

<div class="accordion">
  <div class="accordion-item">
    <div class="accordion-title">
      TITLE 2
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      CONTENT 2
    </div>
  </div>
  <div class="accordion-item">
    <div class="accordion-title">
      TITLE 3
      <span class="arrow"></span>
    </div>
    <div class="accordion-content">
      CONTENT 3
    </div>
  </div>
</div>

Answer №1

To implement this functionality, make sure to include the following code snippet at the beginning of your click event handler:

$('.accordion-item').not($(event.target).parent()).removeClass('is-open');

If you want to see a live example, you can check out the demo on JSFiddle.

You can also refer to the complete code below for reference:

$(function() {
  
        $('.accordion .accordion-title').on('click', toggleAccordion);
      
        function toggleAccordion(event) {
          var text = $(event.target).find('span').text();
          if(text === "+") {
            $(event.target).find('span').text('-');
          } else {
            $(event.target).find('span').text('+');
          }
          $('.accordion-item').not($(event.target).parent()).removeClass('is-open');
          var target = $(event.target).closest('.accordion-item');
          
          target.parent('.accordion').find('.accordion-item').not(target).removeClass('is-open');
          target.toggleClass('is-open');
        }
        
      });
.accordion .accordion-item {
        border-bottom: 1px solid #000;
      }
      
      /* Add your CSS styles here */
      
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  
      <div class="accordion">
        <div class="accordion-item">
          <div class="accordion-title">
            TITLE 1
            <span class="arrow">+</span>
          </div>
          <div class="accordion-content">
             CONTENT 1
          </div>
        </div>
      </div>
      
       <div class="accordion">
        <div class="accordion-item">
          <div class="accordion-title">
            TITLE 2
            <span class="arrow">+</span>
          </div>
          <div class="accordion-content">
           CONTENT 2
          </div>
        </div>
        <div class="accordion-item">
          <div class="accordion-title">
            TITLE 3
            <span class="arrow">+</span>
          </div>
          <div class="accordion-content">
            CONTENT 3
          </div>
        </div>
      </div>

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

Choose elements with unique identifiers other than those provided by the API

Seeking assistance with Material UI select element and naming dropdown. Have a few questions: 1: My API that populates the dropdown lacks good names. Is it possible to assign names like 'data 1, data 2, data 3...' to the options without manually ...

Using CSS to customize the dropdown text styling of a select box within a custom wrapper

I have a specific customized dropdown menu using the styled-select wrapper: HTML: <div class="styled-select"> <select name="example_length" aria-controls="example" class=""> <option value="10">10</option> <option value="25"> ...

The presence of 'touched' within Angular validation is causing a delay in method execution

Upon utilizing this validation method, it became apparent: <label>Password</label> <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': f.password.touc ...

express/node: You are unable to define headers once they have already been sent to the client

I seem to be running into a problem with my expressJS application. Every time I try to post to a specific route, I keep getting the error message Cannot set headers after they are sent to the client. I've been troubleshooting this issue but can't ...

The Facebook bots are unable to crawl our AngularJS application because the JavaScript is not being properly

I have a unique setup where my website is built with AngularJS and Wordpress as a single page application. Depending on the routing of the page, I dynamically define meta tags in the controller. Here's a snippet of my HTML header: <meta property=" ...

Securing nested access tokens in JavaScript: Best practices

FB.api({user-id}, { "fields":"context", "access_token": anAccessToken }, function (response) { console.log(response); }) I am currently retrieving mutual friends using the context parameter. However, I need to provide b ...

The user has chosen a CSS stylesheet in Rails

Currently, I am developing a Rails website and I want to give users the option to switch between light and dark CSS themes. In my view file, I have included the following code snippet to use a variable for the stylesheet: <%= stylesheet_link_tag @curr ...

Challenges with React Native's AsyncStorage

When I try to access data stored in asyncStorage using the 'getToken' and 'getMail' functions in the code snippet below, I encounter an issue where the data appears empty when I initially open the page on the emulator. However, upon sav ...

Encountered a cross-domain error with node.js and jQuery: ERR_CONNECTION_REFUSED

Just beginning my journey with Node.js. I've set up a basic node/express application that serves a single webpage featuring a button. When clicked, this button triggers a jQuery ajax request to an Express route. The route callback then makes an http ...

Implementing AngularJS drag and drop functionality in a custom directive

I am in search of an example that demonstrates similar functionality to the HTML5 File API using Angular-js. While researching directives for Angular 1.0.4, I found outdated examples that heavily rely on DOM manipulation. Here is a snippet of the pure Ja ...

Having trouble parsing bytes from a protobuf message in JavaScript

In my current project, I am faced with the task of encoding and decoding bytes within a protobuf message using Javascript. It seems that working with strings is functional, but once I introduce bytes in the message definition, retrieving the data becomes a ...

Create a notification menu in Bootstrap using Bootply, which conveniently displays a numerical badge at the top

I am interested in implementing a bootstrap notification menu similar to the one found at this link: http://www.bootply.com/oasBuRC8Kz# However, I would like to add the number of notifications to the upper right corner of the glyphicon. I have gone throug ...

Creating a WordPress widget that links to a local file

Hey there, I've been attempting to utilize the text widget in order to link to a local file, but unfortunately, it's not working as expected, and I'm unsure of the reason why: Here is what I am using: <a href="file:///D:/" target="_blan ...

What is the reason for the presence of the ^ symbol in this drop-down menu?

Just came across a great script, check it out here! Noticed the drop down has a ^ on top. The CSS I found for this is as follows: #colorNav li ul li:first-child:before{ content:none; position:absolute; width:1px; height:1px; border:5 ...

How to Build a Number Spinner Using Angular Material?

Is there a number spinner in Angular Material? I attempted to use the code provided in this question's demo: <mat-form-field> <input type="number" class="form-control" matInput name="valu ...

Searching for the function scope across modules - where could it be?

Consider the following scenario: include.js module.exports = function() { ... return { func: function(val) { return Function('return ' + val + ';'); } } }() running.js var outer = function() ...

Escaping the setTimeout loop

I'm struggling to find a solution for breaking out of a setTimeout loop. for (var i = 0; i < 75; i++) { setTimeout(function (i) { return function () { console.log("turn no. " + i); if (table.game.playerWon) { con ...

What sets apart importing crypto from 'crypto' as opposed to simply using crypto in Node.js?

For my upcoming Node project, I'm considering using crypto to obtain a UUID. After some research, I discovered that I can achieve this by utilizing crypto and that it is already a declared variable without the need for importing it. So there are two o ...

Transforming text colors dynamically using Vue.js

Here is an Angular code snippet: <div [style.color]="'#' + prod.id.substring(0,6)"> <small>{{ prod.id }}</small> </div> Now I want to create a similar code using vue.js. ...

Retrieve and save files under a common directory

I have a specific route called payments/transactions that retrieves all relevant data. I'm interested in finding a way to generate a CSV file without the need to create new routes or add query parameters, so that my route appears as payments/transacti ...