Search code examples
jquerywordpresssiblingsjquery-traversing

Finding next sibling of parent in Jquery


I've seen this (apparently) exact same problem addressed here, but the solution is simply not working for me. I can't seem to select the element I wish to show / hide.

I have the following HTML, repeated for several similar items:

<div class="item">
  <div class="titleRow">
    <h3 class="yesterday">Some text</h3>
    <h3 class="today">Some other text</h3>
  </div>
</div> <!-- /item (table) -->

<div class="details">
  <p>A long paragraph of description.</p>
</div>

And this JS:

$('.details').hide();

$('body.page-id-55 .titleRow').toggle(
    function() {

    $(this).parent().next('.details').slideDown();
    $(this).addClass('close');
    },

    function() {
    $(this).parent().next('.details').slideUp();
    $(this).removeClass('close');
    }
)

My understanding is that since .titleRow is being clicked, and .details is the next sibling of its parent (.item), .details should be targeted, and roll down and up when the .titleRow div is clicked.

But in fact nothing happens.

If I change that line to

$('.details').slideDown();

It works, but of course ALL instances of .details roll down and up. I just want the next one after the clicked div to activate.

What am I doing wrong?

UPDATE:

Even with andyface's great suggestion, I still get no action when clicking. I even tried this:

$('body.page-id-55 .titleRow').on('click', function() {

    $details = $(this).parent().next('.details');

    $details.show();

});

To (I would assume) force all .details to simply become visible - but nothing happens then, either.

Possible interference from other JS's on my page?

Still seems like the tree-traversal is the issue, since if I do this:

$('body.page-id-55 .titleRow').on('click', function() {

  $('.details').show();

});

They all appear.

As for potential conflict from other javascripts being loaded, I can at least confirm that my js is the last one being loaded, since I'm using correct WordPress enqueuing method to load it via functions.php. Here's all the js's in the header - my two (one for another page) are last:

<script type='text/javascript' src='http://gazeleyandgazeley.com/site/wp-includes/js/jquery/jquery.js?ver=1.11.0'></script>
<script type='text/javascript' src='http://gazeleyandgazeley.com/site/wp-includes/js/jquery/jquery-migrate.min.js?ver=1.2.1'></script>
<script type='text/javascript' src='http://gazeleyandgazeley.com/site/wp-content/themes/twentythirteen-child/js/sidebarfix.js?ver=9.9.9'></script>
<script type='text/javascript' src='http://gazeleyandgazeley.com/site/wp-content/themes/twentythirteen-child/js/gteam.js?ver=9.9.9'></script>
<script type='text/javascript' src='http://gazeleyandgazeley.com/site/wp-content/themes/twentythirteen-child/js/rolldowns.js?ver=9.9.9'></script>

Would loading it first, or at the end of the document, make a difference? It seems that since the traversing is the only thing "not" working, that it's something about that, not to do with another js conflict... but then again, i don't really know anything. 8^)


Solution

  • Without changing your HTML structure, I would suggest using additional attibute to determine which details to toggle. In the example below I use data-details attribute for title div and id for details div - in order to match proper sections:

    HTML

    <div class="item">
      <div class="titleRow" data-details="1">
        <h3 class="yesterday">Some text</h3>
        <h3 class="today">Some other text</h3>
      </div>
    </div> <!-- /item (table) -->
    
    <div class="details" id="1">
      <p>A long paragraph of description.</p>
    </div>
    
    <div class="item">
      <div class="titleRow" data-details="2">
        <h3 class="yesterday">Some text</h3>
        <h3 class="today">Some other text</h3>
      </div>
    </div> <!-- /item (table) -->
    
    <div class="details" id="2">
      <p>A long paragraph of description.</p>
    </div>
    

    JS

    $('.titleRow').click(function() {
        var details_id = $(this).data('details');
        $('div[id="' + details_id + '"]').toggle();
    });
    

    PS. You don't need to use hide() for the details divs. Simple CSS display: none will do it.

    Working code with comments: http://jsfiddle.net/PhAhu/