Combining consecutive list items into separate groups using jQuery

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

I tried the wrapAll() method, but found all the <li class="sub"> elements and wrapped them in a single <ul> . I need him to support individual groups.

The export 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 this 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.

+4
source share
3 answers
  • Use .each to go through all the .sub elements.
  • Ignore elements whose parent has wrapped class using hasClass()
  • Use nextUntil(:not(.sub)) to select all consecutive subelements (enable yourself using .andSelf() ).
    This first parameter means: Stop searching forward when the item does not match .sub .
  • wrapAll

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

For completeness, I wrapped a set of <li> elements in <li><ul>...</ul></li> instead of a simple <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 
+7
source

I would like to extend Rob W to an already awesome solution providing a way to eliminate the temporary transfer class:

 $(document).ready(function() { $('li.sub').filter(':not(li.sub + li.sub)').each(function() { $(this).nextUntil(':not(li.sub)').andSelf().wrapAll('<li><ul>'); }); }); 

http://jsfiddle.net/m8yW3/

Edit: filter is not even needed:

 $('li.sub:not(li.sub + li.sub)').each(function() { $(this).nextUntil(':not(li.sub)').andSelf().wrapAll('<li><ul>'); }); 
+5
source

I believe you need this jQuery:

$('li.sub').wrap('<li><ul>');

This will correctly wrap your <li> elements in a new <ul> , wrapping them in <li> tags. The result of your example will be as follows:

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

Source: https://habr.com/ru/post/1393223/


All Articles