Tag / JavaScript

I was adding reports to an application and wanted a quick way of sorting the data based on multiple columns, without having to write lots of backend code to do so. Using a JavaScript solution also meant that the re-ordering would be more responsive, provided the dataset wasn’t too big. I found tablesorter, which is a nice jQuery plugin written to do exactly what I wanted. Although it doesn’t seem to be under development any more (the last release was sometime in 2008), it seems to be stable and quite powerful.

To get going, all you need to do is surround your table headers with a thead element, and the data you want to sort with tbody, and you’re good to go.
The sorting that comes out of the box is immediately useful, with many data types automatically picked up (e.g. dates, decimals, percentages, IP addresses) and sorted correctly, ascending and descending, with a clean user interface to match. You can also sort on multiple columns, and specify defaults when the page is loaded.

When you want to get more customised, that’s easy too. CSS classes for the interface can be easily changed. If you want to add a custom sorter (e.g. it doesn’t parse prettified numeric values automatically, such as -3,405.02, so I wrote a custom parser for these), they are simple to write:

$.tablesorter.addParser({
id: 'value', // unique name for the parser
is: function(s) {
/* a function to determine based on cell values whether a parser can be used
* e.g. return !isNaN(parseFloat(s));
* return false to only use the parser when explicitly specified */
return false;
},
format: function(s) {
// function to parse a value from the data
return parseFloat(s.replace(/[^\d.-]/, ""));
},
type: 'numeric' // set type, either numeric or text
});

To use your custom parser, you can specify which columns to use it for when initialising tablesorter:

This would use the “value” parser for sorting values in the fourth column (columns are of course zero-indexed). However, this is a bit clumsy, especially if your columns might shift position (as was my case). Far better I found was to use the jQuery metadata plugin, which allows you to configure tablesorter using inline code, e.g.

So no matter how your markup changes, your sorting won’t break. 🙂 There’s also functionality for paging and other AJAX enhancements, and custom widgets, but I didn’t look at those. All in all it seems an excellent tool, and certainly worked very well in my application.

One thing to note is that the dates are automatically parsed as being in US format; you can change this in the defaults when initialising tablesorter (or just edit the base code as I did): the option is called dateFormat and should be set to “uk” for UK-formatted dates:

An important part of any web project is to minimise your JavaScript, reducing loading times from downloading the scripts to the browser. We were using Packer for .NET, which supports modes for packing (compressing the JavaScript into a packed function, which then needs to be run on the client to decompress the JavaScript), and minimisation (where comments, whitespace, unrequired/unreachable code is stripped out, leaving only necessary characters). However, it has the annoying habit of prepending a comment to every processed JS file telling us that this magic was performed by Packer for .NET, which is perhaps forgiveable, but also includes a comment with the path to the original source file, which seems crazy and in our case was exposing internal server names. As well as being irritating this also added unnecessary content to the JS files, which the whole process of minimisation was trying to avoid! I searched and couldn’t find any command line options to turn this off, so I looked for alternatives, and found the Microsoft AJAX Minifier, which is easy to use and performs good quality minimisation without any such annoying comments.

On a side note, I prefer minimisation since packing requires additional processing at the client side which can slow the page load, especially for browsers with poorer JS performance. For minimisation to be most effective, it’s best to first pass the JS code through a verifier such as JavaScript Lint, a good idea anyway for good quality JS code.