TinySort is a small and simple jQuery plugin that will sort any nodetype by it's text- or attribute value, or by that of one of it's children.
The examples below should help getting you on your way.

For those interested: there is a unit/regression test here.

If you find a bug, have a feature request or a code improvement you can file them here. Please provide code examples where applicable.


usage

The first argument in the tsort function can either be nothing...

$('li').tsort();
$('ul#people>li').tsort();

a string (as you would in find)...

$('ul#people>li').tsort('span.surname');

a 'settings' object...

$('ul#people>li').tsort({place:'end'});

both...

$('ul#people>li').tsort('img',{order:'desc',attr:'alt'});

or more if you want multiple sort criteria...

$('ul#people>li').tsort('span.surname',{order:'desc'},'span.name',{order:'desc'});

Change default settings globally like so:

$.tinysort.defaults.order = 'desc';
	$.tinysort.defaults.attr = 'title';

TinySort has a number of settings:

propertytypedescriptionpossible valuesdefault
order String the order of the sorting method
ascascending order
descdescending order
randrandom order
"asc"
attr String order by attribute value (ie title, href, class) anything ""
useVal Boolean use element value instead of text
falseuse text
trueuse value
false
data String use the data attribute for sorting
nulluse text
Stringuse data attribute
null
charOrder String use the data attribute for sorting
nulluse text
Stringuse data attribute
null
place String determines the placement of the ordered elements in respect to the unordered elements filtered out by using the 'attr' setting or the first parsed 'find' string
startsorted elements are prepended at the parent attribute
endsorted elements are appended at the parent attribute
orgplacement occurs at the positions the sortable elements are found
firstelements are appended after the first occurance of a sortable element
"start"
returns Boolean affects the returned jquery array
falseall elements are returned
trueonly sorted elements are returned
false
cases Boolean a case sensitive sort (orders [aB,aa,ab,bb])
falsecases are ignored
truecase sensitive sort
false
ignoreDashes Boolean ignore dashes when matching numerals to prevent negative numbers
falsedashes are ignored
truedashes are matched
false
forceStrings Boolean use string value for numerals
falsenumbers sorted by numeric value
trueeverything sorted as string
false
sortFunction function override the default sort function any sort function like function(a,b){return -1,0,1;} where the two parameters are objects with the following properties:
ejQuery object
noriginal order
sstring to sort
...

examples

default sorting

The default sort is done by simply calling the 'tsort' function onto your selection.

$('ul#xdflt>li').tsort();

sort on any node

TinySort works on any nodeType. The following is a div with spans.

$('div#xany>span').tsort('',{order:'desc'});

sorted numbers

TinySort also works on numbers.

$('ul#xnum>li').tsort();

mixed literal and numeral

In a normal sort the order would be a1,a11,a2 while you'd really want it to be a1,a2,a11. TinySort corrects this:

$('ul#xmix>li').tsort();

sorted by attribute value

Sort by attribute value by parsing the additional parameter 'attr=attributeName'. This will sort by attribute of, either the jquery selection, or of the sub-selection (if provided). In this case sort is by href on the anchor sub-selection.

$('ul#xval>li').tsort('a',{attr:'href'});

Another example: images sorted by attribute title value.

$('span#ximg>img').tsort({attr:'title'});

sorted by sub-selection

You can provide an additional subselection by parsing a jquery sub-selection string into the tsort function. The returned array will be in the newly sorted order.
In this example the list elements are sorted to the text of the second span.

$('ul#xsub>li').tsort('span:eq(1)');

The following example will only sort the non-striked elements.

$('ul#xattr>li').tsort('span[class!=striked]');

return only sorted elements

By default, all the elements are returned, even the ones excluded by your sub-selection. By parsing the additional parameter 'returns=true' only the sorted elements are returned.
You can also adjust the placement of the sorted values by adding the 'place' attribute. In this case the original positions are maintained.

$('ul#xret>li').tsort('span[class!=striked]',{returns:true,place:'org'}).css({color:'red'});

multiple sort criteria

Sometimes multiple sorting criteria are required. For instance: you might want to sort a list of people first by surname then by name.

For multiple sorting rules you can just append the parameters. So tsort(selector,object) becomes tsort(selector1,object1,selector2,object2,selector3,object3...). You can also leave out either the selector or the object if it's not needed: tsort(selector1,selector2,object2,object3...). Keep in mind that tsort will look for selector-object pairs and if no applicable pair is formed it will use default values. In this example three arguments are two criteria: the first argument uses the default options object, the second argument uses the third argument as options object.

$('ul#xmul>li').tsort('span.name','span.date',{data:'timestamp'});

non-latin characters

A normal array sorts according to Unicode, which is wrong for most languages. For correct ordering you can use the charorder plugin to parse a rule with the 'charOrder' parameter. This is a string that consist of exceptions, not the entire alfabet. For characters that should sort equally use brackets. For characters that consist of multiple characters use curly braces. For example:

Here some real examples:

$('ul#greek>li').tsort({charOrder:'α[ά]βγδε[έ]ζη[ή]θι[ίϊΐ]κλμνξο[ό]πρστυ[ύϋΰ]φχψω[ώ]'});
$('ul#danish>li').tsort({charOrder:'æøå[{Aa}]'});
$('ul#serb>li').tsort({charOrder:'cčćd{dž}đl{lj}n{nj}sšzž'});

Here are some example languages:

Language charOrder
since only one of these is my native language please feel free to contact me if you think corrections are in order
Cyrilicабвгдђежзијклљмнњопрстћуфхцчџш
Czecha[á]cčd[ď]e[éě]h{ch}i[í]n[ň]o[ó]rřsšt[ť]u[úů]y[ý]zž
Danish and Norwegianæøå[{Aa}]
Dutcha[áàâä]c[ç]e[éèêë]i[íìîï]o[óòôö]u[úùûü]
Frencha[àâ]c[ç]e[éèêë]i[ïî]o[ôœ]u[ûù]
Germana[ä]o[ö]s{ss}u[ü]
Greekα[ά]βγδε[έ]ζη[ή]θι[ίϊΐ]κλμνξο[ό]πρστυ[ύϋΰ]φχψω[ώ]
Icelandica[á]dðe[é]i[í]o[ó]u[ú]y[ý]zþæö
Polishaąbcćeęlłnńoósśuúzźż
Serbo-Croatiancčćd{dž}đl{lj}n{nj}sšzž
Spanisha[á]c{ch}e[é]i[í]l{ll}nño[ó]u[ú]y[ý]
Swedishåäö

sort $.val()

The .val() method is primarily used to get the values of form elements. By parsing the useVal attribute you can also sort by this form element value. Everything is in the first line, I added some extra code to show the values it sorts on.

$('ul#xinp>li').tsort('>input,>select',{useVal:true}).each(function(i,el){
var $Li = $(el);
$Li.find('span').text(' : '+$Li.find('>input,>select').filter(':eq(0)').val());
});

sort $.data()

Sort by data attribute by parsing the additional parameter 'data=dataName'.

$('ul#xdta>li').tsort('a',{data:'foo'});

sorted descending

Sort by ascending or descending order by parsing the additional 'order="desc"/"asc"' parameter.

$('ul#xdesc>li').tsort('',{order:'desc'});

randomize

TinySort can also order randomly (or is that a contradiction).

$('ul#xrnd li').tsort({order:'rand'});

parsing a custom sort function

Custom sort functions are similar to those you use with regular Javascript arrays with the exception that the parameters a and b are objects of a similar type. These objects contains three variables: a variable 'e' containing the jQuery object of the element passing through the sort, an integer 'n' containing the original order of the element, and a string 's' containing the string value we want to sort. The latter is not necessarily the text value of the node, should you parse the 'attr' property then 's' will contain the value of that property.

$('ul#xcst li').tsort('',{sortFunction:function(a,b){
var iCalcA = parseInt(a.s)%16;
var iCalcB = parseInt(b.s)%16;
return iCalcA===iCalcB?0:(iCalcA>iCalcB?1:-1);
}});

sorting tables

With a little extra code you can create a sortable table. The anchors in this table header call the function sortTable which basicly does this:

var aAsc = [];
function sortTable(e) {
var nr = $(e.currentTarget).index();
aAsc[nr] = aAsc[nr]=='asc'?'desc':'asc';
$('#xtable>tbody>tr').tsort('td:eq('+nr+')[abbr]',{order:aAsc[nr]});
}
$('#xtable').find('thead th:last').siblings().on('click',sortTable);
				

Note that the mixed column only sorts those rows of which the td's have the abbr attribute set, and because of the default place value the non-sorted elements always remain at the bottom

word int float mixed mixed add row

animated sorting

Tinysort has no built in animating features but it can quite easily be accomplished through regular js/jQuery.

var $Ul = $('ul#xanim');
$Ul.css({position:'relative',height:$Ul.height(),display:'block'});
var iLnH;
var $Li = $('ul#xanim>li');
$Li.each(function(i,el){
	var iY = $(el).position().top;
	$.data(el,'h',iY);
	if (i===1) iLnH = iY;
});
$Li.tsort().each(function(i,el){
	var $El = $(el);
	var iFr = $.data(el,'h');
	var iTo = i*iLnH;
	$El.css({position:'absolute',top:iFr}).animate({top:iTo},500);
});