Carl Papworth Carl Papworth - 6 months ago 7
Javascript Question

jQuery, function within function targets wrong div

I have set of objects where I'm hiding

div
inside the wrapper, which alos has a child
<a>
button that toggles a slideDown-effect on the hidden object. However when clicked it opens only the hidden div in the last object, instead of only in ITS child

Simplified HTML:

<div class="panel-compressed">
<div class="panel-header">
<div class="toggle-panel">
<a href="#" class="toggle-panel-btn">Open content</a>
</div>
</div>
<div class="panel-body">
<p>Content goes here</p>
</div>
</div>

<div class="panel-compressed">
<div class="panel-header">
<div class="toggle-panel">
<a href="#" class="toggle-panel-btn">Open content</a>
</div>
</div>
<div class="panel-body">
<p>Content goes here</p>
</div>
</div>

<div class="panel-compressed">
<div class="panel-header">
<div class="toggle-panel">
<a href="#" class="toggle-panel-btn">Open content</a>
</div>
</div>
<div class="panel-body"> <!-- THIS OPENS WHEN CLICKING ANY .toggle-panel-btn -->
<p>Content goes here</p>
</div>
</div>


JS:

var $panelToggle = $('.toggle-panel-btn'); //Toggle button
var $panelBody = $('.panel-body'); //Hidden content
var $panelCompressed = $('.panel-compressed') //Wrapper

function togglePanel(){
$this = $(this);
$this.find($panelBody).hide();
//Open .panel-body
function showPB() {
$this.find($panelBody).slideDown();
$this.find($panelToggle).one("click", hidePB);
$this.addClass('dropdown-open');
}

//close .panel-body
function hidePB() {
$this.find($panelBody).slideUp();
$this.find($panelToggle).one("click", showPB);
$this.removeClass('dropdown-open');
}
$this.find($panelToggle).click("click", showPB);
}

$panelCompressed.each(togglePanel);

Answer

Your code is far too complex.

Here is a simpler one:

$(function() {
  $('.panel-compressed .toggle-panel-btn').on("click",function(e) {
     e.preventDefault(); // cancel link click
     var $panelBody = $(this).closest(".panel-compressed").find('.panel-body').slideToggle();
  });
});
.panel-body { display:none }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="panel-compressed">
  <div class="panel-header">
     <div class="toggle-panel">
       <a href="#" class="toggle-panel-btn">Open content</a>
     </div>
   </div>
   <div class="panel-body">
       <p>Content goes here</p>
   </div>
</div>

<div class="panel-compressed">
  <div class="panel-header">
     <div class="toggle-panel">
       <a href="#" class="toggle-panel-btn">Open content</a>
     </div>
   </div>
   <div class="panel-body">
       <p>Content goes here</p>
   </div>
</div>

<div class="panel-compressed">
  <div class="panel-header">
     <div class="toggle-panel">
       <a href="#" class="toggle-panel-btn">Open content</a>
     </div>
   </div>
   <div class="panel-body"> <!-- THIS OPENS WHEN CLICKING ANY .toggle-panel-btn -->
       <p>Content goes here</p>
   </div>
</div>