DataTables: Custom Response Handling DataTables: Custom Response Handling ajax ajax

DataTables: Custom Response Handling


You can pass a function to the DataTables ajax option, this will give you full control over how to fetch and map the data before passing it to DataTables.

.DataTable({    serverSide: true,    ajax: function(data, callback, settings) {        // make a regular ajax request using data.start and data.length        $.get('/client/api/v1/departments/', {            limit: data.length,            offset: data.start,            dept_name__icontains: data.search.value        }, function(res) {            // map your server's response to the DataTables format and pass it to            // DataTables' callback            callback({                recordsTotal: res.meta.total_count,                recordsFiltered: res.meta.total_count,                data: res.objects            });        });    }});

The solution above has been tested with jQuery DataTables 1.10.4.


As this question is tagged with Angular, here's a solution for those using angular-datatables.

<div ng-controller="testCtrl">    <table datatable dt-options="dtOptions" dt-columns="dtColumns" class="row-border hover"></table></div>

.controller('testCtrl', function($scope, $http, DTOptionsBuilder, DTColumnBuilder) {    $scope.dtOptions = DTOptionsBuilder.newOptions()        .withOption('serverSide', true)        .withOption('ajax', function(data, callback, settings) {            // make an ajax request using data.start and data.length            $http.get('/client/api/v1/departments/', {                limit: data.length,                offset: data.start,                dept_name__icontains: data.search.value            }).success(function(res) {                // map your server's response to the DataTables format and pass it to                // DataTables' callback                callback({                    recordsTotal: res.meta.total_count,                    recordsFiltered: res.meta.total_count,                    data: res.objects                });            });        })        .withDataProp('data'); // IMPORTANT¹    $scope.dtColumns = [        // your column definitions here    ];});

The solution above has been tested with angular-datatables 0.3.0 + DataTables 1.10.4.

¹ The important part to note here is that the angular-datatables solution requires .withDataProp('data') to work, while the pure jQuery DataTables solution does not have a data: 'data' option.


This answer was very useful, but seems a bit outdated in the context of the current (1.10.12 at the moment) version of datatables, which actually makes life a lot easier (or at least more readable).

Under the current version you can do something like the following in your declaration (bearing in mind that tastypie needs to have the filterable & ordering options set for the fields you want to use).

You can now access the data being submitted in the ajax request by doing data.attr inside the function.

This assumes you wish to restrict searching to one field, but can easily be extended in the same manner do console.log(data) within the ajax function to see what is sent.

var table = $('#tableName').DataTable({    "deferRender":true,    "serverSide": true,    "ajax": function(data, callback, settings) {        var sort_column_name = data.columns[data.order[0].column].data.replace(/\./g,"__");        var direction = "";        if (data.order[0].dir == "desc") { direction = "-"};        $.get('your/tasty/pie/url?format=json', {            limit: data.length,            offset: data.start,            your_search_field__searchattr: data.search.value,            order_by: direction +sort_column_name        }, function(res) {            callback({                recordsTotal: res.meta.total_count,                recordsFiltered: res.meta.total_count,                data: res.objects            });        });    },    "columns": [        { "data":"column_1", "orderable": false },        { "data":"column_2" },        { "data":"column_3" }    ],    "order": [[1, "asc"]]});