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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With