Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group list items with jQuery

Tags:

jquery

dom

list

I have a list like this:

<ul>
 <li><span class="date">2011 05 01</span><p>Text...</p></li>
 <li><span class="date">2011 05 01</span><p>Text...</p></li>
 <li><span class="date">2011 04 01</span><p>Text...</p></li>
 <li><span class="date">2011 04 01</span><p>Text...</p></li>
 <li><span class="date">2010 03 01</span><p>Text...</p></li>
 <li><span class="date">2010 02 01</span><p>Text...</p></li>
</ul>

I need jQuery to group the items by both year AND month, like this:

<ul>
 <li class="year">2011
  <ul>
   <li class="month>May
    <ul>
     <li class="item"><span class="date">2011 05 01</span><p>Text...</p></li>
     <li class="item"><span class="date">2011 05 01</span><p>Text...</p></li>
    </ul>
   </li>
   <li class="month>April
    <ul>
     <li class="item"><span class="date">2011 04 01</span><p>Text...</p></li>
     <li class="item"><span class="date">2011 04 01</span><p>Text...</p></li>
    </ul>
   </li>
  </ul>
 </li>
 <li class="year">2010
  <ul>
   <li class="month>March
    <ul>
     <li class="item"><span class="date">2011 03 01</span><p>Text...</p></li>
    </ul>
   </li>
   <li class="month>February
    <ul>
     <li class="item"><span class="date">2011 02 01</span><p>Text...</p></li>
    </ul>
   </li>
  </ul>
 </li>
</ul>

Thanks.

like image 1000
Emin Avatar asked Mar 20 '26 05:03

Emin


1 Answers

I've written a commented solution here (jsFiddle) and here (jsBin).

(the two link have the same content, but jsFiddle is rather slow sometimes so you might want to go to jsBin instead)

Hope you'll like it !


HTML

<ul id="mainList">
    <li><span class="date">2011 05 01</span><p>Text...</p></li>
    <li><span class="date">2011 12 01</span><p>Text...</p></li>
    <li><span class="date">2011 05 01</span><p>Text...</p></li>
    <li><span class="date">2011 04 01</span><p>Text...</p></li>
    <li><span class="date">2011 04 01</span><p>Text...</p></li>
    <li><span class="date">2010 03 01</span><p>Text...</p></li>
    <li><span class="date">2010 02 01</span><p>Text...</p></li>
</ul>

JAVASCRIPT

// Month number to string
var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];

// Sorting the <li> by year
$("#mainList li").sort(function(a,b) {
    var yearA = $(a).children("span").text().split(" ")[0],
        yearB = $(b).children("span").text().split(" ")[0];
    return yearA < yearB;
}).appendTo($("#mainList"));

// Grouping the <li> by year
$("#mainList li").each(function() {
    var year = $(this).children("span").text().split(" ")[0];
    // If the grouping <li> doesn't exist, create it
    if ($("#mainList li.year." + year).length === 0) {
        $("#mainList").append($('<li class="year ' + year + '">' + year + '<ul></ul></li>'));
    }
    // Add the current <li> to the corresponding grouping <li>
    $(this).appendTo($("#mainList li.year." + year + " ul"));
});

// Sorting the <li> by month inside each grouping <li>
$("#mainList li.year ul").each(function() {
    $(this).children("li").sort(function(a,b) {
        var monthA = $(a).children("span").text().split(" ")[1],
            monthB = $(b).children("span").text().split(" ")[1];
        return monthA < monthB;
    }).appendTo($(this));
});

// Grouping the <li> by month inside each grouping <li>
$("#mainList li.year ul").each(function() {
    $this = $(this);
    $this.children("li").each(function() {
        var month = $(this).children("span").text().split(" ")[1];
        // If the grouping <li> doesn't exist, create it
        if ($this.find("li.month." + month).length === 0) {
            $this.append($('<li class="month ' + month + '">' + months[month-1] + '<ul></ul></li>'));
        }
        // Add the current <li> to the corresponding grouping <li>
        $(this).appendTo($this.find("li.month." + month + " ul")).addClass("item");
    });
});
like image 163
Sylvain Avatar answered Mar 22 '26 06:03

Sylvain



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!