Maybe you've seen sortable tables before but it has probably been done using databinding in IE4. Now it can be done using DOM level 1 (level 2 isn't finished yet) so it will work in both Internet Explorer 5 and Netscape Navigator 5 (NGLayout, Gecko). The actual sorting algorithm is the standard sort method of the javascript Array object so it is guarantied to be as fast as possible. Read how this was made below or just see the demo or find out how you can use it yourself

The sort method

The built in Array object in javascript provides a sort method. This can either be used whithout an argument or with an argument. The argument is a function that is used for the comparison between two objects in the array. In my case this is really important because the greater than (>) operator is not defined for html element nodes so I made a function that compared the inner text of two nodes.

Higher order functions

Higher order functions are functions that takes functions as arguments or returns a function. Since javascript is object oriented everything is objects, even functions, so you can easily pass functions as arguments. To pass a function as argument you just use the name (without the parenthesis) or create a new function object using the function constructor. Like this:

var myFunction = new Function("x","return x*x);");

function anotherFunction(x) {
	return x+x;
}

var mySecondFunction = anotherFunction;

Now you can pass these functions as argument to a function that takes three functions as argument and it looks like this:

function strangeFunction(f1, f2, f3) {
	function f(x) {
		return f1(f2(f3(x)));
	}
	return f;
}

strangeFunction(myFunction, anotherFunction, mySecondFunction)(5);
// gives 400

Compare function

Now that you know all about higher order functions I'll show you how I defined my compare function. The argument to sort is as I said a function that decides the order between two elements but I wanted to sort by column and also in ascending descending order. For this I made a function that took three arguments, the column number, a boolean for the sort order and an optional string representing the type to use when sorting. This function returns another function that is then used for the comparison.

function compareByColumn(nCol, bDescending, sType) {
   var c = nCol;
   var d = bDescending;
   
   var fTypeCast = String;
   
   if (sType == "Number")
      fTypeCast = Number;
   else if (sType == "Date")
      fTypeCast = parseDate;
   else if (sType == "CaseInsensitiveString")
      fTypeCast = CaseInsensitiveString;

   return function (n1, n2) {
      if (fTypeCast(getInnerText(n1.cells[c])) < fTypeCast(getInnerText(n2.cells[c])))
         return (d) ? -1 : +1;
      if (fTypeCast(getInnerText(n1.cells[c])) > fTypeCast(getInnerText(n2.cells[c])))
         return (d) ? +1 : -1;
      return 0;
   };
}

// And the calling looks like this
array.sort(compareByColumn(2, true, "Number")

The currently supported types are:

String Default. Compare the string values as it is.
CaseInsensitiveString Compare the string values but 'a' and 'A' are treated equally.
Number Casts the text to a number before doing the comparison
Date Casts the text to a date before doing the comparison. Warning! The JS Date object does not handle strings representing dates correctly. I guess an american designed the Date class :-( If you get into trouble with dates try creating your own parseDate function and replace the current one.

Next step

Now we need to get the contents of the table into an array that can be sorted an then we need to insert the content into the table again.




Defining the sort
Manipulating the DOM tree
Demo and instructions how to use it in your pages
Sorting with behaviors

Author: Erik Arvidsson