jQuery TableSorter and XSL Transformation

2009 Sept 1 at 07:36 » Tagged as :xml, javascript, jquery, ajax, node.js,

Jquery and it's plugins are so popular because they allow you to do in a couple of lines of code what might otherwise take days and days of effort.. The tablesorter plugin is one that allows you to sort an HTML table by clicking on any of the column names in the table header. I am talking of a real HTML table not one that is made with UL and LI. Tabular data should be represented by TABLE, TR and TD tags but some people go overboard with LIs and use them even for tabular data.

The table sorter plugin can sort both static and dynamic data inserted into the HTML through user interaction. It can also cope with data retrieved from remote sources (with an XHR). Here is an example straight out of the docs:

    $(document).ready(function() {

    $("table").tablesorter();

    $("#ajax-append").click(function() {

         $.get("assets/ajax-content.html"function(html) {

             // append the "ajax'd" data to the table body

             $("table tbody").append(html);

            // let the plugin know that we made a update

            $("table").trigger("update");

            // set sorting column and direction, this will sort on the first and third column

            var sorting = [[2,1],[0,0]];

            // sort on the first column

            $("table").trigger("sorton",[sorting]);

        });

        return false;

    });

});

What if your webservice only produced XML and you had to rely on an XSL Tranformation to convert it to HTML? Well I found out the hard way that this otherwise excellent plugin has trouble with that. The data would be inserted into the table but the rows would not be sorted. Only the original content (the data that was statically included would be included). So I ran into a funny situation where only the top half of a table would have it's row order changed while the bottom half remained obstinately fixed! Here is the fragment of code that fetched the data, transformed it and appended it into the TBODY.

$.get('report.xsl', function(tr){

xsl_pages = tr;

xProcPrimary.importStylesheet(tr);

$.get('report.php', function(data){

xmlMain = data;

var fragment = xProcPrimary.transformToFragment(xmlMain, document);

$("#msummary tbody").append(fragment);

$("#msummary").trigger("update");

});

} );

After a couple of hours of head scratching and the tedium; I figured out that the

  • DocumentFragment
  • is being appended to the table in some weird way, fixing bugs in your own code is hard enough so I never entertained any thoughts of finding the cause of the problem in the tablesorter codebase. Instead, I came up with a work around: Add the DocumentFragment to a hidden HTML element, then call the jQuery.html() method on that element to generate the HTML source for it and append that HTML into the table. In other words, I cam up with a quick and painless way to convert a DocumentFragment into HTML source.

    $.get('report.xsl', function(tr){

    xsl_pages = tr;

    xProcPrimary.importStylesheet(tr);

    $.get('report.php', function(data){

    xmlMain = data;

    var fragment = xProcPrimary.transformToFragment(xmlMain, document);

    $("div.sortable").html(fragment);

    alert(fragment);

    $("#msummary tbody").append($("div.sortable").html());

    $("div.sortable").html();

    $("#msummary").trigger("update");

    });

    } );