Data table hangs browser when Large data in the table
Datatable search pane with large data set hangs for few second .
My project using react(fe) + node.js(be)
scenarioTable = new DataTable(tableRef?.current, {
fixedColumns: {
leftColumns: 2,
left: 1,
start: 2,
},
fixedHeader: true,
scrollX: 300,
scrollY: ((windowDimensions?.height/1.5)-100),
scrollCollapse: true,
scrollInfinite: true,
colReorder: colReorder_options,
data: scenarioData,
language: {
loadingRecords: " ",
processing: "Loading...",
},
buttons: html5Buttons(),
destroy: true,
pageLength: 100,
lengthMenu: [
[10, 25, 50, 100, 500, -1],
["10", "25", "50", "100", "500", "Show all"],
],
aaSorting: [],
searchPanes: {
layout: 'columns-4',
orderable: false,
threshold: 1,
},
dom: "PBfrtip",
columns: scenarioColumnsHeaders?.map((element, index) => {
// console.log(element, "=====element")
element.render = function (data, type, row) {
if (
type === "display" &&
data != null &&
typeof data === "string"
) {
data = data.replace(/<(?:.|\\n)*?>/gm, "");
data = data.replaceAll('"', "");
const dataTitle = data;
data = data.split(",").join(",<br/>")
if (data.length > 100 && data[element.data] == 'Business Capability') {
return `<span class='show-ellipsis text-wrapped' data-title='${dataTitle}'>${data.substr(
0,
100
)} ...</span><span class='no-show'>${data.substr(100)}</span>`;
} else if (data.length > 50) {
return `<span class='show-ellipsis text-wrapped' data-title='${dataTitle}'>${data.substr(
0,
50
)} ...</span><span class='no-show'>${data.substr(50)}</span>`;
} else {
return data || "";
}
} else {
return data || "";
}
}
return element;
}),
select: {
style: "multi",
selector: "td:first-child",
},
initComplete: function (settings, json) {
var api = this.api();
replacePlaceholder();
// this.api().searchPanes.rebuildPane();
$('#int-app-table').on('dblclick', 'tbody td', async function (e) {
let container = $("div.comment-content");
container.remove();
message.destroy()
if (UserService.hasRole(['Admin', 'Editor'])) {
setDefaultSelectValue([]);
setModalSelectOpen(false);
setModalTextareaOpen(false);
setInputValue('');
let columnIndex = $(this).index();
var rowIndex = $(this).closest('tr').index();
let row = scenarioTable.row(this).data();
let scenarioId;
if (row && row?.DT_RowId) {
scenarioId = row.DT_RowId.split("_")[2];
}
let columnId = null;
let availableColumnId = null;
const column = scenarioColumns[columnIndex - 1];
if (scenarioColumnsResponse?.length != 0) {
for (let item of scenarioColumnsResponse) {
if (item?.columnName == column?.label) {
columnId = item.id;
availableColumnId = item.availableColumnId;
break
}
}
}
let value = $(this).text();
if ($(this).find('span.text-wrapped').length !== 0) {
value = $(this).find('span.text-wrapped').attr('data-title');
}
let obj = {
scenarioId: scenarioId,
rowIndex: rowIndex,
columnId: columnId,
availableColumnId: availableColumnId,
column: column,
row: row,
}
setSelectSubmitData(obj)
if (column?.type == "select") {
const dropdownVal = await ScenarioServices.getScenarioDropdownValue({
"columnId": availableColumnId,
})
if (dropdownVal.data) {
setOptions(dropdownVal.data)
} else {
setOptions(column?.ipOpts)
}
let trimmedValues;
if (value.includes(',')) {
trimmedValues = value.split(',').map(item => item.trim());
setDefaultSelectValue(trimmedValues)
} else {
trimmedValues = [value];
setDefaultSelectValue(trimmedValues)
}
setModalSelectOpen(true)
} else {
setTextareaValue(value);
setModalTextareaOpen(true)
}
} else {
message.error("You are not authorised to update the data!")
}
})
$('#int-app-table').on('contextmenu', 'tbody td', function (event) {
message.destroy()
if (UserService.hasRole(['Admin', 'Editor'])) {
setSelectSubmitData({})
var columnIndex = $(this).index();
let row = scenarioTable.row(this).data()
if (row) {
let scenarioId = row.DT_RowId.split("_")[2];
let rowId = row.DT_RowId.split("_")[1];
let columnId = null;
let availableColumnId = null;
const column = scenarioColumns[columnIndex - 1];
if (scenarioColumnsResponse?.length != 0) {
for (let item of scenarioColumnsResponse) {
if (item?.columnName == column?.label) {
columnId = item.id;
availableColumnId = item.availableColumnId;
break
}
}
}
setSelectSubmitData({
rowId: rowId, columnId: availableColumnId, scenarioId: scenarioId
})
show({
event,
props: {
key: 'value'
}
})
}
} else {
message.error("You are not authorised to apply comment!")
}
})
$('.dataTables_scrollHead').css({
'overflow-x': 'scroll'
}).on('scroll', function (e) {
var scrollBody = $(this).parent().find('.dataTables_scrollBody').get(0);
scrollBody.scrollLeft = this.scrollLeft;
$(scrollBody).trigger('scroll');
});
},
createdRow: function (row, data, dataIndex) {
if (data['column_base']) {
$(row).css('background-color', '#d8e5f1');
$(row).css('font-weight', '600');
}
for (let key in data) {
if (key.includes('_comment') && data[key] && data[key].length > 0) {
const columnIndex = getColumnIndexByKey(scenarioColumnsHeaders, key.replace('_comment', ''));
if (columnIndex !== -1) {
const cell = $(row).find('td:eq(' + columnIndex + ')');
cell.addClass('comment-added');
const commentData = data[key];
const commentContent = commentData.map(item => {
const formattedDate = new Date(item.createdAt).toLocaleDateString('en-GB', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
return `
<strong>User:</strong> ${item.userEmail ? item.userEmail : '-'}<br>
<strong>Comment:</strong> ${item.comment}<br>
<strong>Date:</strong> ${formattedDate}<br>
<hr>
`;
}).join('');
// Add Bootstrap popover
cell.attr('data-toggle', 'popover');
cell.attr('data-html', 'true'); // Enable HTML content
cell.attr('data-content', commentContent);
// cell.attr('data-trigger', 'hover');
cell.attr('data-placement', "bottom");
// cell.popover();
}
}
if (key.includes('_difference') && data[key]) {
const columnIndex = getColumnIndexByKey(scenarioColumnsHeaders, key.replace('_difference', ''));
if (columnIndex !== -1) {
const cell = $(row).find('td:eq(' + columnIndex + ')');
cell.css('color', '#ea0505');
cell.css('font-style', 'italic')
}
}
}
},
searchDelay: 350,
drawCallback: function (settings) {
let searchText = $('#int-app-table_filter input[type=search]').val();
if (settings?.iDraw >= 2) {
setHighlight(searchText);
}
$('.paginate_button.next:not(.disabled)', this.api().table().container())
.on('click', function () {
alert('next');
})
}
});
Edited by Colin - Syntax highlighting. Details on how to highlight code using markdown can be found in this guide.