views:

53

answers:

1

Got myself in a funny situation: page has three tables. Using sortEnd, any time you sort one table, it sorts the other three. However, since I bound sortEnd to the function that does the sorting, you get a infinite loop of sorting/resorting. It looks like:

$("table.tablesorter").tablesorter({widgets: ['zebra']}).bind("sortEnd", function() {
    $(this).find("th.headerSortDown,.headerSortUp").each(function(i) {
        index = $(this).attr("cellIndex");
        order = ($(this).is(".headerSortDown")) ? 1 : 0;
        $("table.tablesorter").tablesorter({sortList: [[index,order]]});
    });
});

Any tips on how to clean this up?

Based on feedback below from Nick Craver, the following code seems to work well:

$("table.tablesorter").tablesorter({widgets: ['zebra']}).bind("sortEnd", function() {
    var current = $(this);
    if (current.data("sorting")) {
        current.data("sorting", false);
        return false;
    }
    $(this).find("th.headerSortDown,.headerSortUp").each(function(i) {
        index = $(this).attr("cellIndex");
        order = ($(this).is(".headerSortDown")) ? 1 : 0;
        $("table.tablesorter").not(current).data("sorting", true).trigger("sorton", [[[index,order]]]);
    });
});
A: 

You can use .data() to "tag" the other tables telling them not to execute this handler after the current sort, like this:

$("table.tablesorter").tablesorter({widgets: ['zebra']}).bind("sortEnd", function() {
  if($(this).data("sorting")) {
    $(this).data("sorting", false);
    return;
  }
  var current = this;
  $(this).find("th.headerSortDown,.headerSortUp").each(function(i) {
    index = $(this).attr("cellIndex");
    order = ($(this).is(".headerSortDown")) ? 1 : 0;
    $("table.tablesorter").not(current).data("sorting", true).tablesorter({sortList: [[index,order]]});
  });
});

This stores a boolean in the data cache on all the other tables (already filtered out this one from running again filtering it with .not()). When the handler executes, it checks if this value is present, if so toggles it off for the next sort, but skips the loop that triggers other tables to sort again.

Nick Craver
Doesn't work- there's a chain of the other tables firing all .tablesorter tables, so checking for the current one doesn't address the issue.
Wells
@Wells - Updated to accommodate this as well...I can't test this readily, so let me know if there are any issues.
Nick Craver
Did you try this on a page w/ three tables classed as tablesorter? :)
Wells
@Wells - Setting up a test case is not that simple...that's why I asked if there were any issues :) If you had a page I could access, it's be easy to test.
Nick Craver
Hrmm. Maybe it does work. I made a few adjustments and am using this method: $("table.tablesorter").tablesorter({widgets: ['zebra']}).bind("sortEnd", function() { var current = $(this); if (current.data("sorting")) { current.data("sorting", false); return false; } $(this).find("th.headerSortDown,.headerSortUp").each(function(i) { index = $(this).attr("cellIndex"); order = ($(this).is(".headerSortDown")) ? 1 : 0; $("table.tablesorter").not(current).data("sorting", true).trigger("sorton", [[[index,order]]]); }); });
Wells
Oops. Can't post code in comments :)
Wells