Search code examples
javascriptjquery-pluginsdatatablestapestry

Calling fnStandingRedraw to retain the current pagination settings in Datatables using javaScriptSupport.addInitializerCall


I am using the CreateEventLink method of the ComponentResources class to create a link to a delete event on my page called UserList using the following:

resources.createEventLink("delete", user.getUserId()).toURI();

The UserList page uses datatables to create a list of user's data and a delete link. When the delete link is clicked, the delete event is called on the same page and everyone is happy.

The problem is the datatable goes back to the first page of records after a user is deleted. For example, if I am on page 5 of my datatable, on the UserList page, and I click delete it will stay on the Userlist page, but my datatable will reset itself to the first page.

After some research I haved discovered that the fnStandingRedraw plugin from datatables will fix this issue: http://datatables.net/plug-ins/api

Going through the documentation I have learned that I should use:

 javaScriptSupport.addInitializerCall("fnStandingRedraw", ""); 

to call the following in js file via an Import notation:

Tapestry.Initializer.fnStandingRedraw = function(oSettings) { 
    //redraw to account for filtering and sorting 
    // concept here is that (for client side) there is a row got inserted at the end (for an add) 
    // or when a record was modified it could be in the middle of the table 
    // that is probably not supposed to be there - due to filtering / sorting 
    // so we need to re process filtering and sorting 
    // BUT - if it is server side - then this should be handled by the server - so skip this step 
    if(oSettings.oFeatures.bServerSide === false){ 
        var before = oSettings._iDisplayStart; 
        oSettings.oApi._fnReDraw(oSettings); 
        //iDisplayStart has been reset to zero - so lets change it back 
        oSettings._iDisplayStart = before; 
        oSettings.oApi._fnCalculateEnd(oSettings); 
    } 

    //draw the 'current' page 
    oSettings.oApi._fnDraw(oSettings); 
}; 

However I get the error:

Uncaught TypeError: Cannot read property 'bServerSide' of undefined 
Tapestry.Initializer.fnStandingRedrawhelpdesk.js:16 
$.extend.inittapestry-jquery.js:32 
jQuery.extend.eachjquery-1.6.2.js:655 
$.extend.inittapestry-jquery.js:26 
jQuery.extend.eachjquery-1.6.2.js:649 
$.extend.inittapestry-jquery.js:18 
(anonymous function)list:70 
jQuery.extend._Deferred.deferred.resolveWithjquery-1.6.2.js:1008 
jQuery.extend.readyjquery-1.6.2.js:436 
DOMContentLoadedjquery-1.6.2.js:915 

Any guidance would be most appreciated...Thanks in advance!!


Solution

  • The best practice is to save DataTables plugin to separate js file, so you can use it not only through tapestry initializer but also from other js.:

    (function($) {
        $.fn.dataTableExt.oApi.fnStandingRedraw = function(oSettings) {
            if(oSettings.oFeatures.bServerSide === false){
                var before = oSettings._iDisplayStart;
    
                oSettings.oApi._fnReDraw(oSettings);
    
                // iDisplayStart has been reset to zero - so lets change it back
                oSettings._iDisplayStart = before;
                oSettings.oApi._fnCalculateEnd(oSettings);
            }
    
            // draw the 'current' page
            oSettings.oApi._fnDraw(oSettings);
        };
    })(window.jQuery);
    

    So you can use it from other places as:

    var oTable = $('.dataTable').dataTable();
    oTable.fnStandingRedraw();
    

    To call fnStandingRedraw() from tapestry:

    jsSupport.addScript("$(%s).dataTable().fnStandingRedraw()", "#myTable");
    

    or you can add tapestry initializer and call it:

    Tapestry.Initializer.standingRedraw = function(spec) { 
        $(spec.tableId).dataTable().fnStandingRedraw();
    }; 
    

    in java:

    jsSupport.addInitializerCall("standingRedraw", 
        new JSONObject("tableId", "#myTable"));
    

    But this will work for you only if your DataTable is client-side(pagination, sorting, filtering) and you do ajax request to delete row and delete this row from DataTable manually from js.