当按钮被点击时,更新datatables(JQuery)

8
我已经创建了一个简单的表单,并使用Datatables jQuery插件在其中显示一些数据。数据由返回JSON格式的php脚本(process.php)填充。在表单中,有一个按钮将文本框的值发送到process.php。问题是当点击按钮时,我无法使用process.php脚本接收到的新数据更新/更改datatable。
表单代码:
<form name="myform" id="myform" action="" method="POST">  
    <label for="id">Enter an id:</label>  
    <input type="text" name="txtId" id="txtId" value=""/> 
    <input type="button" id="btnSubmit" name="btnSubmit" value="Search"> 
</form>

<div id="results">
    <table class="display" id="example">
        <thead>
            <tr>
                <th>id</th>
                <th>Surname</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            <!-- data goes here -->
        </tbody>
    </table>
</div> 

为了创建datatable,我使用以下JQuery代码:
    $(document).ready(function() {
            var oTable = $('#example').dataTable( {
                "sPaginationType": "full_numbers",
                "iDisplayLength": 10,
                //"bServerSide": true,
                "sAjaxSource": "process.php"
            } );

        $("#btnSubmit").click(function(){
            $.ajax({  
                type: "POST",  
                url: "process.php",  
                data: 'txtId=' + $("txtId").val(),  
                success: function(result) {  
                    oTable.fnReloadAjax();
                    oTable.fnDraw();
                }  
            });
        });
    } );

process.php脚本(工作正常)如下:

<?php
$result="";
if (empty($_REQUEST["txtId"])) {    
    $result = '{"aaData":[["1","Surname1","Name1"]]}';
}
else {
    $result = '{"aaData":[["2","Surname2","Name2"]]}';
}
print $result;
?>

1
永远不要使用字符串函数创建JSON。PHP有json_encode()函数。在您的情况下,您可以使用echo json_encode(array('aaData' => array(array('1', 'Surname1', 'Name1')))); - ThiefMaster
是的,我知道json_encode()函数。上面的process.php脚本是出于简单的原因编写的。不管怎样,感谢你,ThiefMaster! - dimmat
5个回答

4

fnReloadAjax是你应该使用的(我相信它可能已经内置了重绘功能)。但问题是,虽然你进行了第二个.ajax调用,但该调用中的数据根本不与你的datatable相关联,并且永远不会绑定到它上面。

使用fnReloadAjax将发起与表格初始化中指定的相同的Ajax调用。所以,正如Stefan提到的,你需要在datatable设置中指定你的fnServerData参数(但删除Success参数,因为datatables已经默认假设了某些行)。然后仅仅让你的按钮调用fnReloadAjax()即可。

这是你最终代码应该看起来的样子:

$(document).ready(function() {
        var oTable = $('#example').dataTable( {
            "sPaginationType": "full_numbers",
            "iDisplayLength": 10,
            "sAjaxSource": "process.php",
            "fnServerData": function ( sSource, aoData, fnCallback ) {
                $.ajax( {
                    "dataType": 'json', 
                    "type": "POST", 
                    "url": sSource, 
                    "data": 'txtId=' + $("txtId").val(), 
                    "success": fnCallback
                } );
            }
        } );

    $("#btnSubmit").click(function(){ 
        oTable.fnReloadAjax();
    });
} );

1
这是一个很好的解释。因此,如果您不坚持使用POST将参数传递给脚本,则似乎甚至不需要使用fnServerData - 因为默认情况下将使用GET。 - Stefan
你的代码看起来没问题,但对我不起作用。我通过在加载datatables的脚本标签之后,在$(document).ready()函数之前添加fnReloadAjax()插件API代码(在http://www.datatables.net/plug-ins/api中找到)来解决了这个问题。我还将提交按钮的jquery代码更改为:
$("#btnSubmit").click(function(){ oTable.fnReloadAjax("process.php?txtId=" + $("txtId").val()); }); 谢谢!
- dimmat
太好了!如果您使用fnReloadAjax为按钮点击指定新的数据源,则不需要fnServerData。很高兴听到您已经解决了问题。 - mbeasley

3
最终,我找到了解决方案!我的JQuery代码中有两个问题:
  1. 我需要在加载datatables的脚本标签后、$(document).ready()语句前添加fnReloadAjax()代码。
  2. 我需要修改提交按钮的JQuery代码(不需要进行AJAX调用,只需要fnReloadAjax())。
感谢Stefan和mbeasley!!
现在的JQuery代码为:
//
// fnReloadAjax() code      
//
    $.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 );
    }


    $(document).ready(function() {

        var oTable = $('#example').dataTable( {
            "sPaginationType": "full_numbers",
            "iDisplayLength": 10,
            //"bServerSide": true,
            "sAjaxSource": "process.php"
        });

        $("#btnSubmit").click(function(){
            oTable.fnReloadAjax("process.php?txtId=" + $("txtId").val());
        });

    } );

1

如果您想使用ajax POST,设置datatable时似乎还应该指定fnServerDatahttp://datatables.net/ref#fnServerData

也有可能您不需要调用fnReloadAjax(),只需要调用fnDraw()即可。fnReloadAjax()是一个插件函数,因此我假设您之前已经加载了它。


似乎我没有加载fnReloadAjax()插件。我将插件的代码复制/粘贴到我的JQuery脚本开头,但什么也没发生。我会再试一次,并尝试使用fnServerData。谢谢Stefan! - dimmat
终于找到解决方案了!我的JQuery代码有两个问题。首先,我必须在加载datatables的<script>...</script>标签之后,并在$(document).ready()语句之前添加fnReloadAjax()代码。其次,我必须修改提交按钮的JQuery代码(不需要进行AJAX调用,只需要fnReloadAjax()即可)。再次感谢Stefan。干得好!! - dimmat
@dimmat:不用谢。所以除了不需要调用.ajax()之外,您是在说您也不需要指定fnServerData吗?(这种情况下,GET用于自动将您的“txtId”参数传递到您的脚本)。此外,我发现mbeasley的答案非常有启发性,也许它应该成为被接受的答案。 - Stefan
是的,确实如此。fnServerData 不是必要的!! :-) 我也相信 mbeasley 的答案会起作用。但是他的代码没有发生任何事情...我忘了提到我使用了 fnReloadAjax,就像这样:$("#btnSubmit").click(function(){ oTable.fnReloadAjax("process.php?txtId=" + $("txtId").val()); }); - dimmat

0

你可以使用。

otable.ajax.reload()


0
你也可以选择销毁表并重新创建它。
var oTable = null;

function reloadTable() {
    if (oTable) {
        oTable.fnDestroy();
    }

    oTable = $('#example').dataTable( {
        "sPaginationType": "full_numbers",
        "iDisplayLength": 10,
        //"bServerSide": true,
        "sAjaxSource": "process.php"
    } );
}

reloadTable();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接