web-dev-qa-db-ja.com

DataTables:カスタム応答処理

AngularJSDataTables の作業を開始し、DataTablesが期待する応答をカスタマイズできるかどうか疑問に思いました。 DataTablesプラグインの現在の期待は次のようなものです。

{
    "draw": 1,
    "recordsTotal": 57,
    "recordsFiltered": 5,
    "data": [...]
}

サーバー側では、APIは Django-tastypie

サーバーからの応答は次のとおりです。

{
     meta: {
        limit: 20,
        next: null,
        offset: 0,
        previous: null,
        total_count: 2
     },

     objects: [...]
 }

それで、この応答を受け入れる/マップするためにDatatablesプラグインを微調整する方法はありますか、それともAPIに期待されるフィールドを追加する方法を見つける必要がありますか?

これまで私はこれを行いました:

    var deptTable = angular.element('#deptManagementTable').DataTable({
        processing: true,
        serverSide: true,
        pagingType: "simple_numbers",
        ajax: {
            url: "/client/api/v1/departments/",
            data: function(d) {
                d.limit = d.length;
                d.offset = d.start;
                d.dept_name__icontains = d.search.value;
            },
            dataSrc: function(json) {
                for (var i=0, len=json.objects.length ; i<len ; i++) {
                    json.objects[i].DT_RowId = json.objects[i].dept_id;
                }
                return json.objects;
            }
        },
        aLengthMenu: [
            [5, 25, 50, 100],
            [5, 25, 50, 100]
        ],
        iDisplayLength: 5,
        columns: [
            {
                data: "dept_name"
            },
            {
                data: "dept_created_on",
                render: function ( data, type, full, meta ) {
                    var dateCreated = new Date(data);
                    dateCreated = dateCreated.toLocaleDateString();
                    return dateCreated;
                }
            }
        ]
    });

どんな助けでもありがたいです。

前もって感謝します :)

16
Ankit Popli

関数をDataTablesに渡すことができます ajax option これにより、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
            });
        });
    }
});
_

上記のソリューションは、jQuery DataTables 1.10.4でテストされています。


この質問はAngularでタグ付けされているため、 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
    ];
});
_

上記のソリューションは、angular-datatables 0.3.0 + DataTables1.10.4でテストされています。

¹ここで注意すべき重要な部分は、angular-datatablesソリューションが機能するには.withDataProp('data')が必要ですが、純粋なjQuery DataTablesソリューションには_data: 'data'_オプションがないことです。

24

この回答は非常に役に立ちましたが、現在の(現時点では1.10.12)バージョンのdatatablesのコンテキストでは少し時代遅れのようです。これにより、実際には作業がはるかに簡単になります(または少なくとも読みやすくなります)。

現在のバージョンでは、宣言で次のようなことを行うことができます(tastypieでは、使用するフィールドにフィルター可能および順序付けオプションを設定する必要があることに注意してください)。

関数内でdata.attrを実行することにより、ajaxリクエストで送信されているデータにアクセスできるようになりました。

これは、検索を1つのフィールドに制限したいことを前提としていますが、ajax関数内でconsole.log(data)を実行して何が送信されるかを確認するのと同じ方法で、簡単に拡張できます。

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"]]
});
2
Keith Bailey