1

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.

connexo
  • 41,035
  • 12
  • 60
  • 87
Bruno Gomes
  • 199
  • 1
  • 1
  • 8
  • I would [start here](https://www.google.com/search?q=jquery+sibling&rlz=1C1GCEU_enGB821GB821&oq=jquery+sibling&aqs=chrome..69i57j0l5.3806j0j7&sourceid=chrome&ie=UTF-8) . Did you do any research into this up to now? Also I would avoid using arrow functions for handling the event, because it [doesn't give you a useful definition of `this`](https://medium.freecodecamp.org/when-and-why-you-should-use-es6-arrow-functions-and-when-you-shouldnt-3d851d7f0b26?gi=3c84191d0965) – ADyson May 20 '19 at 14:54

2 Answers2

1

...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>
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • oh nice seems like the arrow function was the reason everything i tried didn't work? – Bruno Gomes May 20 '19 at 14:57
  • @BrunoGomes - Ah, yeah, that might have bitten you. [More here](https://stackoverflow.com/questions/31095710/methods-in-es6-objects-using-arrow-functions). Happy coding! – T.J. Crowder May 20 '19 at 15:04
0

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>
connexo
  • 41,035
  • 12
  • 60
  • 87