Add data from server while scrolling
Add data from server while scrolling
Hello,
I'm trying to auto load the data to table while scrolling in browser. So to accomplish that I wrote my own dataLoader:
[code]
"fnServerData": dadaLoader
[/code]
Code that loads new data is something like this:
[code]
var oCache = {
iCacheLength: 0,
iLock: false
};
function dadaLoader(sSource, aoData, fnCallback) {
jQuery(window).scroll(function(){
if (!oCache.iLock) {
if (jQuery(window).scrollTop() == jQuery(document).height() - jQuery(window).height()) {
oCache.iLock = true;
jQuery.getJSON(sSource + "?iLimit=" + oCache.iCacheLength + ",30", aoData, function(json) {
var outJson = jQuery.extend(true, {}, oCache.lastJson);
outJson.aaData = jQuery.merge(outJson.aaData, json.aaData);
oCache.lastJson = jQuery.extend(true, {}, outJson);
oCache.iCacheLength = oCache.iCacheLength + json.aaData.length;
fnCallback(outJson);
oCache.iLock = false;
});
}
}
});
jQuery.getJSON(sSource + "?iLimit=0,30", aoData, function(json) {
oCache.lastJson = jQuery.extend(true, {}, json);
oCache.iCacheLength = oCache.iCacheLength + json.aaData.length;
fnCallback(json)
});
}
[/code]
PROBLEM
If I understand correctly, alway then i update aaData array the DataTable is redrawn. So if i scroll a lot the aaData gets bigger and bigger (table redraw is longer and longer with every scroll). Is it somehow possible to not redraw existent rows and add only new (not redraw all table)?
Or maybe there is some better solution to accomplish such functionality?
I'm trying to auto load the data to table while scrolling in browser. So to accomplish that I wrote my own dataLoader:
[code]
"fnServerData": dadaLoader
[/code]
Code that loads new data is something like this:
[code]
var oCache = {
iCacheLength: 0,
iLock: false
};
function dadaLoader(sSource, aoData, fnCallback) {
jQuery(window).scroll(function(){
if (!oCache.iLock) {
if (jQuery(window).scrollTop() == jQuery(document).height() - jQuery(window).height()) {
oCache.iLock = true;
jQuery.getJSON(sSource + "?iLimit=" + oCache.iCacheLength + ",30", aoData, function(json) {
var outJson = jQuery.extend(true, {}, oCache.lastJson);
outJson.aaData = jQuery.merge(outJson.aaData, json.aaData);
oCache.lastJson = jQuery.extend(true, {}, outJson);
oCache.iCacheLength = oCache.iCacheLength + json.aaData.length;
fnCallback(outJson);
oCache.iLock = false;
});
}
}
});
jQuery.getJSON(sSource + "?iLimit=0,30", aoData, function(json) {
oCache.lastJson = jQuery.extend(true, {}, json);
oCache.iCacheLength = oCache.iCacheLength + json.aaData.length;
fnCallback(json)
});
}
[/code]
PROBLEM
If I understand correctly, alway then i update aaData array the DataTable is redrawn. So if i scroll a lot the aaData gets bigger and bigger (table redraw is longer and longer with every scroll). Is it somehow possible to not redraw existent rows and add only new (not redraw all table)?
Or maybe there is some better solution to accomplish such functionality?
This discussion has been closed.
Replies
some:html
[code]
Col 1
Col 2
Col 3
initTable('#DATATABLE');
updateDataTable();
[/code]
some.js
[code]
function initTable(selector) {
oTable = jQuery(selector).dataTable({
"bPaginate" : false
});
}
var oLoadParams = {
iDataStart: 0,
iDataLength: 100,
iLock: false
};
jQuery(window).scroll(function(){
if (!oLoadParams.iLock) {
if (jQuery(window).scrollTop() == jQuery(document).height() - jQuery(window).height()) {
oLoadParams.iLock = true;
updateDataTable();
}
}
});
function updateDataTable() {
jQuery.getJSON("datatable/some.json"+ "?iLimit=" + oLoadParams.iDataStart + "," + oLoadParams.iDataLength, function(json) {
oTable.fnAddData(json.aaData);
oLoadParams.iDataStart = oLoadParams.iDataStart + json.aaData.length;
oLoadParams.iLock = false;
oLoadParams.iDataLength= 10;
});
}
[/code]
Wow - that is absolutely superb! Nice one :-)
I felt thoroughly inspired by your work here, so I've put together a new demo which shows off this ability, but make it scrolling within a div element, rather than relative to the window: http://datatables.net/examples/api/infinite_scroll.html . What do you think?
There is one thing that isn't clear to me about infinite scrolling in a table - when you do filtering or sorting, DataTables can only act on the sub-set of data that it currently has. Do you have any ideas how this might be over come? The only thing I can think of off the top of my head, is to use server-side processing, and when filtering or sorting does occur, then clear what have currently been loaded, and start afresh... My example doesn't do that - it's client-side based.
Regards,
Allan
My thoughts about filtering and sorting are same as yours at the moment. And if some nice solution will born to over come it, be ready for new post from me.
And that about server side? Then i use [code]"bServerSide": true[/code] all table is redrawn, and the problem from first post occurs for me. Maybe I'm trying to implement wrong solution with server side processing... hm.
Regards,
Allan
Patch contains such lines (marked as PATCH or PATCH START/END):
classSettings function:
[code]
this.fnRecordsTotal = function ()
{
if ( this.oFeatures.bServerSide ) {
// PATCH START
if (this.oFeatures.bServerSideInfinitie) {
return this.aiDisplayMaster.length;
} else {
return this._iRecordsTotal;
}
// PATCH END
} else {
return this.aiDisplayMaster.length;
}
};
this.fnRecordsDisplay = function ()
{
if ( this.oFeatures.bServerSide ) {
// PATCH START
if (this.oFeatures.bServerSideInfinitie) {
return this.aiDisplay.length;
} else {
return this._iRecordsDisplay;
}
// PATCH END
} else {
return this.aiDisplay.length;
}
};
this.fnDisplayEnd = function ()
{
if ( this.oFeatures.bServerSide ) {
return this._iDisplayStart + this.aiDisplay.length;
} else {
return this._iDisplayEnd;
}
};
[/code]
[code]
/*
* Variable: oFeatures
* Purpose: Indicate the enablement of key dataTable features
* Scope: jQuery.dataTable.classSettings
*/
this.oFeatures = {
"bPaginate": true,
"bLengthChange": true,
"bFilter": true,
"bSort": true,
"bInfo": true,
"bAutoWidth": true,
"bProcessing": false,
"bSortClasses": true,
"bStateSave": false,
"bServerSide": false,
"bServerSideInfinitie": false // PATCH
};
[/code]
Look next post >>>
[code]
/* Rebuild the search */
_fnBuildSearchArray( oSettings, 1 );
if ( typeof bRedraw == 'undefined' || bRedraw )
{
// PATCH START
if (oSettings.oFeatures.bServerSideInfinitie) {
_fnDrawWithNoAjaxUpdate( oSettings );
} else {
_fnDraw( oSettings );
}
// PATCH END
}
return aiReturn;
[/code]
Before _fnDraw function:
[code]
// PATCH START
function _fnDrawWithNoAjaxUpdate( oSettings )
{
oSettings._ajaxUpdate = false;
_fnDraw( oSettings );
}
// PATCH END
/*
* Function: _fnDraw
* Purpose: Insert the required TR nodes into the table for display
* Returns: -
* Inputs: object:oSettings - dataTables settings object
*/
function _fnDraw( oSettings )
{
var i, iLen;
var anRows = [];
var iRowCount = 0;
var bRowError = false;
var iStrips = oSettings.asStripClasses.length;
var iOpenRows = oSettings.aoOpenRows.length;
// PATCH START
var checkAjax = true;
if (oSettings._ajaxUpdate != null) {
if (!oSettings._ajaxUpdate) {
checkAjax = false;
}
}
/* If we are dealing with Ajax - do it here */
if ( oSettings.oFeatures.bServerSide && checkAjax &&
!_fnAjaxUpdate( oSettings ) )
{
return;
}
oSettings._ajaxUpdate = true;
// PATCH END
/* Check and see if we have an initial draw position from state saving */
if ( typeof oSettings.iInitDisplayStart != 'undefined' && oSettings.iInitDisplayStart != -1 )
{
...
[/code]
Map flag to oSettings:
[code]
_fnMap( oSettings.oFeatures, oInit, "bPaginate" );
_fnMap( oSettings.oFeatures, oInit, "bLengthChange" );
_fnMap( oSettings.oFeatures, oInit, "bFilter" );
_fnMap( oSettings.oFeatures, oInit, "bSort" );
_fnMap( oSettings.oFeatures, oInit, "bInfo" );
_fnMap( oSettings.oFeatures, oInit, "bProcessing" );
_fnMap( oSettings.oFeatures, oInit, "bAutoWidth" );
_fnMap( oSettings.oFeatures, oInit, "bSortClasses" );
_fnMap( oSettings.oFeatures, oInit, "bServerSide" );
_fnMap( oSettings.oFeatures, oInit, "bServerSideInfinitie" ); // PATCH
_fnMap( oSettings, oInit, "asStripClasses" );
_fnMap( oSettings, oInit, "fnRowCallback" );
_fnMap( oSettings, oInit, "fnHeaderCallback" );
_fnMap( oSettings, oInit, "fnFooterCallback" );
_fnMap( oSettings, oInit, "fnInitComplete" );
_fnMap( oSettings, oInit, "fnServerData" );
_fnMap( oSettings, oInit, "aaSorting" );
_fnMap( oSettings, oInit, "aaSortingFixed" );
_fnMap( oSettings, oInit, "sPaginationType" );
_fnMap( oSettings, oInit, "sAjaxSource" );
_fnMap( oSettings, oInit, "iCookieDuration" );
_fnMap( oSettings, oInit, "sDom" );
_fnMap( oSettings, oInit, "oSearch", "oPreviousSearch" );
_fnMap( oSettings, oInit, "aoSearchCols", "aoPreSearchCols" );
_fnMap( oSettings, oInit, "iDisplayLength", "_iDisplayLength" );
_fnMap( oSettings, oInit, "bJQueryUI", "bJUI" );
[/code]
P.S.
This is a quick patch without deep understanding of how DataTables works. Maybe it is better way to do this. Pease :)
Just want to update the actual support for infinite scroll + server side processing. Is there any new feature-support in Datatables for this purpose?
http://datatables.net/forums/comments.php?DiscussionID=2674
:)