Skip to content

Manually load update datatable data without calling ajax

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.

Answer

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);