How to Load a Set Number of Rows from a Table on Pageload and Only Load Further Rows When the User Loads Them

How can i load a set number of rows from a table on pageload and only load further rows when the user loads them?

This will focus purely on the DataTables aspects of a "server-side" solution. How you write the server-side logic needed to support it is out of scope for this answer. But I hope these notes will at leasst clarify what that logic needs to be, and how you can approach it.

Assumptions

Assume you have a text file containing 1,000 rows of data like this (or a million - but too many rows to send to the browser and to DataTables, all at once). The text file is a simple pipe-delimited file, with three fields:

id|name|description
1|widget_1|This is a description for widget 1
2|widget_2|This is a description for widget 2
3|widget_3|This is a description for widget 3
...
1000|widget_1000|This is a description for widget 1000

You want to send 10 items at a time to DataTables, using server-side processing.

Your data maps to a simple JSON structure, like this - an array of objects (each object is one record):

[
{
"id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
},
{
"id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
},
... // more records...
]

The DataTable Definition

Your datatable definition looks like this - it is deliberately very simple, at this stage:

<body>

<div style="margin: 20px;">

<table id="demo" class="display dataTable cell-border" style="width:100%">
</table>

</div>

<script type="text/javascript">

$(document).ready(function() {
$('#demo').DataTable({
serverSide: true,
ajax: {
url: 'http://localhost:7000/data',
type: 'POST'
},
columns: [
{ title: 'ID',
data: 'id' },
{ title: 'Name',
data: 'name' },
{ title: 'Description',
data: 'description' }
]
});

});
</script>

</body>

Initial Response

When the web page is first displayed, it will send an initial POST request to the URL (http://localhost:7000/data), and it will expect to receive a JSON response from the web server, containing the data to be displayed.

Because DataTables is using serverSide: true, DataTables will expect the JSON to have a specific structure, as described here.

Specifically, the server has to add all of the mandatory fields (draw, recordsTotal, recordsFiltered, and data) to the JSON it sends to DataTables.

In our case it would look like this - note that it is just our previously mentioned JSON structure, with a few extra metadata fields added:

{
"draw": 1,
"recordsTotal": 1000,
"recordsFiltered": 1000,
"data": [{
"id": 1,
"name": "widget_1",
"description": "This is a description for widget 1"
}, {
"id": 2,
"name": "widget_2",
"description": "This is a description for widget 2"
}, {
"id": 3,
"name": "widget_3",
"description": "This is a description for widget 3"
}, {
"id": 4,
"name": "widget_4",
"description": "This is a description for widget 4"
}, {
"id": 5,
"name": "widget_5",
"description": "This is a description for widget 5"
}, {
"id": 6,
"name": "widget_6",
"description": "This is a description for widget 6"
}, {
"id": 7,
"name": "widget_7",
"description": "This is a description for widget 7"
}, {
"id": 8,
"name": "widget_8",
"description": "This is a description for widget 8"
}, {
"id": 9,
"name": "widget_9",
"description": "This is a description for widget 9"
}, {
"id": 10,
"name": "widget_10",
"description": "This is a description for widget 10"
}]
}

It is the server's responsibility to build this JSON - the first 10 records of the server's data set. The server also tells DataTables that it has a total of 1,000 records, and that it has not filtered out any data (yet) - hence there are also a total of 1,000 records after filtering.

DataTables needs all of this information, so it knows how many pagination buttons to display, and what pagination data to show.

Note that it is entirely the server's responsibility to do all this work - that's why it's called "server-side" processing.

The client (browser) only has 10 records to render - so that happens quickly.

server-side screen

(I just noticed that the screenshot mentions "500 records" - that's a mistake in my server-side code - there is no filter, so I need to fix that).

Subsequent Requests

When a user clicks on a page navigation button (e.g. page "4"), that triggers a new request from DataTables to the server. DataTables builds this request automatically, using the fields described here.

The request is sent as form data.

In our example, the request looks like this:

"Form data": {
"draw": "5",
"columns[0][data]": "id",
"columns[0][name]": "",
"columns[0][searchable]": "true",
"columns[0][orderable]": "true",
"columns[0][search][value]": "",
"columns[0][search][regex]": "false",
"columns[1][data]": "name",
"columns[1][name]": "",
"columns[1][searchable]": "true",
"columns[1][orderable]": "true",
"columns[1][search][value]": "",
"columns[1][search][regex]": "false",
"columns[2][data]": "description",
"columns[2][name]": "",
"columns[2][searchable]": "true",
"columns[2][orderable]": "true",
"columns[2][search][value]": "",
"columns[2][search][regex]": "false",
"order[0][column]": "1",
"order[0][dir]": "asc",
"start": "30",
"length": "10",
"search[value]": "",
"search[regex]": "false"
}

These fields tell the server everything it needs to know, so it can prepare the correct response.

In our case the most important fields are these:

"start": "30",
"length": "10"

Start at row 30, and provide 10 records.

It is, again, the server's responsibility to prepare a JSON response which accurately reflects the requested data.

In our case this means the server needs to have logic to read through the text file to the correct starting point (data row 31 - remember the offset starts at zero), and 10 rows in total (rows 31 through 40).

Other fields in the above request from DataTables describe how the data is to be sorted, and filtered. In our case there is no filter "search[value]": "", - and the data is to be sorted by the first column in ascending order.

Final Notes

I have deliberately not described the following:

1) How your server-side code handles the creation of the JSON responses it sends back to DataTables;

2) How your server-side code parses the form requests it receives from DataTables.

That all depends entirely on what your server-side technology is. DataTables doesn't care. It's just passing JSON messages - it is decoupled from the server-side implementation - as it should be.

Regarding the "defer render" option described here, that is an enhancement you may choose to add if you feel you need it. But I would recommend getting a more basic server-side implementation working first.

Change the order of table rows on page load

What about something like this?

Add an id to the <tbody>. Otherwise use a CSS selector (not shown).

<table>
<tbody id="table-body">

</tbody>
</table>

Write some javascript that runs at window.document.ready()

<script language="javascript">
$(window.document).ready(function () {
var tableRows = Array(),
i = 0,
tempRow = undefined;

//clone each row node to the local array
$('#table-body').children().each(function cloneRowsToArray() {
tableRows.push($(this).clone());
});

//re-order the array as necessary
tempRow = tableRows[0];
tableRows[0] = tableRows[1];
tableRows[1] = tempRow;

//re-write the newly arranged rows.
$('#table-body').children().each(function replaceEachRowFromArray() {
$(this).replaceWith(tableRows[i]);
i += 1;
});
});
</script>

Selecting Row After Render/Table Load

table.selectRow(ROWID); wont work until table is initialized you
have to do this.selectRow

Check this jsfiddle

  renderComplete: function() {
const rows = this.getRows();
console.log('rows', rows);
for (let i = 0; i < rows.length; i++) {
const childRows = rows[i].getTreeChildren();
if (childRows.length > 0) {
// console.log('childRows', childRows);

// this.selectRow(childRows);
for (let j = 0; j < childRows.length; j++) {
const gender = childRows[j].getData().gender;
console.log('gender', gender);
if (gender === 'male') {
this.selectRow(childRows[j]);
const childRows2 = childRows[j].getTreeChildren();

}
}
}
}
}
});

material-table - How to add more rows per page and fix rendering - ReactJs

As mentioned in the docs you can use emptyRowsWhenPaging and set it to false in the options.



Related Topics



Leave a reply



Submit