skip to Main Content

I am trying to create an accordion element that can be used throughout my website. I’ve managed to get the logic working, sort off… I will select any of the accordions to open and effectively add a class called ‘show’, however it only works for the first accordion in the parent container holding each accordion element.

And sometimes it opens all of them at once, I want it to have to functionality of the user being able open and close any of the accordions displayed 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>
<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>

2

Answers


  1. Your line $(".accordian-content").toggleClass("show"); searches the entire DOM-Tree for all matching elements that have the class ‘.accordian-content’, and toggling the class show for all those elements.

    As your content is always a child of the .accord element, you can use $(this) in the click callback to recieve the clicked element. With this, we can then use .find(SELECTOR) to search the childs for a matching element, in this case .accordian-content. This will result in the expected element to show.

    (function ($) {
    
        $(".accord").on("click", function (e) {
        
        // Changed this Line to find the Accordian-content thats 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>
    Login or Signup to reply.
  2. There may be a more efficient method, but I’ve always found that using unique identifiers to pick up which item has been clicked and apply that ID to the accordian template works best.

    I’ve added some ID’s to your text, and changed the javascript slightly to apply the number from the clicked div to the accordian content control.

    The added benefit of the unique id method is that if you wanted to open the page and target a specific accordian to open on load, it can be done via the ID, whereas it gets a little more complicated without an ID. That may or may not be something you need to accomplish.

    (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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search