سؤال

I'm using the jQuery tablesorter 2.14.5. I load the table like this:

var html = '';
for (var i = 0; i < rows.length; i++) {
    // code to fill html
}
$('#TableToFill tbody').html(html);
$('#TableToFill').tablesorter({...});

if (filterlist) {
    $.tablesorter.setFilters($('#TableToFill'), filterlist, true);
}

And it works great when the page first loads. However I'm refreshing the contents of the table with AJAX. It reloads rows and runs this code again. When the page first loads (and filterlist does have something) then the table's contents are filtered properly. When the AJAX completes and this code runs again (filterlist containing the same thing it had before) then the table does not filter. The filter inputs have the proper values in them, but the unfiltered table contents are displayed.

What can I do differently to make sure that when the table is recreated with new values through AJAX that the filters stay applied?

EDIT: All of the code.

HTML for empty table:

<table id="ProblemQueue" class="tablesorter tablesorter_sorted" border="0" cellpadding="0" cellspacing="1" style="overflow: scroll;">
    <colgroup>
        <col span="1" style="width: 17%;">
        <col span="1" style="width: 17%;">
        <col span="1" style="width: 10%;">
        <col span="1" style="width: 20%;">
        <col span="1" style="width: 5%;">
        <col span="1" style="width: 5%;">
        <col span="1" style="width: 13%;">
        <col span="1" style="width: 8%;">
        <col span="1" style="width: 5%;">
    </colgroup>
    <thead>
        <tr class="tablesorter-headerRow">
            <th>First Name</th>
            <th>Last Name</th>
            <th>DOB</th>
            <th class="filter-select">Problem</th>
            <th class="filter-false">Note</th>
            <th class="filter-false">Action</th>
            <th>Last Worked</th>
            <th class="filter-select">User</th>
            <th>Date Recieved</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
</table>

The only call to tablesorter:

$("#ProblemQueue").tablesorter({
    theme: 'blue',
    widthFixed: true, // hidden filter input/selects will resize the columns, so try to minimize the change
    widgets: ["zebra", "filter"],// initialize zebra striping and filter widgets
    headers: { 4: { sorter: false, filter: false }, 5: { sorter: false, filter: false } },
    widgetOptions: {
        filter_childRows: false,
        filter_columnFilters: true,
        filter_cssFilter: 'tablesorter-filter',
        filter_filteredRow: 'filtered',
        filter_formatter: null,
        filter_functions: null,
        filter_hideFilters: false, // true, (see note in the options section above)
        filter_ignoreCase: true,
        filter_liveSearch: true,
        filter_reset: 'button.reset',
        filter_searchDelay: 300,
        filter_serversideFiltering: false,
        filter_startsWith: false,
        filter_useParsedData: false
    }
}).bind('filterEnd', function () {
    sessvars.filters.ProblemQueue = $.tablesorter.getFilters($('#ProblemQueue'));
});

The table is always filled through ajax. The above example was shortened for conciseness, but here is what the actual code looks like:

function GetProblemQueue(async) {
    async = async || true;
    var url = "/our/rest/api";
    $.ajax({
        url: url,
        dataType: "json",
        headers: { "x-li-format": "json" },
        async: async,
        cache: false,
        success: function (data) {
            problems = data; // problems is global
            FillProblemQueue();
        },
        type: "Get"
    });
}

function FillProblemQueue() {
    var rows = '';
    for (var i = 0; i < problems.length; i++) {
        var style = "odd";
        if (i % 2) { style = "even"; }
        rows += "<tr class='" + style + "'><td>";
        // cell text added to rows, removed business logic
        rows += "</td><td>";
        ...
        rows += "</td><td>";
        ...
        rows += "</td><td>";
        ...
        rows += "</td><td style='text-align:center;'>";
        ...
        rows += "</td><td>";
        ...
        rows += "</td><td>";
        ...
        rows += "</td><td>";
        ...
        rows += "</td><td>";
        ...
        rows += "</td></tr>";
    }
    $("#ProblemQueue tbody").html(rows);
    $('#ProblemQueue').trigger('update');
    if (sessvars.filters.ProblemQueue) {
        $.tablesorter.setFilters($('#ProblemQueue'), sessvars.filters.ProblemQueue, true);
    }
}

GetProblemQueue(true) is called on document ready and there's a setInterval that calls it every 60 seconds. This is in IE 10. It has to work for IE 10 due to business requirements.

هل كانت مفيدة؟

المحلول

Tablesorter should not be re-initialized after the ajax call

// this should only be done once
$('#TableToFill').tablesorter({...});

Instead after each ajax call, trigger an update:

$('#TableToFill').trigger('update');

The filter widget should reapply automatically, so no need to set the filters again.


Update: Oh, I understand now. Basically, the filter widget won't update its search when the filters haven't changed. It doesn't know that the table contents have been updated. So to bypass that issue, trigger a "search" on the table and include a false flag:

$('#TableToFill').trigger('search', false);

I'll fix this in the next update, so that when the setFilter function is called with the apply flag set to true, it will force a new search.

Here are a few other observations I noticed when reviewing the above code:

  • There is no need to include widget options if they are not changing the default.
  • There is no need to set the widthFixed option as it will not do anything since a <colgroup> and <col> is already defined.
  • Adding a filter: false to the headers option has priority over the "filter-false" class name in the header <th class="filter-false">. There is no need to include both, either will work.
  • With the above suggestion, triggering a search with false flag, there shouldn't be a need to use $.tablesorter.getFilter() or $.tablesorter.setFilter() functions.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top