Sorting Elements with jQuery

Whilst refactoring a jQuery plugin today, I came across a method that placed a list item into an unordered list at a specific point, so that all the items remained in alphabetic order. This long method seemed completely convoluted and slow to me and I decided that there must be an easier way to keep the list in alphabetical order.

There are existing plugins for sorting elements but I never like to just pile on the 3rd party plugins as that means more javascript files to include in a page. Besides, I was sure it should not be difficult.

It soon occured to me that jQuery has the built-in ability to return the elements as an array, using the .get() method and from there, it was not too long before I had my streamlined code to sort the list element alphabetically:

var mylist = $('ul');
var listitems = mylist.children('li').get();
listitems.sort(function(a, b) {
   var compA = $(a).text().toUpperCase();
   var compB = $(b).text().toUpperCase();
   return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
})
$.each(listitems, function(idx, itm) { mylist.append(itm); });

I utilise the javascript array.sort method to sort the elements in the array and then using the jQuery append() method,  reorder them in the actual list element.

20 Responses to “Sorting Elements with jQuery”

  1. tim  on March 19th, 2009

    These orders alphabetically nicely, but what would i need to do to make it sort by say class or attribute etc instead of alphabetically..

  2. admin  on March 19th, 2009

    The array.sort function allows you to sort by anything. In my example I am retrieving the text of the element with $(a).text() but I could easily retrieve an attribute and compare that instead $(a).attr(‘id’) etc.

  3. William Fisk  on April 10th, 2009

    Thanks, worked perfectly. Its seemingly quite simple but I couldn’t work out myself how to do it.

  4. javigoile  on June 17th, 2009

    Quick question: I tried your script and it works fine the first time, but if I run it twice (I have a link that orders by price and other by category), don’t know why but it duplicates the result!

    What can I do to avoid this?

    Thanks a lot!

  5. javigoile  on June 18th, 2009

    Ups, my bad! I was having a problem with the selector, that was all, script works like a charm!

    Thank you!

  6. dan  on June 18th, 2009

    @javigoile I am glad to hear you sorted the problem.

  7. Fatih YASAR  on August 11th, 2009

    Hey Dan,
    It’s working perfectly, thank for this post.

  8. Bhat  on September 11th, 2009

    Fabulous…Thanks….

  9. Rich Staats  on November 18th, 2009

    Hey Dan, Thank you so much for this, you made it look so easy. I am trying to take this one step further, if possible. I have a list of names (first name and last name) and would like to have this function sort by last name, without forcing the list to be echoed: {lastname}, {firstname}. ie, Staats, Rich. It would be nice to echo: Rich Staats yet sort by “Staats” instead of “Rich.”

    I attempted my own solution based on the attr comment above. I added a span class to each of the list items and gave it a class of “abc”. I then attempted to sort like so:

    var compA = $(a).attr(’span.abc’).toUpperCase();
    var compB = $(b).attr(’span.abc’).toUpperCase();

    That however did not work. Can you possibly point me in the right direction?

    Rich

  10. Rich Staats  on November 18th, 2009

    im sorry i had a typo:

    I added a span class to each of the list items and gave it a class of “abc”

    should read:

    I added a span class to each of the last names within the list items and gave it a class of “abc”

    thanks!

  11. beekermd03  on November 19th, 2009

    This is money, thanks!

  12. dan  on November 19th, 2009

    @Richstaats You were nearly there. It should be something like:

    var compA = $(a).find(’span.abc’).text().toUpperCase();
    var compB = $(b).find(’span.abc’).text().toUpperCase();

    the compA and compB is the text you are comparing, so with the above statement I am retrieving the text within the span tag.

    Hope that helps,
    Dan

  13. total13  on November 20th, 2009

    Thank you for your code, it helps me a lot! It’s important to note that the sort method in jquery opbjects only works in version 1.3.2, (and above when released i suppose). I was developing in 1.3.1 and gets an error.

    Thanks again and sorry if english is not good!

  14. total13  on November 20th, 2009

    ups! I realized just now that i did it’s not the same as you proposse (i’ve just copied the return line). Now in jquery 1.3.2 is posible do something like this:

    var listitems = $(‘ul li’);
    listitems.sort(function(a, b) {
    var compA = $(a).text().toUpperCase();
    var compB = $(b).text().toUpperCase();
    return (compA compB) ? 1 : 0;
    })

  15. mark  on December 3rd, 2009

    Anyway you can make it work with decimal numbers?

  16. dan  on December 4th, 2009

    @mark Yes, the array.sort function allows you to sort by anything, just use jQuery to select the information you want to sort by, then compare and return -1 when “a” is to be a lower index than “b”, 0 when they are the same and 1 when “b” is to be a lower index than “a”. For more information, google for ‘javascript array sort’.

  17. kshitiz  on December 18th, 2009

    Hi, I have used your script to make a travel website. but, while doing the sorting of hotel by name system slows down. Script works fine with 20 – 80 hotels. But when list is bigger than 300 hotel it hangs the PC.

    I am using your script to sort divs.

    here is the code

    please help me to speed this up.

    var mylist = $(‘#hiddenresult’);
    var listitems = mylist.children(‘div.result’).get();
    listitems.sort(function(a, b) {
    var compA = $(a).find(“#h_hotelnameandprice”).text().toUpperCase();
    var compB = $(b).find(“#h_hotelnameandprice”).text().toUpperCase();
    return (compA compB) ? 1 : 0;
    })
    $.each(listitems, function(idx, itm) {
    mylist.append(itm);
    });

  18. dan  on December 21st, 2009

    @kshitiz I am not sure there is much that can speed things up when you are dealing with large quantities of elements like that. You best approach would be to re-think the page so that you are not displaying so many results or to do the sorting on the server rather than client.

  19. taktu  on December 29th, 2009

    There is a way to speed it up, by reducing amount of append calls to just one at the very end of the sorting process.

    btw. if anyone would like to get desc sorting just change return line as below:
    return (compA > compB) ? -1 : (compA < compB) ? 1 : 0;

    Great script Dan!

  20. aja328  on January 27th, 2010

    This was awesome!


Leave a Reply