From 430d7cfe4818e0763953c53818d6d93e13591684 Mon Sep 17 00:00:00 2001 From: phot0n Date: Thu, 9 Jun 2022 11:43:53 +0530 Subject: [PATCH] fix: use custom formatter when filtering rows As datatable renders only some rows at a time and sets each cell's html property based on that rendering, so when someone filters things and only looks at some rows without scrolling the whole grid and tries to filter things (when there is a custom cell formatter), they won't be able to see the data as the filtering is done based on cell's content not html (as it's not set at that point) --- src/cellmanager.js | 31 +++++++++++++++++++------------ src/filterRows.js | 16 +++++++++++++--- src/rowmanager.js | 4 ++-- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/cellmanager.js b/src/cellmanager.js index 5a41620..bcd2af8 100644 --- a/src/cellmanager.js +++ b/src/cellmanager.js @@ -527,7 +527,7 @@ export default class CellManager { const done = editor.setValue(value, rowIndex, col); // update cell immediately - this.updateCell(colIndex, rowIndex, value); + this.updateCell(colIndex, rowIndex, value, true); $cell.focus(); if (done && done.then) { @@ -605,7 +605,7 @@ export default class CellManager { let rowIndex = i + focusedCell.rowIndex; row.forEach((cell, j) => { let colIndex = j + focusedCell.colIndex; - this.updateCell(colIndex, rowIndex, cell); + this.updateCell(colIndex, rowIndex, cell, true); }); }); } @@ -620,16 +620,16 @@ export default class CellManager { } } - updateCell(colIndex, rowIndex, value) { + updateCell(colIndex, rowIndex, value, refreshHtml = false) { const cell = this.datamanager.updateCell(colIndex, rowIndex, { content: value }); - this.refreshCell(cell); + this.refreshCell(cell, refreshHtml); } - refreshCell(cell) { + refreshCell(cell, refreshHtml = false) { const $cell = $(this.selector(cell.colIndex, cell.rowIndex), this.bodyScrollable); - $cell.innerHTML = this.getCellContent(cell); + $cell.innerHTML = this.getCellContent(cell, refreshHtml); } toggleTreeButton(rowIndex, flag) { @@ -804,7 +804,7 @@ export default class CellManager { `; } - getCellContent(cell) { + getCellContent(cell, refreshHtml = false) { const { isHeader, isFilter, @@ -827,15 +827,18 @@ export default class CellManager { const hasDropdown = isHeader && cell.dropdown !== false; const dropdown = hasDropdown ? this.columnmanager.getDropdownHTML() : ''; - const customFormatter = cell.format || (cell.column && cell.column.format) || null; - + let customFormatter = CellManager.getCustomCellFormatter(cell); let contentHTML; if (isHeader || isFilter || !customFormatter) { contentHTML = cell.content; } else { - const row = this.datamanager.getRow(cell.rowIndex); - const data = this.datamanager.getData(cell.rowIndex); - contentHTML = customFormatter(cell.content, row, cell.column, data); + if (!cell.html || refreshHtml) { + const row = this.datamanager.getRow(cell.rowIndex); + const data = this.datamanager.getData(cell.rowIndex); + contentHTML = customFormatter(cell.content, row, cell.column, data); + } else { + contentHTML = cell.html; + } } cell.html = contentHTML; @@ -885,4 +888,8 @@ export default class CellManager { selector(colIndex, rowIndex) { return `.dt-cell--${colIndex}-${rowIndex}`; } + + static getCustomCellFormatter(cell) { + return cell.format || (cell.column && cell.column.format) || null; + } } diff --git a/src/filterRows.js b/src/filterRows.js index 9e9fd78..4dca6cd 100644 --- a/src/filterRows.js +++ b/src/filterRows.js @@ -1,4 +1,5 @@ import { isNumber, stripHTML } from './utils'; +import CellManager from './cellmanager'; export default function filterRows(rows, filters) { let filteredRowIndices = []; @@ -17,7 +18,7 @@ export default function filterRows(rows, filters) { const cells = filteredRows.map(row => row[colIndex]); let filter = guessFilter(keyword); - let filterMethod = getFilterMethod(filter); + let filterMethod = getFilterMethod(rows, filter); if (filterMethod) { filteredRowIndices = filterMethod(filter.text, cells); @@ -29,9 +30,18 @@ export default function filterRows(rows, filters) { return filteredRowIndices; }; -function getFilterMethod(filter) { +function getFilterMethod(rows, filter) { + const getFormattedValue = cell => { + let formatter = CellManager.getCustomCellFormatter(cell); + if (formatter && cell.content) { + cell.html = formatter(cell.content, rows[cell.rowIndex], cell.column, rows[cell.rowIndex]); + return stripHTML(cell.html); + } + return cell.content || ''; + }; + const stringCompareValue = cell => - String(stripHTML(cell.html || '') || cell.content || '').toLowerCase(); + String(stripHTML(cell.html || '') || getFormattedValue(cell)).toLowerCase(); const numberCompareValue = cell => parseFloat(cell.content); diff --git a/src/rowmanager.js b/src/rowmanager.js index 720e97e..16eb5f5 100644 --- a/src/rowmanager.js +++ b/src/rowmanager.js @@ -67,7 +67,7 @@ export default class RowManager { const _row = this.datamanager.updateRow(row, rowIndex); _row.forEach(cell => { - this.cellmanager.refreshCell(cell); + this.cellmanager.refreshCell(cell, true); }); } @@ -353,7 +353,7 @@ export default class RowManager { getFilterInput(props) { let title = `title="Filter based on ${props.name || 'Index'}"`; const dataAttr = makeDataAttributeString(props); - return ``; }