Apr 7

Sorttable v2: making your tables even more sortable

Sorttable, the JavaScript table sorting library, is pretty much the most popular thing I’ve ever written. (Top hit for “javascript sort table” on Google, too.) Over the four years or so since I first released it, there’s been a steady trickle of thanks, feature requests, and bug fixes to it. I’ve finally got around to releasing a new version of the script that hopefully covers everything that people were looking for. You can get it at the same place as it ever was, sorttable: Make all your tables sortable.

What’s changed in version 2

The most important thing that’s changed is that sorttable now has a much much clever automatic column typer. You still can just drop sorttable in place and not have to do any configuration, but it’s quite a bit cleverer about working out whether your columns are numeric or dates or currency or text. It skips blank lines, it can tell the difference between English and American format dates, it understands numbers with commas in and negative numbers. This is the number one feature request. Secondly, you can now use custom sort keys for those columns that sorttable can’t work out for itself. See the page for details, but this should allow anyone to make anything work with sorttable v2. It’s also a bit more compliant with HTML standards. To add a “totals” row you should add the row to a <tfoot> section in your table. Sorttable v1 used a class of “sortbottom” on totals rows; for backwards compatibility this is still supported, but you really should be using <tfoot> instead. In a similar way, sorttable now uses <thead> as your column headers if you have it. If you do not have it then it will create a <thead> and put the first row of your table in it. This is a backwards incompatible change: to apply style to your table headers, you should now style table.sortable thead, not table.sortable a.sortheader as in v1. Input elements are now supported in table cells! If your table cells contain input elements then sorttable will use the value in the input element. Sorttable is now quite a lot faster than it used to be, owing to various little tweaks. It’s especially fast at resorting the table by the column you’ve already sorted by (but reversed), because now it just reverses the table rather than doing the sort. Stable sorting is supported but commented out in the code (because the stable sort is implemented in JavaScript, not using the native list sorter, and so it’s a lot slower). You can change this by editing one line in sorttable.js if stable sorting is important; see the page for details.

Thanks

Lots of people (really, really lots) have contributed code suggestions, feature requests, bug reports, and compliments about sorttable. Here’s my chance to say thankyou. So: thankyou to… Eric Chang, Mehmet Kut, Dan Synder, Jeff Bradley, Eric Holstege, Victor Kryukov, Nikola Ivanov, Geoff Clevenger, Mikko Suniala, Scott Reynen, Justin Meyer, Leonardo Kenji Shikida, Ben Ostrowsky, Daniel Berlin, Richard Snazell, Mark James, Eric Rizzo, Garve, Andreas Rehm, Scott Kingdon, Marcus Månsson, Bill Barry, Michael Rumpler, Avi Rogers, Kevin Wu, Espen Hovlands, Petronel Laviniu Malutan, John M. Pierre, opus27, Brendan Bowles, Marty O’Brien, Alex Rubin, Chris Gay, Jack Vanhan, Guy Rosen, John Dawson, Ryan Korczykowski, Carl Forde, Pete K, Glenn Haser, Richard Grassy, Olivier Briat, Bob Hanson, Alex Z, Narayana Rao Kankipati, Rey Hernandez, Eric Moriztz, Marco Valk, Marcus Daniel, David Dockhorn, Angela Weise, Aneel Nazareth, Jeremy Hulford, Thomas K. Weinstock, Edward, Matthew Egbers, Anton Berezin, Moustafa Elqabbany, Justin Williams, Daniel Chace, Inigo Surguy, Vladimir Kornea, John Mund, Pablo, David Golden, Brad Kemper, Brian Schott, Christian Robottom Reis, Justin Haygood, C. David Eagle, Simon Willison, and Dean Edwards. Phew! All those people have contacted me asking for new features or have sent me patches or have provided code that I was able to reuse in v2 of sorttable. Thankyou: for those of you who wanted sorttable to do something new, I hope you like it.

296 thoughts on “Sorttable v2: making your tables even more sortable

  1. spacer dsas says:

    Oh..you’re where I got that code from. Thanks!

  2. spacer sil says:

    dsas: no problem. spacer

  3. spacer margiex says:

    if i have more than one row in header, I want to do sort by the last header row, how can I set it?
    thx

  4. spacer sil says:

    margiex: you can’t, I’m afraid. Sorttable doesn’t support tables with more than one header row, because it gets a bit confused by them.

  5. spacer mrben says:

    It would be nice if a third click on a header would revert the table back to the original sort, rather than just toggling ascending and descending on that column.

    Just a thought spacer

  6. spacer sil says:

    mrben: daresay it would, but that would mean caching the table structure, which I’d like to avoid spacer If you want that, hit refresh.

  7. spacer mrben says:

    Why would it mean caching the table structure? Surely you could define the default sort somewhere, and then re-run that particular sort on every third click of a header? Or have I over-simplified?

  8. spacer sil says:

    mrben: there isn’t a “default sort”; there’s just “what the table looked like when it got served from the server”, which could be in any order at all or even no order.

  9. spacer mrben says:

    Ah. Point taken. Shame spacer

  10. spacer sil says:

    mrben: hence “hit refresh” to get that order back.

  11. spacer log @ Make Data Make Sense » Sortable Tables with Totals and Averages says:

    [...] Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL. « Discussion List, Crossdomain.xml forFlash [...]

  12. spacer tommie says:

    Would it be possible to add some extra variables to the makeSortable() function, like:

    makeSortable($(‘table’), ‘header’, ‘ASC’);

    Where the last two can the name of the header and sorting order you’d like to use for sorting immediately instead of just adding the event listeners.

  13. spacer sil says:

    tommie: Sorttable doesn’t support sorting the table as soon as the page is loaded. There are some notes as to why not in the old sorttable documentation (see “Sorting a table the first time the page is loaded”).

  14. spacer Anonymous Coward says:

    In Netscape 8 this script close the window. There is a solution for this?

  15. spacer GaryF says:

    Stuart: I’ve just had the inevitable “client-side sorting” request on a new project I’m working on. Less than 5 minutes later, we had it working. Thanks a lot for this script, I owe you a drink.

  16. spacer ScottW says:

    Nice job! If I could only get it to work spacer

    When I include your script file in my Asp.net AJAX site I get the following error.

    Error Sys.ArgumentTypeException: Object of type ‘Object’ cannot be converted to type ‘Array’
    Parametername:array

    This occurs even if I don’t have any sortables defined.

    Any Ideas?

    The error is occuring in a file calse ResourceScript.axd

    Here is the function

    Array.forEach = function Array$forEach(array, method, instance) {
    ///
    ///
    ///
    var e = Function._validateParams(arguments, [
    {name: "array", type: Array, elementMayBeNull: true},
    {name: "method", type: Function},
    {name: "instance", mayBeNull: true, optional: true}
    ]);
    if (e) throw e;

    for (var i = 0, l = array.length; i

  17. spacer ScottW says:

    I’ve narrowed it down further and the code below in the sorttable init function is causing the error.

    forEach(document.getElementsByTagName(‘table’), function(table) {

    if (table.className.search(/bsortableb/) != -1) {
    sorttable.makeSortable(table);
    }
    });

    I’m not as versed in Javascript as you are so any help would be appreciated.

  18. spacer ScottW says:

    Got it working. It took 2 code changes. Basically it was erroring on function(table) and onsort it error on function(Cell). I’ve include my new code in case it helps someone else.
    // forEach(document.getElementsByTagName(‘table’), function(table) {
    var tables = document.getElementsByTagName(“table”);
    for (var i=0; i

  19. spacer ScottW says:

    Change 1
    var tables = document.getElementsByTagName(“table”);
    for (var i=0; i

  20. spacer ScottW says:

    Sorry guys, this forum keeps cutting off my post when I include the code.

    I basically changed each foreach loop into an index loop and accessed each table and cell using the appropriate array index.

    I also had the problem that my tables are loaded via AJAX after page initialization. A simple call to sorttable.makeSortable(MyNewTable) worked like a charm.

    Thanks again for the code!

    Scott

  21. spacer sil says:

    GaryF: that’s what it’s for. spacer

  22. spacer sil says:

    ScottW: glad you got it sorted! I’d like to talk over this in more detail; could you drop me a mail? (See the contact link for my address.)

  23. spacer robert Lee says:

    you are very appreciated for you good job at sorttable.js.
    And i also have a question.
    To have the function ” when the table is loaded, one column is sorted”, how can i do it?

    thanks very much!
    RobertLee
    From Peking of China

  24. spacer Varun says:

    Hey, I was tryin out the script, great job spacer although having a few a problems, I think it is similar to ScottW’s problem, if you could somehow please provide me with the fix, I would be really thankful. I dont know if this is another problem when your table is in a javascript variable, and calling the html contents of the variable through innerHTML, but the script doesnt work on the tables then. (I think it works in IE, but not firefox and mozilla, really being odd like that)

  25. spacer robert Lee says:

    To Varun:
    I have used sorttable.js. it does indeed work in IE.

  26. spacer Jason Friesen says:

    Fantastic tool, thanks so much!

    I’m curious why you chose to use the non-standard sorttable_customkey="2" rather than a class attribute? I’m loath to use invalid markup. spacer

    That said, I can see myself using this in many places, particularly at my workplace, a community college in British Columbia, Canada. I’ve been creating complicated workarounds in my custom CMS but this is a far better solution all around. Well done!

  27. spacer sil says:

    Jason: two reasons. Firstly, a custom sortkey is emphatically not a class spacer I feel a bit guilty about using class atrributes for things like column type overrides, but they are *sort of* appropriate. If you use a class of “2″ as a sortkey, then you’re suggesting that that table cell is like other cells with a class “2″, which it ain’t; it contains (something that maps to) the value 2, which is not the same thing. That’s the academic ivory-tower argument. The other argument is that if you’ve got more than one class applied to the cell then it won’t know which one to use as the sortkey, and setting class=”sorttable_sortkey_2″ seemed very silly spacer I didn’t like the invalid markup either, I have to admit it, but it seemed the lesser of the evils.

  28. spacer Jason Friesen says:

    Fair enough. I’m working tangentially with Moodle that does all sorts of your second example to attempt to be fully compliant. I admit it’s a bit crazy to look at class="course_47 subsection_cheese_danish_12". I think I’d still prefer that, but I definitely see your point.

    Nevertheless, I sure appreciate the code. spacer