Hi @Natalia_Shilova , @Listopad , @webix_B_123
I’m using Webix Pro (v11.x) and have a datatable with thousands of records (virtual scrolling enabled).
For performance reasons, I want to adjust / expand only the currently visible rows (around 20 rows) — not the entire dataset.
Currently, I use a custom method to adjust row height to fit the largest cell text when a row is selected.
/**
* @Method resizeRowHeight
* Adjusts row height based on the largest text content of its cells.
*/
const resizeWebixRowHeight = (rowObj, dataTable) => {
const colIds = [];
dataTable.config.columns?.forEach(colObj => colObj.id && colIds.push(colObj.id));
function processRow(grid, rowObjL) {
const configuredRowHeights = [grid.config.rowHeight || 24];
let config;
for (let i = 0; i < colIds.length; i++) {
if (colIds[i] === "checkColumn") continue;
config = grid.getColumnConfig(String(colIds[i]));
const tempDiv = webix.html.create("DIV", {
class: "webix_table_cell webix_measure_size webix_cell",
style: "height:1px; visibility:hidden; white-space: normal !important; position:absolute; top:0px; left:0px; overflow:hidden;word-break:break-all !important;"
}, "");
dataTable.$view.appendChild(tempDiv);
tempDiv.style.width = config.width + "px";
const cellValue = rowObjL[String(config.id)];
tempDiv.innerHTML = cellValue ? webix.template.escape(cellValue) : "";
configuredRowHeights.push(tempDiv.scrollHeight);
webix.html.remove(tempDiv);
}
rowObjL.$height = Math.max.apply(null, configuredRowHeights);
rowObjL.$css = (rowObjL.$css || "") + " adjustRow";
}
const row = dataTable.getItem(rowObj.row);
if ((row.$css + "").indexOf(" adjustRow") !== -1) {
row.$css = row.$css.replace(" adjustRow", "");
row.$height = dataTable.config.rowHeight;
} else {
processRow(dataTable, row);
}
dataTable.config.__prevAdjustedRow = rowObj.row;
dataTable.refresh();
};
This works perfectly for a single selected row.
However, now I’d like to expand all currently visible rows only (i.e., the ones rendered in the viewport, ~20 rows) — not the entire dataset (1000+ records).
What I’ve tried
- Using
getVisibleCount()
— works, but I couldn’t find a way to get start/end indexes.
- Tried to use
getVisibleRange()
— seems deprecated in newer versions.
Please suggest me a best solution on this.
Thanks in advance
Hello @Abhishek_Reddy
To get start/end indices please use getScrollState method to get current scroll position.
Using the row height we can get the index of the first visible record:
const first = Math.floor(state / table.config.rowHeight);
Using the getVisibleCount we can calculate the index of the last one.
Please check the example: Code Snippet
@Natalia_Shilova , @Listopad
What I below requirements to achive
-
Adjust row height for only the currently selected record (not all rows)
-
A checkbox to Expand All Rows (auto-fit to content).
-
When unchecked, revert all rows to their original/compact height.
-
I’m using custom HTML templates (badges, multi-line content). I want auto-height to work seamlessly with these templates.
below I have sample custom render temple
const renderMultiSelectColumn = (
obj: FileNode | webix.obj | RULE_DETAILS_DATA,
value: string,
column: webix.WebixDatatableColumn & {
_filterText?: string;
_matchCase?: boolean;
_matchWholeWord?: boolean;
separator?: string;
}
) => {
if (!value) return renderEmptyValue();
const separator = column.separator || ',';
const values = value
.split(separator)
.map((v) => v.trim())
.filter(Boolean);
if (values.length === 0) return renderEmptyValue();
const adjusted = isRowAdjusted(obj);
const chips = values.map((val) => {
const displayText = adjusted ? val : middleEllipsis(val, 20);
const highlighted = getHighlightedSearchText(
displayText,
column._filterText || '',
undefined,
adjusted,
column._matchCase,
column._matchWholeWord
);
const encodedVal = encodeHtml(val);
return `<span class="chip-item" webix_tooltip="${encodedVal}">${highlighted}</span>`;
});
return `<div class="multi-select-chips" webix_tooltip="${encodeHtml(value)}">${chips.join('')}</div>`;
};
export { renderMultiSelectColumn };```
Hello @Abhishek_Reddy ,
Please try this example: Code Snippet
- Adjust row height for only the currently selected record (not all rows)
To adjust row height of the currently selected item, you first need to determine the width of the cells excluding paddings and rowLineHeight :
const item = this.getItem(selection.row)
const config = this.getColumnConfig(selection.column);
const width = config.width - webix.skin.$active.dataPadding*2;
const lineHeight = this.config.rowLineHeight;
Next, you can obtain the raw width of the text in that particular cell (using getText and webix.html.getTextSize ) to calculate the necessary height for the cell:
const cellContent = this.getText(selection.row, selection.column);
const size = webix.html.getTextSize(cellContent, "webix_table_cell");
const cellHeight = lineHeight*Math.ceil(size.width/width);
And using setRowHeight method apply the necessary height.
- A checkbox to Expand All Rows (auto-fit to content).
To expand all row please use adjustRowHeight method.
- When unchecked, revert all rows to their original/compact height.
To revert all rows you can use each method of the DataStore to iterate the items and apply the default height:
table.data.each(function (obj) {
obj.$height = height;
this.refresh();
})