mhalici
mhalici

Reputation: 55

How to wrap all elements that are next to each other and have the same class?

I would like to know how to wrap all elements that are next to each other and have the same class. .wrapAll() didn't work since it pushes the paragraph to the bottom.

Source:

<div class="container">
  <div class="group"></div>
  <div class="group"></div>
  <div class="group"></div>

  <p>Lorem ipsum dolor sit amet</p>

  <div class="group"></div>
  <div class="group"></div>
  <div class="group"></div>
</div>

Desired output:

<div class="container">
  <div class="group-wrapper">
    <div class="group"></div>
    <div class="group"></div>
    <div class="group"></div>
  </div>

  <p>Lorem ipsum dolor sit amet</p>

  <div class="group-wrapper">
    <div class="group"></div>
    <div class="group"></div>
    <div class="group"></div>
  </div>
</div>

Upvotes: 1

Views: 1968

Answers (2)

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196187

You will have to break it to groups between the non-matching elements.

$(function(){
    $.fn.reverse = [].reverse;
    var target = '.group', // the class of the elements to group
        invert = ':not(' + target + ')', // we create the invert to find the breakpoints
        wrap = '<div class="group-wrapper">', // what to wrap with
        breakpoints = $('.container > *'+invert); // find the breakpoints in our container

   breakpoints.each(function(){
        $(this).nextUntil(invert).wrapAll( wrap ); // get the matching elements efter this breakpoint and wrap them
    });

    breakpoints.first().prevUntil(invert).reverse().wrapAll( wrap ); // wrap the elements before the first breakpoint

});

Demo at http://jsfiddle.net/gaby/qz53fggd/

Upvotes: 5

charlietfl
charlietfl

Reputation: 171690

Here's one approach based on elements being children

var $container =$('.container');
function wrapGroup( target, $container){
    // wrap until next non group element
    var $groups = $container.children(target)
    if($groups.length){        
        $groups.first().nextUntil(':not('+target+')').andSelf().wrapAll('<div class="group-wrap">') 
    }
    // check if more group as children and do it again
    if($container.children(target).length){
        wrapGroup( target, $container);
    }    
}
//usage
wrapGroup('.group', $container);

DEMO

Upvotes: 1

Related Questions