views:

153

answers:

5

Hi all - I have a UL that contain any number of LIs. I am trying to create some jQuery code that will parse the original UL and wrap a UL and another LI after every 5 of the original LIs.

Starting HTML:

<ul id="original_ul">
    <li class="original_li">..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
    <li>..</li>
</ul>

Required HTML:

<ul id="processed_ul">

    <li class="new_wrap_li">

        <ul class="new_wrap_ul">

            <li class="original_li">..</li>
            <li>..</li>
            <li>..</li>
            <li>..</li>
            <li>..</li>

        </ul><!-- end new wrap ul -->

    </li><!-- end new wrap li -->

    <li class="new_wrap_li">

        <ul class="new_wrap_ul">

            <li class="original_li">..</li>
            <li>..</li>
            <li>..</li>
            <li>..</li>
            <li>..</li>

        </ul><!-- end new wrap ul -->

    </li><!-- end new wrap li -->

</ul><!-- end processed ul -->

I've been using the .each function to go through the LIs and append them to the new processed ul held inside a temp div... now I just need to wrap the new LI and UL around every 5 LIs.

Thanks in advance!!

Al

+1  A: 

You can use a loop.

For example: (Untested)

while($('ul#original li').length) {
    var newContainer = $('<li class="new_wrap_li"><ul class="new_wrap_ul" /></li>')
        .appendTo('#processed_ul');


    $('ul#original li:lt(4)').detach().appendTo(newContainer.children('ul'));
}
SLaks
+2  A: 

You can do this:

var lis = $("#original_ul li");
for(var i = 0; i < lis.length; i+=5) {
  lis.slice(i, i+5)
     .wrapAll("<li class='new_wrap_li'><ul class='new_wrap_ul'></ul></li>");
}

This keeps them in the same #original_ul element, but you could just change the ID if that's necessary. This approach generates the exact output html you have in the question aside from the ID on the top <ul>

Nick Craver
Wow, this was my first posting ever on stackoverflow and I never imagined receiving so many helpful responses!! Thanks a lot everyone! I went with Nick's solution as it seems the simplest and I don't even need my temp div anymore - I just perform the actions directly on the orginal list. Thanks a lot mate!!
Al
A: 

Something like this will do it:

$('#original_ul').find('li:nth-child(5n)').each(function(){
    $(this).prevAll('li').andSelf()
        .wrapAll('<ul class="new_wrap_ul"></ul>');
}).end().find('ul').wrap('<li class="new_wrap_li"></li>')
.find('li:first-child').addClass('original_li');
PetersenDidIt
A: 
jQuery('ul#original_ul').attr('id', 'processed_ul')
    .find('li:nth-child(5n)').each(function() {
        $(this).prevAll('li').andSelf()
            .wrapAll('<li class="new_wrap_li"><ul class="new_wrap_ul"></ul></li>');
    });
166_MMX
A: 

DEMO: http://jsbin.com/agixi/edit

If you know how many items ( ex: 10 ) why not use eq() for find LI index? :-)

var wrp = '<li class="new_wrap_li"><ul class="new_wrap_ul"></ul></li>';
$('li').eq(5).nextAll().andSelf().wrapAll(wrp).eq(0).attr('class','original_li');
$('li').eq(4).prevAll().andSelf().wrapAll(wrp);

btw imho the most elegant is the one from Nick Craver ;-)

aSeptik