1

I need to sort a multilevel html list alphabetically. What I have:

<ul>

<li>
   <a href="#">B Link</a>
   <ul class="sub-cat-list">
      <li>
         <a href="#">X sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">A Sub sub link</a></li>
            <li><a href="#">C sub sub link</a></li>
            <li><a href="#">D sub sub link</a></li>
            <li><a href="#">X sub sub link</a></li>
         </ul>
      </li>
   </ul>
</li>

<li>
   <a href="#">A Link</a>
   <ul class="sub-cat-list">
      <li>
         <a href="#">H sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">X Sub sub link</a></li>
            <li><a href="#">D sub sub link</a></li>
            <li><a href="#">F sub sub link</a></li>
            <li><a href="#">Z sub sub link</a></li>
         </ul>
      </li>
      <li>
         <a href="#">B sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">V Sub sub link</a></li>
            <li><a href="#">J sub sub link</a></li>
            <li><a href="#">O sub sub link</a></li>
            <li><a href="#">U sub sub link</a></li>
         </ul>
      </li>
   </ul>
</li>

<li>
   <a href="#">X Link</a>
   <ul class="sub-cat-list">
      <li>
         <a href="#">C sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">L Sub sub link</a></li>
            <li><a href="#">O sub sub link</a></li>
            <li><a href="#">Y sub sub link</a></li>
            <li><a href="#">Y sub sub link</a></li>
         </ul>
      </li>
      <li>
         <a href="#">A sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">G Sub sub link</a></li>
            <li><a href="#">T sub sub link</a></li>
            <li><a href="#">R sub sub link</a></li>
            <li><a href="#">A sub sub link</a></li>
         </ul>
      </li>
   </ul>
</li>

</ul>

Every link and every block list should be sorted. So what I need:

<ul>

<li>
   <a href="#">A Link</a>
   <ul class="sub-cat-list">
      <li>
         <a href="#">B sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">J sub sub link</a></li>
            <li><a href="#">O sub sub link</a></li>
            <li><a href="#">U sub sub link</a></li>
            <li><a href="#">V Sub sub link</a></li>
         </ul>
      </li>
      <li>
         <a href="#">H sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">D sub sub link</a></li>
            <li><a href="#">F sub sub link</a></li>
            <li><a href="#">X Sub sub link</a></li>
            <li><a href="#">Z sub sub link</a></li>
         </ul>
      </li>

   </ul>
</li>

<li>
   <a href="#">B Link</a>
   <ul class="sub-cat-list">
      <li>
         <a href="#">X sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">A Sub sub link</a></li>
            <li><a href="#">C sub sub link</a></li>
            <li><a href="#">D sub sub link</a></li>
            <li><a href="#">X sub sub link</a></li>
         </ul>
      </li>
   </ul>
</li>


<li>
   <a href="#">X Link</a>
   <ul class="sub-cat-list">
      <li>
         <a href="#">A sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">A sub sub link</a></li>
            <li><a href="#">G Sub sub link</a></li>
            <li><a href="#">R sub sub link</a></li>
            <li><a href="#">T sub sub link</a></li>
         </ul>
      </li>

      <li>
         <a href="#">C sub link </a>
         <ul class="sub-cat-list">
            <li><a href="#">L Sub sub link</a></li>
            <li><a href="#">O sub sub link</a></li>
            <li><a href="#">Y sub sub link</a></li>
            <li><a href="#">Y sub sub link</a></li>
         </ul>
      </li>

   </ul>
</li>

</ul>

There's a code for sorting:

$.fn.sortList = function() {
    var mylist = $(this);
    var listitems = $('li', mylist).get();
    listitems.sort(function(a, b) {
        var compA = $(a).text().toUpperCase();
        var compB = $(b).text().toUpperCase();
        return (compA < compB) ? -1 : 1;
    });
    $.each(listitems, function(i, itm) {
        mylist.append(itm);
    });
}

I try to use it with this way:

$("ul.sub-cat-list >li >ul").each(function(){
    $(this).sortList();
})

But the problem is it applies to the second .sub-cat-list class only and I can't understand what selector I should use for the whole menu to get the result I need.

JSFiddle

Hope for your help. Thanks.

lloydbanks
  • 63
  • 7

2 Answers2

0

Based on @NagarajS suggestion (order ul in jquery), I made some changes for your case.

Try this:

$('.menu ul').each(function () {
    var ul = $(this);
    var items = $(this).children().get();
    items.sort(function (a, b) {
        var keyA = $(a).text();
        var keyB = $(b).text();

        if (keyA < keyB) return -1;
        if (keyA > keyB) return 1;
        return 0;
    });
    $.each(items, function (i, li) {
        ul.append(li);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="menu">
    <ul>
        <li> <a href="#">B Link</a>

            <ul class="sub-cat-list">
                <li> <a href="#">X sub link </a>

                    <ul class="sub-cat-list">
                        <li><a href="#">A Sub sub link</a>

                        </li>
                        <li><a href="#">C sub sub link</a>

                        </li>
                        <li><a href="#">D sub sub link</a>

                        </li>
                        <li><a href="#">X sub sub link</a>

                        </li>
                    </ul>
                </li>
            </ul>
        </li>
        <li> <a href="#">A Link</a>

            <ul class="sub-cat-list">
                <li> <a href="#">H sub link </a>

                    <ul class="sub-cat-list">
                        <li><a href="#">X Sub sub link</a>

                        </li>
                        <li><a href="#">D sub sub link</a>

                        </li>
                        <li><a href="#">F sub sub link</a>

                        </li>
                        <li><a href="#">Z sub sub link</a>

                        </li>
                    </ul>
                </li>
                <li> <a href="#">B sub link </a>

                    <ul class="sub-cat-list">
                        <li><a href="#">V Sub sub link</a>

                        </li>
                        <li><a href="#">J sub sub link</a>

                        </li>
                        <li><a href="#">O sub sub link</a>

                        </li>
                        <li><a href="#">U sub sub link</a>

                        </li>
                    </ul>
                </li>
            </ul>
        </li>
        <li> <a href="#">X Link</a>

            <ul class="sub-cat-list">
                <li> <a href="#">C sub link </a>

                    <ul class="sub-cat-list">
                        <li><a href="#">L Sub sub link</a>

                        </li>
                        <li><a href="#">O sub sub link</a>

                        </li>
                        <li><a href="#">Y sub sub link</a>

                        </li>
                        <li><a href="#">Y sub sub link</a>

                        </li>
                    </ul>
                </li>
                <li> <a href="#">A sub link </a>

                    <ul class="sub-cat-list">
                        <li><a href="#">G Sub sub link</a>

                        </li>
                        <li><a href="#">T sub sub link</a>

                        </li>
                        <li><a href="#">R sub sub link</a>

                        </li>
                        <li><a href="#">A sub sub link</a>

                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</div>

Every single ul inside the .menu div will be sorted, starting from the top level to the lowest level.

Community
  • 1
  • 1
Joel Almeida
  • 7,939
  • 5
  • 25
  • 51
0

If you change var listitems = $('li', mylist).get(); to var listitems = $('> li', mylist).get(); in your sortList function it will only look at the <li> tags for the current list.

Then you can sort all the lists by calling

$("ul").each(function(){
    $(this).sortList();
})

JSFiddle

Martin
  • 2,411
  • 11
  • 28
  • 30