davidglassford
davidglassford

Reputation: 183

Wrapping a series of elements between two h2 tags with jquery

I currently have a page being dynamically created like below:

<h2>a Heading</h2>
<p>a paragraph</p> 
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<h2>a Heading</h2>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  

What I'm looking to do is to use jQuery to wrap the h2 and p tags till the next h2 tag: e.g.:

<div class="headingName">
<h2>a Heading</h2>  
<p>a paragraph</p> 
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>
</div>
<div class="headingName">
<h2>a Heading</h2>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
<p>a paragraph</p>  
</div>

So far I unsuccessfully managed this, but have gotten close using code from a user here (can't find the link to the original article):

$('.report-content h2').each(function(){
    var $set = $();
    var nxt = this.nextSibling;
    while(nxt) {
        if(!$(nxt).is('.report-content h2')) {
            $set.push(nxt);
            nxt = nxt.nextSibling;
        } else break;
    } 
   $set.wrapAll('<div class="content" />');
});

What I get is the div being wrapped around only the p tags but need to include the associated h2 tag, usually the one above the p tags.

Upvotes: 12

Views: 5566

Answers (4)

scottheckel
scottheckel

Reputation: 9244

Take each h2, grab all sibilings until you get another h2 (or there are no elements at this level) and then reinclude the h2 in the set. Here's the JSFiddle.

$('.report-content h2').each(function(){ 
    $(this)
        .nextUntil("h2")
        .addBack()
        .wrapAll('<div class="content" />');
});

jQuery Documentation

Upvotes: 26

Phillip Chan
Phillip Chan

Reputation: 993

P.S. If anyone is looking for the answer to this for jQuery 1.8+, addSelf() is deprecated in favor of addBack().

A modification to @Hexxagonal's answer worked for me:

$('.report-content h2').each(function(){ 
    var $set = $(this).nextUntil("h2").addBack();
    $set.wrapAll('<div class="content" />');
});

See:

Upvotes: 2

campino2k
campino2k

Reputation: 1671

$('.report-content h2').each(function(){
    var $set = $(this); // this is your key ;)
    var nxt = this.nextSibling;
    while(nxt) {
        if(!$(nxt).is('.report-content h2')) {
            $set.push(nxt);
            nxt = nxt.nextSibling;
        } else break;
    } 
   $set.wrapAll('<div class="content" />');
});

See http://jsfiddle.net/mMpVB/

Upvotes: 2

SeanCannon
SeanCannon

Reputation: 78006

Check out JQuery's nextUntil() function

Upvotes: 0

Related Questions