Skip to content

Instantly share code, notes, and snippets.

@StanBoyet
Created November 18, 2014 18:37
Show Gist options
  • Save StanBoyet/aa6396b69a8ac3d8f12e to your computer and use it in GitHub Desktop.
Save StanBoyet/aa6396b69a8ac3d8f12e to your computer and use it in GitHub Desktop.
Sort elements with jQuery

from http://trentrichardson.com/2013/12/16/sort-dom-elements-jquery/

I wanted to share a quick snippet that I worked up for a unique scenario. Occasionally you want to sort or display DOM elements in a certain order. For instance, what if you have a list of names. A feature of your site may be that you can sort the list by first name, or last name. There are a few ways you can approach this.

One approach may be using a javascript framework like Backbone or Angular, where you have a model and collection. Then simply sort the collection, magic happens, and your list is essentially regenerated.

The other could be that you’re not using a framework and not want to regenerate the entire list, but to move the nodes. It is actually rather simple. Lets say you have a list like the following:

<ul class="js-people">
	<li data-name="John Doe">Mr. John Doe</li>
	<li data-name="Trent Richardson">Mr. Trent Richardson</li>
	<li data-name="Cindy Smith">Ms. Cindy Smith</li>
	<li data-name="Bill Williams">Mr. Bill Williams</li>
	<li data-name="Jane Doe">Mrs. Jane Doe</li>
</ul>

You will notice each

  • has a data-name attribute. This is one trick I have picked up over time. This will hold the raw string to compare for the sort (notice the actual text contains Mr., Mrs., etc. which may interfere with the sort). At this point it won’t matter what markup or text is inside the element, the data-name is all we are concerned about.

    Now, how complex is it to sort the elements with jQuery? Not so difficult if you think about it. jQuery stores selected elements as an array, and guess which function is available on array instances in javascript? Sort! Lets see how this might look.

     
    var $people = $('ul.js-people'),
    	$peopleli = $people.children('li');
     
    $peopleli.sort(function(a,b){
    	var an = a.getAttribute('data-name'),
    		bn = b.getAttribute('data-name');
     
    	if(an > bn) {
    		return 1;
    	}
    	if(an < bn) {
    		return -1;
    	}
    	return 0;
    });
     
    $peopleli.detach().appendTo($people);
     

    So when using the sort we will pass a sort function to pick out our data-name attributes for comparison. Then it is a simple comparison to determine which is greater. Now the collection of elements in the jQuery object is sorted, now we just need to re-inject them into the DOM.

    To do this we detach and re-append the elements in the new order. jQuery makes this part very simple.

    There is a little to take away here aside from the example. Ever used tablesorter? Depending on your data it can be a real pain to get the sorter to detect and pick out the text to sort the column by. Fortunately they do provide an option to pass function for textExtraction. What if you populate a data-sort attribute (or whatever you want to name it) with your raw sortable data when you generate the html?

    So if your <td> has a complex date stored in it simply use:

    <td data-sort="1387146049476">December the 15th, 2013</td> Then use the textExtraction option like so:

    $('table').tablesorter({
    	textExtraction: function(node){
    		var d = node.getAttribute('data-sort');
    		if(d !== null){
    			text = d;
    		}
    		else {
    			text = node.innerHTML;
    		}
    		return text;
    	}
    });

    I’ve used getAttribute a couple times the in the examples, simply because it will likely be faster on larger scale than using jQuery’s .data(), and isn’t exactly difficult. That’s all, have fun!

  • Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment