Every day I become more of a jQuery fan, and every day I find some other jQuery plugin that does something I need to do. Today, that something is table sorting. There is, of course, a jQuery plugin for this: Tablesorter. It’s simple. I like simple.

Most Javascript-based table sorting solutions lack persistence, as they probably should, and Tablesorter is no exception. There’s a common belief that all initial sorting should be done on the back-end, and that using Javascript to do it is bad practice. To those who harbor this belief, I say: Whatever!

What I want is a drop-in persistent sorting solution to use with Tablesorter, which is itself a drop-in solution. I’m all about dropping things in, and don’t steal my thunder with your “ideals.”

I can hear you say: “Why not just use Ajax or pass some query parameters to your script that modify the ‘order by’ section of your SQL statement?” Good question. Or is it? (Hint: no)

I won’t provide a long, convoluted explanation, but the simplest way to look at it is this: Data can be built in different places and in different ways. Maybe you can quickly write something that handles the first part of that, but how about the second? What if the data isn’t being built directly from a SQL statement. What if the columns you see (in the HTML table) don’t map to columns in a database? And so on. Work work work.

This is getting complicated. Let’s simplify. What did I say I wanted to do? Ah yes, persistently sort HTML tables. And that’s it. I don’t care where the data is coming from, I don’t care what it’s for, or what scripting language is used to create it. I just want to sort it, and have the sort stick.

And I’m willing to use cookies to do it. Let’s have a look at how, together.

Tablesorter has a widget interface and a parser interface. “Persistent sorting” doesn’t really sound like a widget or a parser, but it sounds less like a parser so let’s make a widget. To do this, we’ll also need the jQuery JSON plugin and the jQuery Cookie plugin.

Once we have all that, we can make a widget that creates a cookie to keep a map of the last sort done to a table, using the form: {tableId: sortList}. The idea is to set the cookie sortList whenever a sort is done on a table, and check the cookie for an existing sortList every time a page with the table loads. If a sortList exists for the table, sort with it, which will also then save it to the cookie, and so on.

Lucky for us, Tablesorter’s widget interface fires off the function format(table) every time the sorter is initialized, and once after every sort, which is exactly what we need. The code:

$(document).ready(function() {
    // give the widget an id
    id: "sortPersist",
    // format is called when the on init and when a
    // sorting has finished
    format: function(table) {

      // Cookie info
      var cookieName = 'MY_SORT_COOKIE';
      var cookie = $.cookie(cookieName);
      var options = {path: '/'};

      var data = {};
      var sortList = table.config.sortList;
      var tableId = $(table).attr('id');
      var cookieExists = (typeof(cookie) != "undefined"
          && cookie != null);

      // If the existing sortList isn't empty, set it into the cookie
      // and get out
      if (sortList.length > 0) {
        if (cookieExists) {
          data = $.evalJSON(cookie);
        data[tableId] = sortList;
        $.cookie(cookieName, $.toJSON(data), options);

      // Otherwise...
      else {
        if (cookieExists) { 

          // Get the cookie data
          var data = $.evalJSON($.cookie(cookieName));

          // If it exists
          if (typeof(data[tableId]) != "undefined"
              && data[tableId] != null) {

            // Get the list
            sortList = data[tableId];

            // And finally, if the list is NOT empty, trigger
            // the sort with the new list
            if (sortList.length > 0) {
              $(table).trigger("sorton", [sortList]);
  $("#maintable").tablesorter({widgets: ['sortPersist']});

And there you have it, a Tablesorter widget that implements a persistable sort using cookies. Here’s an example of it in action. Sort on a column, then refresh to page to see that the column is still being sorted.