Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping consecutive list items in separate groups using jQuery

I have an unordered list exported by a CMS and need to identify <li> elements that have the class .sub and wrap them in a <ul>.

I have tried the wrapAll() method but that finds all <li class="sub"> elements and wraps them in one <ul>. I need it to maintain seperate groupings.

The exported code is as follows:

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li></li>
  <li></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li class="sub"></li>
  <li></li>
 </ul>

I need it to be:

<ul>
  <li></li>
  <li></li>
  <li></li>
  <ul>
     <li class="sub"></li>
     <li class="sub"></li>
     <li class="sub"></li>
  </ul>
  <li></li>
  <li></li>
  <li></li>
  <ul>
     <li class="sub"></li>
     <li class="sub"></li>
     <li class="sub"></li>
   </ul>
   <li></li>
   <li></li>
</ul>

Any help would be greatly appreciated.

like image 496
Lucas JD Avatar asked Dec 17 '22 04:12

Lucas JD


1 Answers

  1. Use .each to walk through all .sub elements.
  2. Ignore elements whose parent has class wrapped, using hasClass()
  3. Use nextUntil(:not(.sub)) to select all consecutive sub elements (include itself using .andSelf()).
    The given first parameter means: Stop looking forward when the element does not match .sub.
  4. wrapAll

Demo: http://jsfiddle.net/8MVKu/

For completeness, I have wrapped the set of <li> elements in <li><ul>...</ul></li> instead of a plain <ul>.

Code:

$('.sub').each(function() {
   if ($(this.parentNode).hasClass('wrapped')) return;
   $(this).nextUntil(':not(.sub)').andSelf().wrapAll('<li><ul class="wrapped">');
});
$('ul.wrapped').removeClass('wrapped'); // Remove temporary dummy
like image 158
Rob W Avatar answered Dec 18 '22 17:12

Rob W