views:

493

answers:

4

First thing, i know i should use a server side language to accomplish this not client side like jquery but that's not the point, i'm just trying to learn how to use it to manipulate html. Heres the html:

<div class="items">
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="1.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 1</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="2.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 2</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="3.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 3</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="4.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 4</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="5.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 5</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="6.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 6</span></div></div>
</div>

I want to be able to wrap every 3 <divs> within the <div class="items"> with yet another div: <div class="row"></div>. So it end up like this:

<div class="items">
 <div class="row">  
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="1.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 1</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="2.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 2</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="3.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 3</span></div></div>
 </div>
 <div class="row">
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="4.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 4</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="5.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 5</span></div></div>
  <div class="boxgrid"><span class="cushycms"><a href="#"><img src="6.jpg" alt=""/></a></span><div class="cover"><span class="film_title">Title 6</span></div></div>
 </div>
</div>

How can i accomplish this with jquery's selectors? I thought i can use something like:

$("div.items:nth-child(3n)").wrap('<div class="row"></div>');

But that doesn't work. Any ideas please?

+4  A: 

I think what you actually want is the range of divs between 1 and 3, not just wrapping the third div, yeah?

For getting a range you'll need to use jquery slice.

Steerpike
A: 

Use map(), slice(), and wrapAll();

 $(document).ready( function(){
  var results =[];
  var elements = $(".items").children('.boxgrid');
  $.map( elements  , function(i, n){
   if( n%3 === 0 ){
    results.push(n);
   }
  });
  $.each( results , function(i,v){
   elements.slice(v, v+3).wrapAll('<div class="row"></div>');
  });
 });

This is tested and works.

Elzo Valugi
I may be being silly here, but aren't you using map as if it were each? - couldn't you do results = $.map(... and return n rather than pushing onto results?
Whisk
you are right and I could be further optimized, it just shows a way to do it.
Elzo Valugi
+1  A: 

As a plugin:

jQuery.fn.wrapInChunks = function(html, chunkSize) {

    chunkSize = chunkSize || 1;

    var items = this.get(),
        rows = [],
        cur = rows[0] = $(html);

    while (items[0]) {

        if (rows[rows.length - 1].children().length === chunkSize) {
            cur = rows[rows.length] = $(html);
        }

        cur.append( items.shift() );

    }

    return this.pushStack(rows);

};

$('.boxgrid').wrapInChunks('<div class="row" />', 3).appendTo('.items');
J-P
A: 

You would have to slice the elements and make new div elements to contain the sliced elements. Below is a code example. I'm not aware of any more simpler method to do this.

$(".items").each(function()
{ 
 var rowDiv = document.createElement("div");
 $(rowDiv).addClass("row");

 for(i=0; i< $(this).find("> .boxgrid").length ; i+= 3)
 { 
  $(rowDiv).append( $(this).find("> .boxgrid").slice(i, i+3).clone() );  
  $(this).append(rowDiv);
  rowDiv = document.createElement("div");
  $(rowDiv).addClass("row");
 }
 $(this).find("> .boxgrid").remove();//Remove all the immediate boxgrid child elements. 
});
Technowise