sorttable: Make all your tables sortable
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:
- Download the Javascript library
- Include the Javascript library, by
putting a link to it in the HEAD of your page, like so:
<script src="/img/spacer.gif">
- Mark your table as a sortable one by giving it a class of
"sortable":
Note that the library's JavaScript file is called<table class="sortable">
sorttable
(two Ts), but the class you add to the table issortable
(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.
Advanced usage
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.
- How do I sort a table that I added with Ajax?
- How do I make my "totals" row stay at the bottom of my table?
- How do I sort some data in a format that sorttable doesn't understand?
- What do I do if sorttable isn't sorting my data the way I'd expect it to?
- How do I make sorttable handle dates in the format I put them in?
- Can sorttable do a stable sort?
- How can I tell a sortable table to sort from my code, rather than from a user click?
- How do I make some columns not be sortable?
- Can sorttable sort a table as soon as the page loads, without requiring the user to click?
- How do I make sorttable sort columns in descending order first rather than ascending order?
- How do I make sorttable sort text case-insensitively (i.e., so lower-case and upper-case letters sort together)?
- What's new in version 2 of sorttable?
- Can I use sorttable in a commercial product? On a commercial website? What licencing terms is it available under?
- I love sorttable so much that I want to donate some money to you even though I don't have to. Can I?
- I've found a problem in sorttable. How can I tell you about it?
- But I need my problem with sorttable to be fixed! Can I pay you to fix it?
Sorting a table added after page load
Once you've added a new table to the page at runtime (for example, by doing an Ajax request to get
the content, or by dynamically creating it with JavaScript), get a reference to it (possibly with
var newTableObject = document.getElementById(idOfTheTableIJustAdded)
or similar), then do this:
sorttable.makeSortable(newTableObject);
Totals rows
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>
<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 |
Using custom sort keys
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>
<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.
Manually specifying a column's type
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>
<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.
Using custom date formats
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.
Stable sorting
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.
Sorting a table from your code
Sometimes you want to, from your own JavaScript code, tell a table to sort. This is deliberately awkward because you shouldn't be doing it, and you'll want to make sure that you have an up-to-date version of sorttable.js to do it (download it from this site), but it's doable. Call
var myTH = document.getElementsByTagName("th")[0];
sorttable.innerSortFunction.apply(myTH, []);
See the example table and buttons below.
Name | Car |
---|---|
Stuart Langridge | Nissan Juke |
Jeremy Clarkson | Mercedes CLK Black |
Penelope Pitstop | The Pink Pussycat |
The Ant Hill Mob | Chug-a-Boom |
Making some columns unsortable
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 |
Sorting the table when the page is loaded
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.
(However, if you really want to, see sorting a table from your own code.)
Sort in descending order first
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();
Sort case-insensitively
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;
},
Changes from sorttable v1
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.
Licencing
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.
Can I give you money for sorttable? I really like it
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.
I've found a problem in sorttable. How can I tell you about it?
Firstly, thanks for using sorttable; sorry it's not doing quite what you want! If your question isn't answered on this page, please contact me and tell me about it, and I'll try and give you some pointers on how to fix it yourself.
But I need my problem with sorttable fixed! Can I pay you to fix it?
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
kryogenix.org | other browser experiments