1

I'm trying to avoid making two ajax calls by using .ajax.params() to get the last set of ajax parameters and returning the table data from my first call.

I then pass in my own json to datatables following this pattern

datatable.clear();
datatable.rows.add(newDataArray);
datatable.draw();

from this question.

However my table has ajax set so when draw() is called another ajax call is fired which defeats the point of passing in the data myself. What I need is a way to suppress the ajax call while redrawing the table.

An alternative would be to write my own ajax handling and manually add the data into datatables as above, however I think I would also have to create the ajax parameters myself which would be a pain.

Community
  • 1
  • 1
Edward Louth
  • 1,010
  • 2
  • 9
  • 19
  • Why do you want to have an ajax sourced table but then manually load rows into it? Why not stick with one approach or the other? – Brian Kates Jul 27 '16 at 14:32
  • When certain events happen I make an ajax call to update data on the server side, sometimes these alter the data behind the table. Currently when this ajax call returns it then tells the datatable to redraw, however this uses another ajax call which I would like to avoid. – Edward Louth Jul 27 '16 at 15:27
  • Maybe I am going about this the wrong way, instead of loading the data from another ajax call I could change the datatables call with table.ajax.url and add extra parameters using ajax.data (not sure how to set this after initialisation). The question then becomes how to cancel the redraw based on the returned json. – Edward Louth Jul 27 '16 at 15:42
  • My suggestion would be to stick to the basics and not over-complicate things. If you're needing to write custom ajax handling, etc, you're probably looking at the problem the wrong way. – Brian Kates Jul 27 '16 at 16:11
  • So I've got it working with my second method however it is rather hacky as I set `ajax.data` at initialisation and then test to see if I'm actually trying to do a more complex data call. Will have a look into how `ajax.url` works to see if I can write something similar for `ajax.data`. – Edward Louth Jul 27 '16 at 17:07

2 Answers2

1

I have created the following datatables plugin that makes it possible to do an ajax load with custom ajax settings for just one time.

var __reload = function ( settings, holdPosition, callback ) {
    // Use the draw event to trigger a callback
    if ( callback ) {
        var api = new _Api( settings );

        api.one( 'draw', function () {
            callback( api.ajax.json() );
        } );
    }

    if ( settings.oApi._fnDataSource( settings ) == 'ssp' ) {
        settings.oApi._fnReDraw( settings, holdPosition );
    }
    else {
        settings.oApi._fnProcessingDisplay( settings, true );

        // Cancel an existing request
        var xhr = settings.jqXHR;
        if ( xhr && xhr.readyState !== 4 ) {
            xhr.abort();
        }

        // Trigger xhr
        settings.oApi._fnBuildAjax( settings, [], function( json ) {
            settings.oApi._fnClearTable( settings );

            var data = settings.oApi._fnAjaxDataSrc( settings, json );
            for ( var i=0, ien=data.length ; i<ien ; i++ ) {
                settings.oApi._fnAddData( settings, data[i] );
            }

            settings.oApi._fnReDraw( settings, holdPosition );
            settings.oApi._fnProcessingDisplay( settings, false );
        } );
    }
};

jQuery.fn.dataTable.Api.register( 'ajax.loadOnce()', function ( ajax, callback, resetPaging ) {
    return this.iterator( 'table', function ( ctx ) {
        store = ctx.ajax;
        ctx.ajax = ajax;
        __reload( ctx, resetPaging===false, callback );
        ctx.ajax = store;
    } );
} );

This makes it possible to combine the datatables parameters with custom data and a new url as such

ajax = {
    url: url,
    data: function (d){                    
        d.value = value;
    }
};

table.ajax.loadOnce(ajax);
Edward Louth
  • 1,010
  • 2
  • 9
  • 19
0

I had a similar issue. The easiest work around I found was temporarily disabling the AJAX and server side processing, make your changes, and then reset the values like shown below:

function set_datatable_ajax_processing(table, bool) {
table.settings()[0].oFeatures.bServerSide = bool;
table.settings()[0].ajax = bool;
}

set_datatable_ajax_processing(table, false)
// table edits and/or draw done here ...      
set_datatable_ajax_processing(table, true)
David Buck
  • 3,752
  • 35
  • 31
  • 35