-1

I am using my CMS to output list items, and then I am using .wrapAll() to wrap the list items in a ul based on their class. This is to basically group them, because I can't do it on the server side with my CMS.

But it is wrapping list items that have the same class into one unordered list. How can I get around this?

jQuery

$('.week_7').wrapAll('<ul class="devotionals"/>');
$('.week_6').wrapAll('<ul class="devotionals"/>');
$('.week_5').wrapAll('<ul class="devotionals"/>');
$('.week_4').wrapAll('<ul class="devotionals"/>');
$('.week_3').wrapAll('<ul class="devotionals"/>');
$('.week_2').wrapAll('<ul class="devotionals"/>');
$('.week_1').wrapAll('<ul class="devotionals"/>');

HTML: Before jQuery

<li class="week_1">Day 1</li>
<li class="week_1">Day 2</li>
<li class="week_1">Day 3</li>
<li class="week_1">Day 4</li>
<li class="week_1">Day 5</li>
<li class="week_2">Day 1</li>
<li class="week_2">Day 2</li>
<li class="week_2">Day 3</li>
<li class="week_2">Day 4</li>
<li class="week_2">Day 5</li>

This continues to continue list items with week 3 through 7.

HTML: After jQuery

<ul>
    <li class="week_1">Day 1</li>
    <li class="week_1">Day 2</li>
    <li class="week_1">Day 3</li>
    <li class="week_1">Day 4</li>
    <li class="week_1">Day 5</li>
    <li class="week_1">Day 1</li>
    <li class="week_1">Day 2</li>
    <li class="week_1">Day 3</li>
    <li class="week_1">Day 4</li>
    <li class="week_1">Day 5</li>
    <li class="week_2">Day 1</li>
    <li class="week_2">Day 2</li>
    <li class="week_2">Day 3</li>
    <li class="week_2">Day 4</li>
    <li class="week_2">Day 5</li>
    <li class="week_2">Day 1</li>
    <li class="week_2">Day 2</li>
    <li class="week_2">Day 3</li>
    <li class="week_2">Day 4</li>
    <li class="week_2">Day 5</li>
</ul>

HTML: How it should render

<ul>
    <li class="week_1">Day 1</li>
    <li class="week_1">Day 2</li>
    <li class="week_1">Day 3</li>
    <li class="week_1">Day 4</li>
    <li class="week_1">Day 5</li>
    <li class="week_2">Day 1</li>
    <li class="week_2">Day 2</li>
    <li class="week_2">Day 3</li>
    <li class="week_2">Day 4</li>
    <li class="week_2">Day 5</li>
</ul>
<ul>
    <li class="week_1">Day 1</li>
    <li class="week_1">Day 2</li>
    <li class="week_1">Day 3</li>
    <li class="week_1">Day 4</li>
    <li class="week_1">Day 5</li>
    <li class="week_2">Day 1</li>
    <li class="week_2">Day 2</li>
    <li class="week_2">Day 3</li>
    <li class="week_2">Day 4</li>
    <li class="week_2">Day 5</li>
</ul>

EDIT This is basically what it is in HTML.

Before jQuery

<section class="series">
    <h1>June</h1>
    <li class="week_1">Day 1</li>
    <li class="week_1">Day 2</li>
    <li class="week_1">Day 3</li>
    <li class="week_1">Day 4</li>
    <li class="week_1">Day 5</li>
    <li class="week_2">Day 1</li>
    <li class="week_2">Day 2</li>
    <li class="week_2">Day 3</li>
    <li class="week_2">Day 4</li>
    <li class="week_2">Day 5</li>
</section>
<section class="series">
    <h1>July</h1>
    <li class="week_1">Day 1</li>
    <li class="week_1">Day 2</li>
    <li class="week_1">Day 3</li>
    <li class="week_1">Day 4</li>
    <li class="week_1">Day 5</li>
    <li class="week_2">Day 1</li>
    <li class="week_2">Day 2</li>
    <li class="week_2">Day 3</li>
    <li class="week_2">Day 4</li>
    <li class="week_2">Day 5</li>
</section>

After jQuery

<section class="series">
    <h1>June</h1>
    <ul class="devotionals">
        <li class="week_1">Day 1</li>
        <li class="week_1">Day 2</li>
        <li class="week_1">Day 3</li>
        <li class="week_1">Day 4</li>
        <li class="week_1">Day 5</li>
        <li class="week_1">Day 1</li> <!-- July Week 1 -->
        <li class="week_1">Day 2</li>
        <li class="week_1">Day 3</li>
        <li class="week_1">Day 4</li>
        <li class="week_1">Day 5</li>
        <li class="week_2">Day 1</li>
        <li class="week_2">Day 2</li>
        <li class="week_2">Day 3</li>
        <li class="week_2">Day 4</li>
        <li class="week_2">Day 5</li>
        <li class="week_2">Day 1</li> <!-- July Week 2 -->
        <li class="week_2">Day 2</li>
        <li class="week_2">Day 3</li>
        <li class="week_2">Day 4</li>
        <li class="week_2">Day 5</li>
    </ul>
</section>
<section class="series">
    <h1>July</h1>

</section>
Justin Clarke
  • 139
  • 1
  • 8
  • 2
    [I can see it works](http://jsfiddle.net/zgmXy/), also this is a question to me, why you can't do it from the server side, if you can generate the `li`s dynamically then you could have also generate the `ul`s somehow. – The Alpha Oct 21 '13 at 20:52
  • Is the "how it should render" code you posted REALLY what you are aiming for? I don't see the 'class="devotionals"' bit and the way you have the listed doesn't follow from what you describe above... – AllInOne Oct 21 '13 at 21:03
  • @RecoveringSince2003 Yours works, though you are only wrapping list items with the class once. jQuery .wrapAll(); is pulling list items from other sections with list items into one unordered list. – Justin Clarke Oct 21 '13 at 21:16
  • @JustinClarke, Not sure what you are talking about but I might have misunderstood. – The Alpha Oct 21 '13 at 21:20
  • @RecoveringSince2003 I am using .wrapAll(); to group list items based on their class. When there are other list items on the page that have the same class, jQuery wraps them all into one unordered list. I don't want it to do that. I want the list items in each of the sections based on its class to be grouped in a ul normally without being grouped in other sections(
    ).
    – Justin Clarke Oct 21 '13 at 21:27
  • Solution is below--try it out. – struthersneil Oct 21 '13 at 21:35
  • @JustinClarke, if it ([fiddle](http://jsfiddle.net/zgmXy/1/)) doesn't solve the problem then you should also post the other `li`s that you are talking about, how the layedout on the page. – The Alpha Oct 21 '13 at 21:36
  • @RecoveringSince2003 I have made edits that should help you even more. Which I should of done in the beginning. – Justin Clarke Oct 21 '13 at 23:24

2 Answers2

1

I think you want something like this

$(function(){
    $('li.week_1').not('ul li').wrapAll('<ul class="devotionals"/>');
    $('.week_2').not('ul li').wrapAll('<ul class="devotionals"/>');
});

Example.

If it doesn't solve your problem then post other li (with relevant parent/location) that have same class but you want to exclude from wrapping.

Update :

$(function(){
    $('section.series').each(function(){
        var ul1 = $('<ul />', {'class':'devotionals'}), ul2 = ul1.clone();
        ul1.append($(this).find('li.week_1'));
        ul2.append($(this).find('li.week_2'));
        $(this).append(ul1).append(ul2);
    });
});

If you want to add any event handler on these lis then use something like this (delegated)

$('section.series').on('click', 'ul > li', function(){
    // code here
});

Example.

The Alpha
  • 143,660
  • 29
  • 287
  • 307
  • I have made edits that should help you even more. Which I should of done in the beginning. – Justin Clarke Oct 21 '13 at 23:24
  • Though I am going to have to change a couple things because in areas that don't have the same amount of weeks, such as one section may have 3 weeks and others may have 7, it appends the ul. – Justin Clarke Oct 22 '13 at 13:56
0

Select the first five of each class that are not already wrapped in a 'devotionals' class, and wrap those. Then repeat until there are none remaining that are not wrapped. This is the selector that you run until everything's wrapped:

$('.week_1:not(.devotionals > li):lt(5), .week_2:not(.devotionals > li):lt(5),
   .week_3:not(.devotionals > li):lt(5), .week_4:not(.devotionals > li):lt(5), 
   .week_5:not(.devotionals > li):lt(5), .week_6:not(.devotionals > li):lt(5), 
   .week_7:not(.devotionals > li):lt(5)').wrapAll('<ul class="devotionals"/>');

And to DRY that up a little:

var week_not_wrapped = '.week_X:not(.devotionals > li):lt(5)';
var weeks_not_wrapped = [];

for (var i = 1; i <= 7; ++i) 
{
  weeks_not_wrapped.push(week_not_wrapped.replace('X', i));
}

weeks_not_wrapped = weeks_not_wrapped.join(',');

do { $(weeks_not_wrapped).wrapAll('<ul class="devotionals"/>'); }
while($(weeks_not_wrapped).length > 0);

...and shrink it a bit further:

var weeks_not_wrapped = $.map([1, 2, 3, 4, 5, 6, 7], function(elem) {
  return '.week_' + elem + ':not(.devotionals > li):lt(5)';
}).join(',');

do { $(weeks_not_wrapped).wrapAll('<ul class="devotionals"/>'); } 
while($(weeks_not_wrapped).length > 0);
struthersneil
  • 2,700
  • 10
  • 11