2011 05 01

Text...

  • Group list items using jQuery

    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 elements by year and month, for example:

    <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>
    

    Thank.

    +3
    source share
    2 answers

    I wrote a commented solution here (jsFiddle) and here (jsBin) .

    (two links have the same content, but jsFiddle is sometimes quite slow, so you might want to switch to jsBin)

    I hope you will 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");
        });
    });
    
    +9
    source

    Here is an example of alphabetical sorting . I think this will be a good place to start. Hope this helps!

    +2
    source

    All Articles