Add data from server while scrolling

Add data from server while scrolling

dimegdimeg Posts: 9Questions: 0Answers: 0
edited March 2010 in General
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?

Replies

  • dimegdimeg Posts: 9Questions: 0Answers: 0
    edited March 2010
    OK. Done this with fnAddData and it seems to work nicely for me at this stage :). Another approaches?

    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]
  • allanallan Posts: 63,186Questions: 1Answers: 10,411 Site admin
    Hi dimeg,

    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
  • dimegdimeg Posts: 9Questions: 0Answers: 0
    edited March 2010
    Brilliant example Allan! Works like a charm :). Yeah.

    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.
  • allanallan Posts: 63,186Questions: 1Answers: 10,411 Site admin
    Good point... With server-side processing, whenever DataTables does a redraw, it will destroy the current table and draw in whatever if given back from the server - since it's always expecting new data... Which makes this that bit more difficult... This might require a small change to the server-side API, or possibly a modification to DataTables, something to flag that the old data should not be deleted. Requires a bit more thought I think...

    Regards,
    Allan
  • dimegdimeg Posts: 9Questions: 0Answers: 0
    edited March 2010
    Made some patch to DataTables not to render _fnAjaxUpdate if fnAddData is used. To work with such behavior I added [code]"bServerSideInfinitie": true[/code] flag.

    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 >>>
  • dimegdimeg Posts: 9Questions: 0Answers: 0
    edited March 2010
    fnAddData function:
    [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 :)
  • erramunerramun Posts: 12Questions: 0Answers: 0
    Hi all,

    Just want to update the actual support for infinite scroll + server side processing. Is there any new feature-support in Datatables for this purpose?
  • JerAndersonJerAnderson Posts: 3Questions: 0Answers: 0
    Any news on this topic? It would appear that the infinite scroll feature may handle this type of thing already, but I'm still unclear on whether only new rows are requested from the server as you scroll. What's the difference between the example allan references here and the other shown in the documentation?
  • dimegdimeg Posts: 9Questions: 0Answers: 0
    Found nice improvements for this issue here:

    http://datatables.net/forums/comments.php?DiscussionID=2674

    :)
This discussion has been closed.