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)
This commit is contained in:
phot0n 2022-06-09 11:43:53 +05:30
parent b4428639cb
commit 430d7cfe48
3 changed files with 34 additions and 17 deletions

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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 `<input class="dt-filter dt-input" type="text" ${dataAttr} tabindex="1"
return `<input class="dt-filter dt-input" type="text" ${dataAttr} tabindex="1"
${props.colIndex === 0 ? 'disabled' : title} />`;
}