Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery wrap every X elements in div

I have a list of elements (divs) preseded by a H3 tag

<h3></h3>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<h3></h3>
<div class="item"></div>
<div class="item"></div>

etc...

Using jQuery, I'd like to group every 3 divs (or less) followed by each h3 like this:

<h3></h3>
<div class=row>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
<div class=row>
    <div class="item"></div>
</div>
<h3></h3>
<div class=row>
    <div class="item"></div>
    <div class="item"></div>
</div>

I tried a solution proposed here: Insert <div> for every 5 elements using Javascript but it obviously grouped ALL the divs. I also tried using ~ selector without any success:

var a = $('h3 ~ div.item');

for( var i = 0; i < a.length; i+=3 ) {
    a.slice(i, i+3).wrapAll('<div class="row"></div>');
}

Any help will be highly appreciated.

like image 368
Daniel Sachs Avatar asked Jul 07 '12 15:07

Daniel Sachs


2 Answers

I've ended up with this and it's working

$(function(){
    var h3=$('h3');
    h3.each(function(){
        var divs=$(this).nextUntil('h3');
        var row_wreapper=$('<div></div>');
        while(divs.length)
        {
            var grp=divs.splice(0, 3);
            var row=$('<div class="row"></div>');
            $(grp).each(function(){
                row.append($(this));
            });
            row_wreapper.append(row);
        }
        $(this).after(row_wreapper.html());
    });
});​

DEMO or with a little extra checking of item class DEMO.

Or

$(function(){
    var h3=$('h3');
    h3.each(function(){
    var divs=$(this).nextUntil('h3');
    var row_wreapper=$('<div></div>');
    while(divs.length)
    {
        var grp=divs.splice(0, 3);
        var row=$(grp).wrapAll('<div class="row"></div>');
        if(row.children().length) row_wreapper.append(row);
    }
    $(this).after(row_wreapper.html());
    });
});​

DEMO.

like image 142
The Alpha Avatar answered Oct 04 '22 01:10

The Alpha


There is a plugin here that I use when I want to wrap, just because it's clean and allows me to do amazing things. || You can find the source for the wrapper in plain-text here

The only issue is that -- because of your DOM we have to do some structuring of all the items and group them, before we can iterate over those lists.

We'll do this first by ->

$.each($('h3'), function(i,v){
  $(v).nextUntil($('h3')).wrapAll('<div class="row-container"></div>');    
});

.nextUntil() is jQuery 1.6+, so hopefully there's no restrictions there.

Now, with the plugin above that I've linked, we can reference it and have it wrap objects within each new row-container.

$.each($('.row-container'), function(i,v){
  $(v).nwrapper({
    wrapEvery      : 3,
    defaultClasses : false,
    extraClasses: ['row']     
  });
});

The proof is in the pudding so here's the jsFiddle

like image 29
Ohgodwhy Avatar answered Oct 04 '22 01:10

Ohgodwhy