Skip to content

setSort() applies multi-column sort priority in reverse order (last entry becomes primary, not first) — getSorters() reports the correct order while the applied result doesn't match it #4939

Description

@mjklugman

Describe the bug

When calling setSort() with more than one sort entry, the sort priority is applied in the reverse of the order specified — the last entry in the array is treated as the primary sort key, and the first entry as secondary, rather than the other way around. This also happens with genuine interactive multi-column sorting (click a column header, then Shift/Ctrl+click a second one) — the second-clicked column ends up as primary, the first-clicked as secondary, the reverse of expected behavior.

Critically, getSorters() correctly reports the sorters array in the originally intended order (matching what was passed to setSort(), or the actual click order) — so the reported sort state and the actually-applied row order are inconsistent with each other. This makes the bug easy to miss unless you specifically compare the visible row order against what getSorters() reports.

To Reproduce

Minimal example (tested directly against v6.5.2, the current release, via the tabulator-tables npm package):

<!DOCTYPE html>
<html>
<head>
  <link href="https://unpkg.com/tabulator-tables@6.5.2/dist/css/tabulator.min.css" rel="stylesheet">
  <script src="https://unpkg.com/tabulator-tables@6.5.2/dist/js/tabulator.min.js"></script>
</head>
<body>
  <div id="example-table"></div>
  <pre id="output"></pre>
  <script>
    var table = new Tabulator("#example-table", {
      data:[
        {id:1, genre:"Rock", album:"Zulu"},
        {id:2, genre:"Jazz", album:"Alpha"},
        {id:3, genre:"Rock", album:"Alpha"},
        {id:4, genre:"Jazz", album:"Zulu"},
      ],
      columns:[
        {title:"Genre", field:"genre", sorter:"string"},
        {title:"Album", field:"album", sorter:"string"},
      ],
    });

    table.on("tableBuilt", function(){
      // Genre listed FIRST (intended as primary), Album SECOND (intended as secondary)
      table.setSort([
        {column:"genre", dir:"asc"},
        {column:"album", dir:"asc"},
      ]);

      var actualOrder = table.getRows("active").map(r => r.getData().genre + "/" + r.getData().album);
      var reportedSorters = table.getSorters().map(s => s.field);

      document.getElementById("output").textContent =
        "getSorters() reports (in this order): " + reportedSorters.join(", ") + "\n" +
        "Actual row order: " + actualOrder.join(", ") + "\n\n" +
        "Expected if Genre is truly primary: Jazz/Alpha, Jazz/Zulu, Rock/Alpha, Rock/Zulu\n" +
        "Actually observed (Album is really primary): " + actualOrder.join(", ");
    });
  </script>
</body>
</html>
  1. Open the above in a browser (or paste into a blank CodePen with the same two script/link tags).
  2. Observe the printed output: getSorters() reports genre, album (matching what was passed in), but the actual row order groups rows by album first, not genre.
  3. The same reversal reproduces with genuine interactive sorting: click one column header, then Shift-click (or Ctrl-click, depending on config) a second column header — the second-clicked column ends up as the primary sort key.

Expected behavior

The first entry in the array passed to setSort() (or the first column clicked, in interactive multi-column sorting) should be the primary sort key, with each subsequent entry acting as a tie-breaker for rows that are equal on all prior keys — matching both the documented behavior and what getSorters() itself reports.

Tabulator Info

Which version of Tabulator are you using?
Directly confirmed via isolated minimal reproduction on 6.5.2 (current release, via npm). Also observed with the same pattern on 6.4.0 and 6.2.0, and informally on the live example page at tabulator.info (6.5.0), across multiple unrelated column pairs (e.g. Title/Conductor as well as Genre/Album), so this doesn't appear to be specific to any particular columns, data, or a recent regression.

Desktop:
OS: Windows 11
Browser: tested via Node/jsdom harness with tabulator-tables 6.5.2, plus confirmed interactively in Chrome

Additional context

This was originally found while debugging what looked like a much stranger, project-specific issue (a persistent initialSort configuration appeared to corrupt sort behavior specifically on the columns it was applied to) — but once that was resolved, this simpler, general reversal remained and reproduces cleanly with plain columns and no special configuration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Possible BugA possible bug that needs investigation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions