jQuery Accordian malfunctioning for all elements except the first one in the list

Trying to implement an accordion feature that can be utilized across the entire website. The current logic seems to be partially functional... When I click on any of the accordions, it should open by adding a 'show' class, but this only works for the first accordion in the parent container.

Sometimes all the accordions open simultaneously, but the desired functionality is to allow users to individually open and close each accordion on the page.

(function ($) {

    $(".accord").on("click", function (e) {
    
    console.log(this);
    
      $(".accordian-content").toggleClass("show");

    });

})(jQuery);
.accord {
    background-color: $primary;
    color: #111;
    cursor: pointer;
    padding: 10px;
    width: 100%;
    text-align: left;
    border: none;
    outline: none;
    transition: 0.4s;
}
.accordian-content {
    display: none;
}

.accordian-content.show {
    display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<ul>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>

<!-- Repeat the above button code for other accordions -->

</ul>

Answer №1

Your code

$(".accordian-content").toggleClass("show");
scans the entire DOM structure for elements with the class '.accordian-content' and toggles the class show for all matching elements.

Since your content is always nested within the .accord element, you can utilize $(this) in the click event to target the clicked element. By doing this, you can then use .find(SELECTOR) to search for a specific child element, such as .accordian-content, resulting in the desired element being displayed.

(function ($) {

    $(".accord").on("click", function (e) {
    
    // Updated this Line to target the Accordian-content that is a child of the clicked 'accord'-button
      $(this).find('.accordian-content').toggleClass("show");

    });

  })(jQuery);
.accord {
    background-color: $primary;
    color: #111;
    cursor: pointer;
    padding: 10px;
    width: 100%;
    text-align: left;
    border: none;
    outline: none;
    transition: 0.4s;
  }
  .accordian-content {
    display: none;
  }

  .accordian-content.show {
    display: block;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<ul>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>
</ul>

Answer №2

Utilizing unique identifiers can be a more efficient approach when determining which item has been clicked and applying that ID to the accordian template.

By incorporating IDs into your text and adjusting the JavaScript code slightly, you can easily match the number from the clicked div with the corresponding accordian content control.

One added advantage of using unique IDs is the ability to target a specific accordian to open on page load by referencing the ID. This simplifies the process compared to not having an ID. Whether this functionality is necessary depends on your requirements.

(function ($) {

    $(".accord").on("click", function (e) {
    
    let accordian = this.id.replace('accord', 'accordian-content')
    
      $('#' + accordian).toggleClass("show");

    });

  })(jQuery);
.accord {
    background-color: $primary;
    color: #111;
    cursor: pointer;
    padding: 10px;
    width: 100%;
    text-align: left;
    border: none;
    outline: none;
    transition: 0.4s;
  }
  .accordian-content {
    display: none;
  }

  .accordian-content.show {
    display: block;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<ul>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer" id="accord1">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content" id="accordian-content1">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer" id="accord2">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content" id="accordian-content2">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>
<li>
    <button class="accord menu w-full my-[15px] cursor-pointer"  id="accord3">
        <div class="menu-item flex align-center p-2 justify-between gap-2 bg-primary">
            <div class="title uppercase text-white font-bold"><?php echo $title; ?></div>
            <span class="icon text-white scale-y-150 pr-[17.5px]">+</span>
        </div>
        <div class="accordian-content" id="accordian-content3">
            <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Eos totam, explicabo deserunt eaque molestiae dolorem perspiciatis? Eius iure veniam nulla architecto necessitatibus culpa debitis maxime velit voluptatum eos nesciunt quidem eveniet deleniti deserunt vel nemo ipsa beatae, harum dolore eligendi sequi quo unde. Adipisci minima id iste in nostrum voluptatibus.</p>
        </div>
    </button>
</li>
</ul>

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

Step-by-step guide on starting Edge with Open package on Windows 10

I am utilizing the Open package to launch URLs across different browsers. Unfortunately, there is a lack of comprehensive documentation on how to specifically launch with different browsers on various operating systems. After some experimentation, I have ...

Ways to stop a form input value from disappearing when clicking on other fields?

Upon loading the page, the form's campaignid input value is automatically filled. However, clicking on other fields causes it to reset to default. Is there a way to prevent this default behavior and preserve the input value of campaignid? I've ...

Create basic HTML using the react.cloneElement method

When using React.cloneElement(), the first parameter always needs to be a react component that is passed as children in props. Is there a way to pass a simple HTML node as a child? Please see the example code below for clarification: Dialog.jsx (Common c ...

Having trouble launching the emulator in VS Code for React Native?

I'm having trouble launching the android emulator on VS Code to run React-Native. I already have an emulator set up in Android Studio, but when I try to launch it, I get the error message: Error Failed to launch emulator. Reason: No emulators found as ...

The React modal refuses to disappear, stubbornly clinging to the original component it sprang from

Hey there, I'm a beginner in learning React and I'm encountering an issue with my popup modal component. Even after showing the modal, I can still interact with and click on the main UI elements. Can anyone assist me with this problem? https://i ...

Inconsistent and non-uniform sizing of table cells (<td> tags)

I'm currently working on creating an HTML table to use as the formatting for a banner and menu links on my website. However, no matter how much I adjust the size and margins, the menu link tags just won't seem to stay at an even size. <table ...

Encountering an issue with Discord JS that says "unable to access property 'content' because it is undefined"

CODE IS BELOW I have recently created a discord bot and included a message file within the events--guild directory. module.exports = (Discord, client, message) => { const prefix = '!'; if(!message.content.startsWith(prefix) || mess ...

Is there a way to incorporate promises into an endless loop while adding a delay in each iteration?

require("./getSongFromSpotify")().then(a => { require("./instify")(a.artist,a.name).then(r => { if (r.status === "ok"){ console.log("saved") }else{ console.log(" ...

Using jQuery to send a multi-dimensional form to PHP

My form includes initial inputs for customer ID and address ID, followed by a multidimensional form where users can dynamically add more items. <div class='invoice_object'> <input name='item[1][quantity]' type=&apo ...

What is the solution for fixing an error that says "There is no 'style' property on the 'Element' type"?

I'm struggling to fix an error in my JavaScript code. I created a script to display a tab indicator when a tab is clicked, but I keep getting the error message: "Property 'style' doesn't exist on type 'Element'". The tabs them ...

Obtaining a Variable Element through Selector

When working with Puppeteer, I am faced with the challenge of clicking on a web button that has a dynamic id like: #product-6852370-Size. Typically, I would use the following code: page.click('#product-6852370-Size'); However, the number withi ...

Adjust PATH for the jQuery AJAX call

Within my perspective, I have a form along with an AJAX event triggering upon the form submission: var info = { message1: $("#msg1").val(), message2: $("#msg1").val(), message3: $("#msg1").val(), }; ...

Issue with Refresh Triggering Update, localStorage, useState, useEffect Combination

I want my app to execute the code inside the useEffect hook every 5 seconds, regardless of whether the page is refreshed or not. Currently, the code only runs when the page is refreshed and then remains inactive until the page is refreshed again. It seems ...

How can I display an ngx spinner after a delay of 1 second?

I am uncertain about the answer I came across on this platform. intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const time = 900; const spinnerLogic = () => { if (this.isRequestServed ...

Ensure the http request is finished before loading the template

When my template loads first, the http request is fired. Because of this, when I load the page for the first time, it shows a 404 image src not found error in the console. However, after a few milliseconds, the data successfully loads. After researching a ...

I'm looking to have a span and an input side by side, both spanning the full width of the containing div. How can I achieve this?

In my code snippet below: <html> <body> <div style="width: 700px;"> <span>test</span> <input style="width: 100%;"></input> </div> </body> </html> I am facing an issue where the span and input el ...

AJAX Object Creation: Only Visible After Manual Refresh

Currently, I am in the process of building a basic to-do app that includes multiple different lists, each of which contains a variety of items. My main objective is to integrate AJAX functionality into the creation and display of lists on the lists#index p ...

Guide on viewing chromedriver logs during Protractor testing

I've recently discovered that chromedriver has the ability to generate a logfile (https://sites.google.com/a/chromium.org/chromedriver/logging) While the process of setting up this feature when running the executable directly is clear: chromedriver. ...

Utilizing svgr in NextJS with TypeScript and Webpack

I have a collection of separate svg files that I want to load in React and use as React components. Here is an example of how I am trying to do this: import SampleIcon from '@/components/editor/icons/add-column-after.svg'; <SampleIcon classNam ...

A malfunction report stemming from an HTTP error code while using react.js/javascript

In my react.js application, I have a Component that displays an error code. It currently looks like this: https://i.stack.imgur.com/2usiy.png Now, in addition to displaying just the code, I also want to show the reason for the error. Similar to how this ...