Bruno Gomes
Bruno Gomes

Reputation: 209

Toggle a class on click on to an element at the same level (sibling?) but do not toggle on other elements with same class

I'm trying to do a simple toggleClass to an element by clicking another element. There are multiple elements with the same class and i'd like to toggle only the sibling / closest one. I believe I'm fundamentally getting the concepts of targeting the parent/child/siblings wrong. Any assist is very much appreciated.

Current progress:

$(".toggle-btn").click(() => {
  $(".content.collapsible").toggleClass("collapsed");
});
.content {
  transition: max-height 0.3s ease-in-out;
  height: auto;
  max-height: 3000px;
  overflow: hidden;
}

.content.collapsed {
  max-height: 0;
}

ul { list-style-type: none; padding: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 1</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 2</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 3</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 4</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 5</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>
</ul>

This is currently to toggleClass on all the elements:

$(".toggle-btn").click(() => {  
   $(".content.collapsible").toggleClass("collapsed");
});

I've tried a few different ways to modify the snipped to solve my problem. I left some commented out attempts in the provided codepenn.

Upvotes: 1

Views: 67

Answers (2)

connexo
connexo

Reputation: 56853

I would install a delegate listener in each of the lists instead of registering a click event listener on each toggle button. The list catches the click event because by default click event bubble up in the DOM. Inside the click listener I check if the click target was a .toggle-btn, and if so, find the first .content.collapsible that shares the parent element with the clicked element.

Because I strongly prefer vanilla Javascript over any library usage, here's an example in good old plain Javascript:

const toggleLists = document.querySelectorAll('.toggleList');

for (const toggleList of toggleLists) {
  toggleList.addEventListener('click', (event) => {
    // make sure you only handle those clicks you want
    if (event.target.classList.contains('toggle-btn')) {
      event.target.parentElement.querySelector('.content.collapsible').classList.toggle('collapsed');
    }
  })
}
.content {
  transition: max-height 0.3s ease-in-out;
  height: auto;
  max-height: 3000px;
  overflow: hidden;
}

.content.collapsed {
  max-height: 0;
}

.toggleList { list-style-type: none; padding: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="toggleList">
  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 1</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 2</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 3</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 4</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>

  <li class="dropdown">
    <a href="#" class="label toggle-btn">Test Button 5</a>
    <div class="content collapsible">
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure
        dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p>

    </div>
  </li>
</ul>

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075925

...only the sibling / closest one...

If you really mean sibling (same parent), then use siblings with a selector filter, and don't use an arrow function (so that jQuery can control what this is during the handler callback):

$(".toggle-btn").click(function() {  
   $(this).siblings(".content.collapsible").toggleClass("collapsed");
});

Live Example:

$(".toggle-btn").click(function() {  
   $(this).siblings(".content.collapsible").toggleClass("collapsed");
});
.content {
    transition:max-height 0.3s ease-in-out;
    height:auto;
    max-height:3000px;
    overflow: hidden;
  }

  .content.collapsed {
    max-height:0;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="dropdown"> 
  <a href="#" class="label toggle-btn">Test Button 1</a>
  <div class="content collapsible"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> 
    
  </div>
</li>

<li class="dropdown"> 
  <a href="#" class="label toggle-btn">Test Button 2</a>
  <div class="content collapsible"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> 
    
  </div>
</li>

<li class="dropdown"> 
  <a href="#" class="label toggle-btn">Test Button 3</a>
  <div class="content collapsible"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> 
    
  </div>
</li>

<li class="dropdown"> 
  <a href="#" class="label toggle-btn">Test Button 4</a>
  <div class="content collapsible"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> 
    
  </div>
</li>

<li class="dropdown"> 
  <a href="#" class="label toggle-btn">Test Button 5</a>
  <div class="content collapsible"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing 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. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. </p> 
    
  </div>
</li>
</ul>

Upvotes: 1

Related Questions