Javascript 单击按钮时,如何触发 jquery 数据表 fnServerData 以通过 AJAX 更新表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11566463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:21:24  来源:igfitidea点击:

how can I trigger jquery datatables fnServerData to update a table via AJAX when I click a button?

javascriptjqueryajaxtriggersdatatables

提问by frequent

I'm using the datatables plugin with server-side data and am updating the table using AJAX.

我正在使用带有服务器端数据的数据表插件,并使用 AJAX 更新表。

My dataTables setup looks like this:

我的数据表设置如下所示:

tblOrders = parameters.table.dataTable( {
    "sDom": '<"S"f>t<"E"lp>',
    "sAjaxSource": "../file.cfc",
    "bServerSide": true,
    "sPaginationType": "full_numbers",  
    "bPaginate": true,
    "bRetrieve": true,
    "bLengthChange": false,         
    "bAutoWidth": false,
    "aaSorting": [[ 10, "desc" ]],      
    "aoColumns": [                      
        ... columns 
                  ],
    "fnInitComplete": function(oSettings, json) {
        // trying to listen for updates
        $(window).on('repaint_orders', function(){
            $('.tbl_orders').fnServerData( sSource, aoData, fnCallback, oSettings );
            });
        },
    "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) {
        var page = $(oSettings.nTable).closest('div:jqmData(wrapper="true")')
        aoData.push(
            { "name": "returnformat", "value": "plain"},
            { "name": "s_status", "value": page.find('input[name="s_status"]').val() },
            { "name": "s_bestellnr", "value": page.find('input[name="s_bestellnr"]').val() },
            { "name": "form_submitted", "value": "dynaTable" }
            );
        $.ajax({ "dataType": 'json', "type": "POST", "url": sSource, "data": aoData , "success": fnCallback });
        }

I have some custom fields for filtering the data server-side, which i'm pushing along with the AJAX request. The problem is, I don't know how to trigger a JSON request from outside of the table. If the user types into the filter, fnServerData fires and updates the table. However, if the user picks a control outside of the table, I have no idea how to trigger the fnServerDatafunction.

我有一些用于过滤数据服务器端的自定义字段,我将其与 AJAX 请求一起推送。问题是,我不知道如何从表外部触发 JSON 请求。如果用户输入过滤器,fnServerData 会触发并更新表。但是,如果用户选择表外的控件,我不知道如何触发fnServerData函数。

Right now I'm trying with a custom event I'm firing and listening to in fnInitComplete. While I can detect the user picking a custom filtering criteria, I'm missing all parameters needed for fnServerData to trigger correctly.

现在我正在尝试在 fnInitComplete 中触发和监听一个自定义事件。虽然我可以检测到用户选择自定义过滤条件,但我缺少 fnServerData 正确触发所需的所有参数。

Question:
Is there a way to trigger fnServerData from a button outside of the actual dataTables table?

问题
有没有办法从实际 dataTables 表之外的按钮触发 fnServerData?

I guess I could try to add a space to the filter, but this is not really an option.

我想我可以尝试在过滤器中添加一个空格,但这不是一个真正的选择。

Thanks for input!

感谢您的输入!

Question

采纳答案by Drakkainen

I found this script some time ago (so I don't remember where it came from :( and who to credit for it :'( ) but here :

我前段时间发现了这个脚本(所以我不记得它是从哪里来的 :( 以及该归功于谁 :'( ) 但在这里:

$.fn.dataTableExt.oApi.fnReloadAjax = function (oSettings, sNewSource, fnCallback, bStandingRedraw) {
    if (typeof sNewSource != 'undefined' && sNewSource != null) {
        oSettings.sAjaxSource = sNewSource;
    }
    this.oApi._fnProcessingDisplay(oSettings, true);
    var that = this;
    var iStart = oSettings._iDisplayStart;
    var aData = [];

    this.oApi._fnServerParams(oSettings, aData);

    oSettings.fnServerData(oSettings.sAjaxSource, aData, function (json) {
        /* Clear the old information from the table */
        that.oApi._fnClearTable(oSettings);

        /* Got the data - add it to the table */
        var aData = (oSettings.sAjaxDataProp !== "") ?
            that.oApi._fnGetObjectDataFn(oSettings.sAjaxDataProp)(json) : json;

        for (var i = 0; i < aData.length; i++) {
            that.oApi._fnAddData(oSettings, aData[i]);
        }

        oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
        that.fnDraw();

        if (typeof bStandingRedraw != 'undefined' && bStandingRedraw === true) {
            oSettings._iDisplayStart = iStart;
            that.fnDraw(false);
        }

        that.oApi._fnProcessingDisplay(oSettings, false);

        /* Callback user function - for event handlers etc */
        if (typeof fnCallback == 'function' && fnCallback != null) {
            fnCallback(oSettings);
        }
    }, oSettings);
}

Add that BEFOREyou call the datatable initialization function. then you can just call the reload like this:

调用数据表初始化函数之前添加。那么你可以像这样调用重新加载:

$("#userFilter").on("change", function () {
        oTable.fnReloadAjax(); // In your case this would be 'tblOrders.fnReloadAjax();'
    });

userFilteris an ID for a dropdown, so when it changes, it reloads the data for the table. I just added this as an example but you can trigger it on any event.

userFilter是下拉列表的 ID,因此当它更改时,它会重新加载表的数据。我只是将其添加为示例,但您可以在任何事件上触发它。

回答by Chuck

From a discussion here, Allan (the DataTables guy) suggests that simply calling fnDraw will yield the results you're looking for. This is the method I use for reloading server-side stuff (via fnServerData, which is important), and it's worked so far.

这里的讨论中,Allan(DataTables 的人)建议简单地调用 fnDraw 将产生您正在寻找的结果。这是我用于重新加载服务器端内容的方法(通过 fnServerData,这很重要),到目前为止它已经奏效。

$("#userFilter").on("change", function() {
    oTable.fnDraw();  // In your case this would be 'tblOrders.fnDraw();'
});

回答by Mitja Gustin

All the solutions mentioned before have some problem (for example, the additional user http paramaters are not posted or are stale). So I came up with following solution that works well.

前面提到的所有解决方案都有一些问题(例如,额外的用户 http 参数没有发布或陈旧)。所以我想出了以下效果很好的解决方案。

Extension function (My params are array of key value pairs)

扩展函数(我的参数是键值对数组)

<pre>
$.fn.dataTableExt.oApi.fnReloadAjax = function (oSettings, sNewSource, myParams ) {
if ( oSettings.oFeatures.bServerSide ) {
    oSettings.aoServerParams = [];
    oSettings.aoServerParams.push({"sName": "user",
        "fn": function (aoData) {
            for (var i=0;i<myParams.length;i++){
            aoData.push( {"name" : myParams[i][0], "value" : myParams[i][1]});
         }
     }});
     this.fnClearTable(oSettings);
     this.fnDraw();
     return;
    }
};
</pre>

Example usage to put in you refresh event listener.

用于放入刷新事件侦听器的示例用法。

<pre>
oTable.fnReloadAjax(oTable.oSettings, supplier, val);
</pre>

Just one thing to pay attention to. Do not redraw table, once it's created, beacuse it's time consuming. Therefore, be sure to draw it only the first time. Otherwise, reload it

只需要注意一件事。不要重绘表格,一旦它被创建,因为它很耗时。因此,请务必仅在第一次绘制它。否则,重新加载它

<pre>
var oTable;
if (oTable == null) {
    oTable = $(".items").dataTable(/* your inti stuff here */); {
}else{
    oTable.fnReloadAjax(oTable.oSettings, supplier, val);
}
</pre>

回答by laromicas

In the initialization use:

在初始化中使用:

"fnServerData": function ( sSource, aoData, fnCallback ) {
                    //* Add some extra data to the sender *
                    newData = aoData;
                    newData.push({ "name": "key", "value": $('#value').val() });

                    $.getJSON( sSource, newData, function (json) {
                        //* Do whatever additional processing you want on the callback, then tell DataTables *
                        fnCallback(json);
                    } );
                },

And then just use:

然后只需使用:

$("#table_id").dataTable().fnDraw();

The important thing in the fnServerData is:

fnServerData 中重要的是:

    newData = aoData;
    newData.push({ "name": "key", "value": $('#value').val() });

if you push directly to aoData, the change is permanent the first time and when you draw the table again the fnDraw don't work the way you want. So, use a copy of aoData to push data to the ajax.

如果您直接推送到 aoData,第一次更改是永久性的,当您再次绘制表格时,fnDraw 不会按照您想要的方式工作。因此,使用 aoData 的副本将数据推送到 ajax。

回答by random_user_name

I know this is late to the game, but fnDraw(from this answer above- which should be the accepted answer), is deprecated as of v1.10

我知道这已经迟到了,但是fnDraw(从上面的这个答案- 这应该是公认的答案),从 v1.10 开始被弃用

The new method is:

新方法是:

this.api( true ).draw( true );

Which, BTW, has a comment that reads:

顺便说一句,其中有一条评论是:

// Note that this isn't an exact match to the old call to _fnDraw - it takes
// into account the new data, but can hold position.

回答by Brane

For reload of the data, simply you need to select the DataTable using jquery selector with DataTable()function and call _fnAjaxUpdatefunction.

要重新加载数据,您只需使用带有DataTable()函数和调用_fnAjaxUpdate函数的jquery 选择器来选择数据表。

Here is example:

这是示例:

$('#exampleDataTable').DataTable()._fnAjaxUpdate();

回答by Tomasz Majerski

Similar to Mitja Gustin answer. Changed a loop, added sNewSource.

类似于 Mitja Gustin 的回答。更改了一个循环,添加了 sNewSource。

$.fn.dataTableExt.oApi.fnReloadAjax = function (oSettings, sNewSource, myParams ) {
    if(oSettings.oFeatures.bServerSide) {
        if ( typeof sNewSource != 'undefined' && sNewSource != null ) {
            oSettings.sAjaxSource = sNewSource;
        }
        oSettings.aoServerParams = [];
        oSettings.aoServerParams.push({"sName": "user",
            "fn": function (aoData) {
                for(var index in myParams) {
                    aoData.push( { "name" : index, "value" : myParams[index] });
                }
            }
        });
        this.fnClearTable(oSettings);
        return;
    }
};

var myArray = {
    "key1": "value1",
    "key2": "value2"
};

var oTable = $("#myTable").dataTable();
oTable.fnReloadAjax(oTable.oSettings, myArray);