by Andrzej Kowal

Datatables.net – ajax pagination on scroll

Listing and paginating data in a web application can be implemented in many different ways. One technique I really like is automatic ajax pagination on window scroll. It provides great user experience and a clean UI without any paging controls. It requires loading just enough items to force the browser to show the vertical scrollbar. When user decides to scroll the window – more items are loaded with ajax as soon as the scroll reaches around 80% of the window height. This approach is widely used by many websites: Facebook, Twitter, Pinterest, LinkedIn and many more. However when it comes to tabular data plain old paging is still implemented quite often, Time for a change.

Recently, when working on insights feature in Ping.it, I had to implement “expand on scroll” behavior in an HTML table driven by jQuery datatables plugin. It is a very handy utility, which converts any HTML table into a powerful client-side enabled grid. It has two basic operation modes: client and server side. To my surprise in the server mode the grid cannot be easily extended with new rows loaded from the server. It supports only the traditional paging. When I tried to force the grid to load more rows, it ended up refreshing the whole grid. After a bit of research and experiments I came up with a solution. In the scroll event handler more data is loaded from the server with ajax:

[javascript]
var scrollForMoreData = function() {
$.ajax({
url: ‘/LoadMoreData’,
data: { … },
success: ajaxSuccess
});
};
[/javascript]

The server JSON response contains formatted HTML table rows:

[javascript]
var result = {
"content": "<tr>
<td>Mary Jane</td>
<td>26</td>
</tr>
<tr>
<td>Peter Parker</td>
<td>28</td>
</tr>…",
"hasMore": true
};
[/javascript]

On ajax success the <tr>s are simply appended to the end of the existing HTML table:

[javascript]
var ajaxSuccess = function (result) {
$(‘#my-table tbody’).append(result.content)
};
[/javascript]

The datatables sorting and filtering still can be used – in such case full grid refresh is the correct behavior (since sorting or filtering can fetch data currently not visible in the grid).

There is one important thing to consider – when loading more data with ajax it is essential to copy the datatable’s auto-generated ajax request data in order to send correct sorting and filtering parameters to the server:

[javascript]
$(‘#my-table’)
.on(‘xhr.dt’, function () {
var ajaxData = $(this).api().ajax.params();
$(this).data(‘custom-ajax-parameters’, ajaxData);
});
[/javascript]

Note that xhr event must be bound with the .dt namespace. Later when user scrolls the page I can retrieve the ajaxData object stored within the #my-table DOM object. And send this object as input to my “scroll” ajax request. This ensures that the server will actually return correctly sorted and filtered result. Since we don’t use datatables paging feature we need to handle it ourselves e.g. by adding additional parameter to “scroll” ajax request – the amount of already displayed rows (or page number, depending on your paging implementation). The adjusted scrollForMoreData function looks like this:

[javascript highlight=”2,3″]
var scrollForMoreData = function() {
var ajaxData = $(‘#my-table’).data(‘custom-ajax-parameters’);
ajaxData.skipRows = $(‘#my-table tbody tr’).length;
$.ajax({
url: ‘/LoadMoreData’,
data: ajaxData,
success: ajaxSuccess
});
};
[/javascript]

Happy data-listing!