While the web design community gradually moves away from using tables to lay out the structure of a page, tables really do have a vital use, their original use; they're for laying out tabular data. For instance, imagine a table of employees.
Name | Salary | Extension | Start date | Start date (American) |
---|---|---|---|---|
Bloggs, Fred | $12000.00 | 1353 | 18/08/2003 | 08/18/2003 |
Turvey, Kevin | $191200.00 | 2342 | 02/05/1979 | 05/02/1979 |
Mbogo, Arnold | $32010.12 | 2755 | 09/08/1998 | 08/09/1998 |
Shakespeare, Bill | $122000.00 | 3211 | 12/11/1961 | 11/12/1961 |
Shakespeare, Hamnet | $9000 | 9005 | 01/01/2002 | 01/01/2002 |
Fitz, Marvin | $3300 | 5554 | 22/05/1995 | 05/22/1995 |
Pretty simple. But if you saw that table in a client-side
application, you'd expect to be able to click on the headers and have
the table sort, would you not? I know it always annoys me when you
can't. A fair few web applications do allow this; most of them, which
are pulling this data by submitting a SQL query to a relational
database (an environment eminently suited to tabular data) implement
this by resubmitting the whole page with something like
ordercolumn=4
in the URL, and then adding an ORDER
BY
clause to their SQL query to return the data from the DB
ordered by the specified column.
Resubmit the page? Just to sort data we already have? I'm sure we can do better than that.
Name | Salary | Extension | Start date | Start date (American) |
---|---|---|---|---|
Bloggs, Fred | $12000.00 | 1353 | 18/08/2003 | 08/18/2003 |
Turvey, Kevin | $191200.00 | 2342 | 02/05/1979 | 05/02/1979 |
Mbogo, Arnold | $32010.12 | 2755 | 09/08/1998 | 08/09/1998 |
Shakespeare, Bill | $122000.00 | 3211 | 12/11/1961 | 11/12/1961 |
Shakespeare, Hamnet | $9000 | 9005 | 01/01/2002 | 01/01/2002 |
Fitz, Marvin | $3300 | 5554 | 22/05/1995 | 05/22/1995 |
As you can see, the above table now has clickable headers that sort the table by the clicked column. Note how the numeric and date columns all sort properly, too, rather than sorting alphanumerically.
This is not a new trick, sorting a table using the DOM. However, this mini-library has two nice attributes; the first is, unsurprisingly, that it follows my principles of unobtrusive DHTML, as you'll see below. The second is that, as mentioned above, it knows how to sort a variety of different data types, and it works them out for itself -- you don't have to tell it.
Now, how to use it. To make a table of your choice sortable, there are three steps:
<script src="sorttable.js"></script>
<table class="sortable">
Note that the library's JavaScript file is called
sorttable
(two Ts), but the class you add to the table is
sortable
(one T).And that's all you need. Your table will now have column sorting available by clicking the headers. For niceness, you might want to add the following styles to your stylesheet, or make up some of your own based on this:
/* Sortable tables */
table.sortable thead {
background-color:#eee;
color:#666666;
font-weight: bold;
cursor: default;
}
This is version 2 of sorttable, released April 2007. If you're using the old version, you may find it useful to update; v2 has numerous new features and should be completely backwards compatible.
You probably don't need the bits here. Sorttable is designed to require no configuration, no fiddling around. Just take it and use it. If you need it to do more than it does by default, then come back here and read this part.
If you have a "totals" row at the bottom of your table that you want to
stay at the bottom of your table (and not get sorted), then add it
to a <tfoot>
section in your table (which is what you
should be doing anyway, according to the HTML spec). So, your table should
look like this:
<table class="sortable">
<thead>
<tr><th>Person</th><th>Monthly pay</th></tr>
</thead>
<tbody>
<tr><td>Jan Molby</td><td>£12,000</td></tr>
<tr><td>Steve Nicol</td><td>£8,500</td></tr>
<tr><td>Steve McMahon</td><td>£9,200</td></tr>
<tr><td>John Barnes</td><td>£15,300</td></tr>
</tbody>
<tfoot>
<tr><td>TOTAL</td><td>£45,000</td></tr>
</tfoot>
</table>
Note how sorting the table leaves the TOTAL row at the bottom.
Person | Monthly pay |
---|---|
Jan Molby | £12,000 |
Steve Nicol | £8,500 |
Steve McMahon | £9,200 |
John Barnes | £15,300 |
TOTAL | £45,000 |
You may have some data which does go in an order but isn't identified
by sorttable. The way to fix this problem is to use custom sort
keys. Take, for example, a column of spelled out numbers. Ordinarily,
sorttable wouldn't work here; it will treat the spelled-out numbers as
strings, and so would sort the numbers in alphabetical order, i.e., five,
four, one, three, two. To get around this, you can specify on a cell in your
table a sorttable_customkey
attribute, and sorttable will use
the contents of that attribute instead of the text in the cell itself when
sorting the table. So, for example, your table might look like this:
<table class="sortable">
<tr><th>Number (spelled)</th><th>Person</th></tr>
<tr><td sorttable_customkey="2">two</td><td>Jan</td></tr>
<tr><td sorttable_customkey="3">three</td><td>Bruce</td></tr>
<tr><td sorttable_customkey="1">one</td><td>Steve</td></tr>
</table>
Note that clicking on the "Number (spelled)" column in the table below sorts it in the correct one,two,three order.
Number (spelled) | Person |
---|---|
two | Jan |
three | Bruce |
one | Steve |
You can fix practically any problem you have with sorttable's automatic column typing by specifying custom sort keys.
Sorttable works out the type of your columns in order to work out how to
sort them (numbers sort differently than letters, for example). Occasionally,
it might get it wrong. If so, you can explicitly specify a type for a column,
which will override sorttable's assessment. To specify a type, add a class
of sorttable_columntype
to the header row
of that column. Available column types are numeric
,
alpha
, ddmm
, and mmdd
. The latter two
are for dates, but are not likely to be useful because if sorttable fails to
automatically identify a date then the sort won't work anyway.
So, for example, if you have a "part number" column which you want to be treated as if it were numeric, then you might do your table like this:
<table class="sortable">
<tr>
<th class="sorttable_numeric">Part number</th><th>Part name</th>
</tr>
<tr>
<td>111-A5</td><td>Three-eighths Gripley</td>
</tr>
<tr>
<td>31337-H4X0R</td><td>Computer system intrusion toolkit</td>
</tr>
</table>
Remember: you probably do not need to do this. It is unlikely that you'll need to "force" sorttable to recognise a column type. You may also want to investigate using custom sortkeys, above, as a better way of achieving your goals.
One common question with sorttable is how to make it handle custom date formats. Sorttable will have a try at understanding dates in whatever format you add them in, but it sometimes needs help. The way to do this is with custom sort keys, as mentioned above. If you have table cells like this:
<td>February 11th 2008, 1.19pm</td>
change them by adding a custom sort key in YYYYMMDDHHMMSS format:
<td sorttable_customkey="20080211131900">February 11th 2008, 1:19pm</td>
The YYYYMMDDHHMMSS format for the date in the custom key will sort properly, and sorttable will use the information in the custom key rather than the information in the table cell itself.
Sorttable, by default, does an unstable sort. This means that it does not maintain the order of rows where those rows have the same key in the sorted column. Wikipedia has more on stable sorting. If this is a problem, and you need the sort to be stable, you can do it by making a tiny edit to sorttable.js. Edit the file and find the lines:
/* If you want a stable sort, uncomment the following line */
//sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
/* and comment out this one */
row_array.sort(this.sorttable_sortfunction);
and change them so the shaker_sort line is uncommented instead:
sorttable.shaker_sort(row_array, this.sorttable_sortfunction);
//row_array.sort(this.sorttable_sortfunction);
The sort will now be stable. However, it will be considerably slower (the stable sorting can take eight times as long as the unstable sort), which is why it isn't enabled by default.
If you'd like some column headers to not be clickable, meaning that
your users won't be able to resort the table by those columns, then add
class="sorttable_nosort"
to the <th>
column header. Observe how the "number of legs" column here isn't
sortable.
Name | Team | Number of legs |
---|---|---|
Molby, Jan | Liverpool | 2 |
Hughes, Mark | Manchester Utd | 2 |
Nicol, Steve | Liverpool | 2 |
Ardiles, Ossie | Tottenham Hotspur | 2 |
Charlie Nicholas | Arsenal | 2 |
Lots of people ask, "how do I make sorttable sort the table the first time the page is loaded?" The answer is: you don't. Sorttable is about changing the HTML that is served from your server without a page refresh. When the page is first served from the server, you have to incur the wait for it to be served anyway. So, if you want the table sorted when a page is first displayed, serve the table in sorted order. Tables often come out of a database; get the data from the database in a sorted order with an ORDER BY clause in your SQL. Any solution which involves you running sorttable as soon as the page loads (i.e., without user input) is a wrong solution.
Making sorttable sort your columns in descending order first rather than ascending order requires editing sorttable.js. Find the line:
row_array.sort(this.sorttable_sortfunction);
and after it, add a new line:
row_array.reverse();
Making sorttable sort your columns case-insensitively (so uppercase and lowercase letters sort together) requires editing sorttable.js. Find the lines:
sort_alpha: function(a,b) {
if (a[0]==b[0]) return 0;
if (a[0]<b[0]) return -1;
return 1;
},
and change them for
sort_alpha: function(a,b) {
if (a[0].toLowerCase()==b[0].toLowerCase()) return 0;
if (a[0].toLowerCase()<b[0].toLowerCase()) return -1;
return 1;
},
Sorttable has changed quite a lot in this new version 2. Please read the release announcement for more details of what's changed and who is to be thanked. If for some reason you need the original version 1 of sorttable you can download it from sorttable_v1.js along with the original instructions.
Sorttable, like all my DOM scripts, is under the X11 licence, which basically means you can do what you want with it, including using it at work, in a commercial setting or product, or in open source projects (including those that are GPL licenced). If you're not sure, or you have other questions, please contact me for details.
You don't have to. I believe in Free Software; writing this and seeing people use it is its own reward. Of course, if you're determined to give me money then I'm not going to stop you. You can send money to my PayPal account with the button below.
Firstly, thanks for using sorttable; sorry it's not doing quite what you want! You can see the list of issues with sorttable, both fixed ones and ones still outstanding, in the sorttable bug tracker. It's quite possible that someone's already reported the issue you've discovered. If a bug hasn't been fixed yet, you can "subscribe" to it in the bug tracker, and when it changes you'll get an email telling you I've done something. If your bug isn't there, do please contact me and tell me about it, and I'll add it to the list to be fixed.
Yes. Sorttable gets worked on in my spare time, between paid work, which means that development might not be as fast as you like. If you really want something fixed, you can jump it up my priority list by waving money at me. Best thing to do is to contact me and we can talk about rates and so on.
Stuart Langridge, November 2003, April 2007