I have a fiddle that make an ajax to URL and rendering a table, but I want to defer and load only 10 rows during page load.
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Account ID</th>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
</table>
$(document).ready(function() {
$('#example').DataTable( {
"bPaginate": true,
"processing": true,
"bServerSide": true,
ajax: {
url: 'https://api.myjson.com/bins/1egsx',
dataSrc: 'data'
},
columns: [
{ data: 'account_id' },
{ data: 'name' },
{ data: 'email' }
],
"deferRender": true,
"deferLoading": 10,
} );
});
I kept getting
No matching records found
There is a option called pageLength . You can set this for show only 5 entries.
len() method can still be used if you wish to programmatically change the page size and pageLength can be used to specify the initial page length.
This option allows DataTables to create the nodes (rows and cells in the table body) only when they are needed for a draw.
TL;DR: You should probably be either using deferRender
with client-side processing OR server-side processing without deferRender
(by fixing your JSON data). This answer assumes you want server-side processing.
deferLoading
When correctly using server-side processing, the default behavior is to only send the number of rows on one page per ajax request. You shouldn't need to be using deferLoading - here's what that does (from documentation here):
When using server-side processing, the default mode of operation for DataTables is to simply throw away any data that currently exists in the table and make a request to the server to get the first page of data to display. This is fine for an empty table, but if you already have the first page of data displayed in the plain HTML, it is a waste of resources. As such, this option exists to allow you to instruct DataTables to not make that initial request, rather it will use the data already on the page (no sorting etc will be applied to it).
Since all your data comes from ajax, that option shouldn't be selected.
deferRender
You really shouldn't need to use deferRender
either, if you're correctly using serverside processing. deferRender
will (from it's documentation here):
As an example to help illustrate this, if you load a data set with 10,000 rows, but a paging display length of only 10 records, rather than create all 10,000 rows, when deferred rendering is enabled, DataTables will create only 10.
Note the important phrase here:
if you load a data set with 10,000 rows
If you're using serverside processing correctly, you should only be loading the number of rows per page in a single load. deferRender
is really an option to speed up datatables when using clientside processing. Serverside processing already handles what deferRender
does. See this picture from the DataTables FAQ for how to speed up datatables:
Note that it emphasizes deferRender
for clientside only. A note to make here is that if you don't have a LOT of rows (tens of thousands +) you probably don't need to use serverside processing.
Your problem probably comes from the fact that your API isn't returning the proper form of JSON for server-side processing; you need to send more information than just the data to be displayed. Here is the documentation page with the full description (you should definitely read it), but I'll try to outline the basics below.
Request
The request sent to your API is going to contain some data that you need to address.
draw
is a unique identifier that tracks sets of request-response pairs; the value in the response needs to match the value in the request. This is how datatables matches requests to responses.
start
represents the record that should be the first in the response; if we are showing 10 records per page and we're on page 2, start
will be equal to 10, so that in the response we send only records numbered 10-19.
length
represents the expected number of rows for this draw, so in the above example of 10 records per page on page 2, length
will be equal to 10. This is how many records you should return. This value will be based on the lengthMenu
or pageLength
options to the Datatables initialization. (Documented here and here, respectively)
An important thing to remember that is often forgotten is to ONLY send as many rows as length
; don't send all your rows in the first request.
Response
Your response will need to be altered as well.
Basically, instead of just returning data
, you need to return an object that looks like the below example (from that documentation page):
{
"draw": 1,
"recordsTotal": 57,
"recordsFiltered": 57,
"data": [
[
"Angelica",
"Ramos",
"System Architect",
"London",
"9th Oct 09",
"$2,875"
],
[
"Ashton",
"Cox",
"Technical Author",
"San Francisco",
"12th Jan 09",
"$4,800"
],
...
]
}
Note the additional data: draw
, recordsTotal
, and recordsFiltered
in addition to the usual data
. These are required options when using serverside processing.
draw
represents the number corresponding to the request made to your API; the GET request will also have a draw
value, and the value in the GET must match the value in the response.
recordsTotal
represents the total number of records in the table, across all pages, where recordsFiltered
represents the number of records that meet the filtering requirements set by the GET request (if there is no filtering, it should be equal to recordsTotal
.
These are the minimum required elements to your reply, but you should look into the linked documentation for more information on optional values.
Side Note
As a side note; bServerSide
should be serverSide
and bPaginate
should be paging
if you're using DataTables version 1.10 or later.
I assume your intention here is to display the DataTable as soon as the page loads. Described below are two ways to load partial data depending on your requirements. The entire data can be loaded at a later point in time by triggering an event like click of a button. In both cases, the entire data will be downloaded as well and stored locally which can then be loaded based on the triggered event so as to avoid making another call to fetch the entire data.
Case 1: Only want to download partial data from the source
The entire data will be fetched from 'https://api.myjson.com/bins/1egsx' before the DataTable will process the data. If you want to only fetch partial data from the URL, you can create your custom function that will parse the data in AJAX interactive mode (readyState=3), stop after receiving the first 10 entries and then massage the data and pass that as the input data for the DataTable. Here's a summary of what you need to do
var inputData = '';
function loadDataTablePreview() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 3 && this.status == 200) {
inputData += this.responseText;
// Count the number of closing '}'. If its 10, lets start processing our data
// Get the index of 10 closing '}'
// Create a substring of inputData
// append ']}'
// Now JSON Decode
var decodedData = JSON.parse(inputData);
// Now create an instance of the DataTable passing this data as the input data
$('#example').DataTable( {
"bPaginate": true,
"processing": true,
"bServerSide": true,
data: decodedData,
columns: [
{ data: 'account_id' },
{ data: 'name' },
{ data: 'email' }
],
});
}
else if (this.readyState == 4 && this.status == 200) {
// JSON Decode the data and store it to load later
}
};
xhttp.open("GET", "https://api.myjson.com/bins/1egsx", true);
xhttp.send();
}
$(document).ready(function() {
loadDataTablePreview();
}
Case 2: Only load the first 10 entries after downloading entire data
Assuming you are ok with having the entire data downloaded, before displaying the DataTable, you can create a function for your dataSrc as seen below. This will display return only the 10 entries in the table. You can optionally store the entire JSON in this function in the browser data store (like sessionStorage) and then trigger a JS function to load the entire JSON at a later point in time.
$(document).ready(function() {
$('#example').DataTable( {
"bPaginate": true,
"processing": true,
"bServerSide": true,
ajax: {
url: 'https://api.myjson.com/bins/1egsx',
dataSrc: function ( json ) {
// Store entire data in sessionStorage
// return the first 10 entries only for now
return json.data.slice(0,10);
},
},
columns: [
{ data: 'account_id' },
{ data: 'name' },
{ data: 'email' }
],
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With