jqueryhtmlajaxdynamictablesorter

jQuery tablesorter does not work on my dynamically loaded table?


I'm trying to use the jquery.tablesorter.js on a dynamically loaded table. I can get it to work flawlessly on a table that is loaded at runtime but not on a table that is built by Ajax.

I have followed many previous tips I have found on here to no avail. Currently I am running a script to call table sorter on page load, with click of a button my table gets built and I call the an update to table sorter after the table is loaded into my page.

I have the following code.

<!-- SCRIPT TO CALL TABLESORTER BEFORE TABLE IS BUILT -->
<script>
    $(document).ready(function () {
        $("#Observation").tablesorter();            
    }
    );
</script>


<!-- SCRIPT TO BUILD TABLE AND CALL TRIGGER UPDATE TO TABLESORTER -->
<script>
    function loadObservations(status) {
        var xhttp = new XMLHttpRequest();
        var a = 'Status=' + status;
        xhttp.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                buildOpenTable(this);
            }
        };
        xhttp.open("POST", "http://localhost:57766/PALWebService.asmx/ObservationResult", true);

        xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        xhttp.send(a);
    }
    function buildOpenTable(xml) {            
        var i;
        var xmlDoc = xml.responseXML;
        var table = "<thead><tr><th>ID</th><th>SITE</th><th>BUILDING</th><th>OBSERVATION</th><th>ACTION</th><th>DATE OBSERVED</th><th>UPDATED BY</th><th></th></tr></thead>";
        var x = xmlDoc.getElementsByTagName("CurrentObservation");            

        for (i = 0; i < x.length; i++) {
            table += "<tbody><tr><td class=col1>" +
                x[i].getElementsByTagName("GUID")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("SITE")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("BUILDING")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("OBSERVATION_DETAIL")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("ACTION")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("DATE_OBSERVED")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("UPDATED_BY")[0].childNodes[0].nodeValue +
                "</td><td>" +
                "<span class=btnSelect id=btnSelect>Select</span>" +
                "</td ></tr ></tbody> ";
        }
        document.getElementById("Observation").innerHTML = table;           
        $("#Observation").trigger("update");
        window.location.hash = "#tableSummary";            
    }

</script>


<!-- TABLE SUMMARY OF OBSERVATIONS -->
<div class="container-fluid" id="tableSummary">
    <h3 class="text-center">Observation Summary</h3>
    <div class="table-responsive">
        <table id="Observation" class="tablesorter table table-condensed table-hover table-bordered"  style="background-color:white"></table>
    </div>
</div>

Solution

  • When an "update" is triggered, tablesorter is only expecting the contents of the tbody to have changed. It will ignore any thead modifications, and if you completely replace the thead, the click bindings are not reapplied.

    In your case it appears that the thead isn't changing, so I would recommend only modifying the tbody:

    function buildOpenTable(xml) {
        var i;
        var xmlDoc = xml.responseXML;
        var tbody = "";
        var x = xmlDoc.getElementsByTagName("CurrentObservation");
    
        for (i = 0; i < x.length; i++) {
            tbody += "<tr><td class=col1>" +
                x[i].getElementsByTagName("GUID")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("ID")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("SITE")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("BUILDING")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("OBSERVATION_DETAIL")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("ACTION")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("DATE_OBSERVED")[0].childNodes[0].nodeValue +
                "</td><td>" +
                x[i].getElementsByTagName("UPDATED_BY")[0].childNodes[0].nodeValue +
                "</td><td>" +
                "<span class=btnSelect id=btnSelect>Select</span>" +
                "</td ></tr >";
        }
        $("#Observation tbody").html(tbody);
        $("#Observation").trigger("update");
        window.location.hash = "#tableSummary";
    }