Stefano De Rosso
Stefano De Rosso

Reputation: 1339

jQuery - toggle only next element

I'd like to toggle just the next element (and not others) with jQuery: I'll explain myself with examples.

This is the HTML:

<article id="post-60" class="post-60 page type-page status-publish hentry">
    <header class="entry-header">
        <h1 class="entry-title">Pagine Critiche</h1>
    </header><!-- .entry-header -->

    <div class="entry-content">
        <p><strong>TITLE 1.1</strong></p>
        <p><strong>TITLE 1.2</strong></p>
        <p><em>Writer writes:</em></p>
        <p>Article #1</p>
        <p>&nbsp;</p>

        <p><strong>TITLE 2.1</strong></p>
        <p><strong>TITLE 2.2</strong></p>
        <p><em>Writer writes:</em></p>
        <p>Article #2.1</p>
        <p>Article #2.2</p>
        <p>Article #2.3</p>
    </div>
</article>

I'd like to click on TITLE 1.1 and show (toggle) ALL that there is between TITLE 1 and TITLE 2 (so everything between the first "strong p" and the second "strong p"); in a few words: I'd like to toggle just the article that refers to that title.

I've tried to write this script:

$(document).ready(function(){
    $("#post-60 p strong").click(function(){
        $("p:not(:has(strong))").toggle(500);
    });
});

But it toggles all the "normal" paragraph at the same time; here's the fiddle.
I believe I need the next() selector, but I'm not using it the right way, like I tried this:

$(document).ready(function(){
    $("#post-60 p strong").click(function(){
        $("p:not(:has(strong))").next().toggle(500);
    });
});

but it's not working either.

I'd like to solve it without having to edit the HTML markup.

Upvotes: 1

Views: 295

Answers (2)

Dev Overflow
Dev Overflow

Reputation: 58

If you can't update your markup then apply this JS.

$(document).ready(function(){
    $("#post-60 p strong").click(function(){
        $(this).parent().next('p').nextUntil( "p:has(strong)").toggle(500);
    });
});

Working fiddle https://jsfiddle.net/xpxhkh1r/3/

It would be much more simpler if you could just rewrite your markup. Here is a example.

<div class="entry-content">
    <p><strong>TITLE 1.1</strong></p>
    <div class="item">
        <p><strong>TITLE 1.2</strong></p>
        <p><em>Writer writes:</em></p>
        <p>Article #1</p>
        <p>&nbsp;</p>
    </div>

    <p><strong>TITLE 2.1</strong></p>
    <div class="item">
        <p><strong>TITLE 2.2</strong></p>
        <p><em>Writer writes:</em></p>
        <p>Article #2.1</p>
        <p>Article #2.2</p>
        <p>Article #2.3</p>
    </div>
</div>

And the JS should look like

$(document).ready(function(){
    $("#post-60 p strong").click(function(){
        $(this).parent().next('.item').toggle(500);
    });
});

See the updated fiddle https://jsfiddle.net/xpxhkh1r/1/

Upvotes: 2

mplungjan
mplungjan

Reputation: 177786

Do you mean this?

$(function() {
  $("#post-60 p>strong").click(function() {
    var $thisP = $(this).closest("p");
    if ($thisP.next().has("strong").length > 0) { // next P has strong, we are on x.1
      $thisP.next().toggle(500);
      $thisP.next().nextUntil("p:has(strong)").toggle(500);
    } else { // we are on x.2
      $thisP.nextUntil("p:has(strong)").toggle(500);
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<article id="post-60" class="post-60 page type-page status-publish hentry">
  <header class="entry-header">
    <h1 class="entry-title">Pagine Critiche</h1>
  </header>
  <!-- .entry-header -->

  <div class="entry-content">
    <p><strong>TITLE 1.1</strong>
    </p>
    <p><strong>TITLE 1.2</strong>
    </p>
    <p><em>Writer writes:</em>
    </p>
    <p>Article #1</p>
    <p>&nbsp;</p>

    <p><strong>TITLE 2.1</strong>
    </p>
    <p><strong>TITLE 2.2</strong>
    </p>
    <p><em>Writer writes:</em>
    </p>
    <p>Article #2.1</p>
    <p>Article #2.2</p>
    <p>Article #2.3</p>
  </div>
</article>

Upvotes: 1

Related Questions