From c32407516df6eb38869971f353aef9f75f29a622 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 15 Sep 2026 12:51:18 +0530 Subject: [PATCH] feat(sort): sort on a value returned by the column Sorting compares `cell.content`, so a column that renders something other than its stored value sorts by the value the user cannot see. `compareValue` already solves this for filtering; `sortValue` is the same idea for sorting. A column with a `sortValue(cell)` function sorts on what that returns. Columns without one are unchanged. --- cypress/integration/column.js | 23 +++++++++++++++++++++++ src/datamanager.js | 12 ++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/cypress/integration/column.js b/cypress/integration/column.js index 106f0fe7..cbdc4d2c 100644 --- a/cypress/integration/column.js +++ b/cypress/integration/column.js @@ -35,6 +35,29 @@ describe('Column', function () { cy.clickDropdownItem(2, 'Reset sorting'); }); + it('sorts on the value returned by a column sortValue hook', function () { + // Sort the Name column by surname instead of the cell content. + cy.window().then(win => { + win.datatable.getColumn(2).sortValue = cell => String(cell.content).split(' ').pop(); + }); + + cy.clickDropdown(2); + cy.clickDropdownItem(2, 'Sort Ascending'); + + cy.window().then(win => { + const datamanager = win.datatable.datamanager; + const surnames = datamanager.rowViewOrder + .map(rowIndex => String(datamanager.getCell(2, rowIndex).content).split(' ').pop()); + + expect(surnames).to.deep.equal([...surnames].sort()); + }); + + cy.clickDropdownItem(2, 'Reset sorting'); + cy.window().then(win => { + delete win.datatable.getColumn(2).sortValue; + }); + }); + it('removes column using dropdown action', function () { cy.get('.dt-cell--header').should('have.length', 12); diff --git a/src/datamanager.js b/src/datamanager.js index dd49b5c1..5b9065f7 100644 --- a/src/datamanager.js +++ b/src/datamanager.js @@ -283,14 +283,18 @@ export default class DataManager { } } + const sortValue = cell => { + const hook = cell.column && cell.column.sortValue; + const value = hook ? hook(cell) : cell.content; + return value == null ? '' : value; + }; + this.rowViewOrder.sort((a, b) => { const aIndex = a; const bIndex = b; - let aContent = this.getCell(colIndex, a).content; - let bContent = this.getCell(colIndex, b).content; - aContent = aContent == null ? '' : aContent; - bContent = bContent == null ? '' : bContent; + const aContent = sortValue(this.getCell(colIndex, a)); + const bContent = sortValue(this.getCell(colIndex, b)); if (sortOrder === 'none') { return aIndex - bIndex;