【问题标题】:Ajaxed Datatable: POST filter parameters on shorting/pagination eventAjaxed 数据表:关于短路/分页事件的 POST 过滤器参数
【发布时间】:2025-12-30 16:30:11
【问题描述】:

我已经实现了 Ajaxed Datatable 来表示分页表中的大约 5000 行。

一切正常,直到不应用过滤。对于未过滤的数据,我可以缩短列和分页工作。

有一次,我在某个字段上应用了shorting,假设我写了手机号码90331,那么它应该输出所有以90331开头的手机号码的记录,SQL按预期工作。搜索结果大约有 2500 行,根据分页设置,它提供前 20 行。 但是只要我点击下一页按钮,它就会触发分页事件并发送没有“过滤参数”的 ajax 请求。因此,由于不是在 ajax 请求上发送过滤参数,因此它不会过滤并且它会丢失过滤后的数据状态并返回包含所有数据的第二页(不过滤)。如果我单击列标题进行排序,也会发生同样的情况。

问题

如何使 Datatable 发送过滤参数值以及诸如排序和分页之类的事件?

下面是代码:

HTML

<table class="table table-striped table-bordered table-hover ajax-table">
    <thead>
        <tr role="row" class="heading">
            <th>Index</th>
            <th>Name</th>
            <th>Email</th>
            <th>Mobile</th>
            <th>Actions</th>
        </tr>
        <tr role="row" class="filter"> <!-- Custom filters here -->
            <td></td>
            <td>
                <input type="text" class="form-control form-filter input-sm" name="cust_name" placeholder="Name">
            </td>
            <td>
                <input type="text" class="form-control form-filter input-sm" name="cust_email" placeholder="Email">
            </td>
            <td>
                <input type="text" class="form-control form-filter input-sm" name="cust_mobile" placeholder="Mobile">
            </td>
            <td>
                <button class="btn btn-sm yellow filter-submit margin-bottom"><i class="fa fa-search"></i> Search</button>
            </td>                                       
        </tr>
    </thead>
    <tbody>

    </tbody>
</table>

JavaScript

grid = new Datatable();
grid.init({
    src: $(".ajax-table"),
    onSuccess: function(grid) {
        // execute some code after table records loaded
    },
    onError: function(grid) {
        // execute some code on network or other general error  
    },
    dataTable: {  // here you can define a typical datatable settings from http://datatables.net/usage/options 
        "aLengthMenu": [
            [20, 50, 100, 150, 200],
            [20, 50, 100, 150, 200] 
        ],
        "oLanguage": {  // language settings
            "sProcessing": '<img src="assets/img/loading-spinner-grey.gif"/><span>&nbsp;&nbsp;Loading...</span>',
        },
        "iDisplayLength": 50, // default record count per page
        "bServerSide": true, // server side processing
        "sAjaxSource": "ajax/customers_ajax.php", // ajax source to retrive customer details
        "aaSorting": [[ 1, "asc" ]], // set first column as a default sort by asc
        "aoColumns": [
                      { "sName": "id","bSortable":false,"sWidth":"5%"},
                      { "sName": "cust_name" ,"sWidth":"10%"},
                      { "sName": "cust_email" },
                      { "sName": "cust_mobile","sWidth":"10%"},
                      { "sName": "Action","bSortable":false }
                  ]
    }
});

PHP(Ajax 源代码)

//Identifying column to short on
$columns=explode(",",$_POST['sColumns']); 
$sortCol=$_POST['iSortCol_0'];
$sortOrder=$_POST['sSortDir_0'];
$table="tblcustomer";
$records = array ();

if (isset ( $_REQUEST ["sAction"] ) && $_REQUEST ["sAction"] == "filter") {
    //Counting "TOTAL" number of rows, that can be returned for given "filters"
    $query = "select count(*) total from $table
            where cust_status>-1 ";
    if (!empty( $_REQUEST ['cust_name'] )) {
        $query .= "and cust_name like :cust_name ";
    }
    if (!empty( $_REQUEST ['cust_mobile'] )) {
        $query .= "and cust_mobile like :cust_mobile ";
    }
    if (!empty( $_REQUEST ['cust_email'] )) {
        $query .= "and cust_email like :cust_email ";
    }

    $query = $con->prepare ( $query );

    if (!empty( $_REQUEST ['cust_name'] )) {
        $query->bindValue ( ":cust_name", $_REQUEST ['cust_name'] . "%" );
    }
    if (!empty( $_REQUEST ['cust_mobile'] )) {
        $query->bindValue ( ":cust_mobile", "%".$_REQUEST ['cust_mobile'] . "%" );
    }
    if (!empty( $_REQUEST ['cust_email'] )) {
        $query->bindValue ( ":cust_email", "%".$_REQUEST ['cust_email'] . "%" );
    }
} else {
    //Counting "TOTAL" number of rows in a table --- For non-filter action
    $query = $con->prepare ( "select count(*) total from $table
            where cust_status>-1 " );
}

$query->execute ();
$row = $query->fetch ( PDO::FETCH_ASSOC );

$iTotalRecords = $row ['total'];

$iDisplayLength = intval ( $_REQUEST ['iDisplayLength'] );
$iDisplayLength = $iDisplayLength < 0 ? $iTotalRecords : $iDisplayLength;
$iDisplayStart = intval ( $_REQUEST ['iDisplayStart'] );
$sEcho = intval ( $_REQUEST ['sEcho'] );

$records ["aaData"] = array (); //actual data for Datatable rows.

if (isset ( $_REQUEST ["sAction"] ) && $_REQUEST ["sAction"] == "filter") {
    //Fetching Filtered data
    $query = "SELECT `id`, `cust_name`, `cust_mobile`, `cust_email`
            FROM $table 
            WHERE cust_status>-1 ";
    if (!empty( $_REQUEST ['cust_name'] )) {
        $query .= "and cust_name like :cust_name ";
    }
    if (!empty( $_REQUEST ['cust_mobile'] )) {
        $query .= "and cust_mobile like :cust_mobile ";
    }
    if (!empty( $_REQUEST ['cust_email'] )) {
        $query .= "and cust_email like :cust_email ";
    }
    $query .=" order by {$columns[$sortCol]} {$sortOrder}";
    $query .= " limit $iDisplayStart, $iDisplayLength";

    $query = $con->prepare ( $query );

    if (!empty( $_REQUEST ['cust_name'] )) {
        $query->bindValue ( ":cust_name", $_REQUEST ['cust_name'] . "%" );
    }
    if (!empty( $_REQUEST ['cust_mobile'] )) {
        $query->bindValue ( ":cust_mobile", "%".$_REQUEST ['cust_mobile'] . "%" );
    }
    if (!empty( $_REQUEST ['cust_email'] )) {
        $query->bindValue ( ":cust_email", "%".$_REQUEST ['cust_email'] . "%" );
    }

} else {
    $query = $con->prepare ( "SELECT `id`, `cust_name`, `cust_mobile`, `cust_email` 
            FROM $table`
            WHERE cust_status>-1
            order by {$columns[$sortCol]} {$sortOrder} 
            limit $iDisplayStart, $iDisplayLength" );
}
$query->execute ();

if ($query->rowCount () > 0) {
    while ( $row = $query->fetch ( PDO::FETCH_ASSOC ) ) {

        $edit="<button class='btn btn-warning btn-sm'>Edit</button>";
        $delete="<button class='btn btn-danger btn-sm'>Delete</button>";

        $records ["aaData"] [] = array (
                $row ['id'],
                $row ['cust_name'],
                $row ['cust_email'],
                $row ['cust_mobile'],
                "$edit $delete"
        );
    }
}

$records ["sEcho"] = $sEcho;
$records ["iTotalRecords"] = $iTotalRecords;
$records ["iTotalDisplayRecords"] = $iTotalRecords;
echo json_encode ( $records );

任何帮助/建议将不胜感激。

谢谢!

【问题讨论】:

  • 你的 Ajaxed Datatable 问题真的很大,几乎不可读......所以写的是自包含的例子
  • @NullPoiиteя,感谢您的关注。我已经包含了我已经实现的所有内容。主要的事情是过滤和分页,所以我也包含了 PHP 代码,这样其他人就可以知道我是如何使用参数的。问题是我无法访问参数。我已经按部分清楚地解释了所有内容。所以我猜它的格式正确且详细的问题!
  • * 是一个问题应该对未来的访问者有帮助的网站......在你的情况下我发现不是......
  • 绑定值语句中好像少了单引号
  • @RamRaider 感谢您的评论。但它在没有单引号的情况下工作,PDO 在绑定时完成这项工作。 :)

标签: php ajax datatable pagination datatables


【解决方案1】:

终于解决了!

使用fnServerParams添加自定义过滤器参数如下:

"fnServerParams": function ( aoData ) {
    //here can be added an external ajax request parameters.
    $('textarea.form-filter, select.form-filter, input.form-filter:not([type="radio"],[type="checkbox"])', table).each(function(){
        aoData.push({"name" : $(this).attr("name"), "value": $(this).val()});
    });
}

它将为每个 ajax 请求(分页、排序、过滤等)添加自定义参数。因此,每次它都会在后端处理中使用它进行过滤。

希望它对某人有用!

【讨论】: