如何将 DataTable 中的单个列搜索与服务器端处理一起使用?
Posted
技术标签:
【中文标题】如何将 DataTable 中的单个列搜索与服务器端处理一起使用?【英文标题】:How to use individual column searching in DataTable with server-side processing? 【发布时间】:2021-08-27 14:02:58 【问题描述】:我正在处理一个包含大量数据的项目。我已经使用服务器端处理来快速处理或加载数据。但是我的老板想在每一列中添加搜索,我尝试使用 multi filter 但数据没有改变。我该如何解决这个问题?
这是我从数据库中加载数据的表:
<table class="table table-bordered responsive nowrap" id="example" >
<thead>
<tr>
<th >No</th>
<th >Machine</th>
<th >Spec1</th>
<th >Spec2</th>
<th >Spec3</th>
<th >Spec4</th>
<th >Spec5</th>
<th >Spec6</th>
<th >Qty</th>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<th >No</th>
<th >Machine</th>
<th >Spec1</th>
<th >Spec2</th>
<th >Spec3</th>
<th >Spec4</th>
<th >Spec5</th>
<th >Spec6</th>
<th >Qty</th>
<th></th>
</tr>
</tfoot>
</table>
这是我使用 php 和 AJAX 从 mysql 加载数据的脚本。我已经在 ajax 之后添加了多过滤器脚本,但仍然无法正常工作。
$(document).ready(function()
//Reading
var dataTable=$('#example').DataTable(
"processing": true,
"serverSide":true,
"ajax":
url:"pages_exe/machine_dt.php",
type:"POST"
,
initComplete: function ()
this.api().columns().every( function ()
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo( $(column.footer()).empty() )
.on( 'change', function ()
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search( val ? '^'+val+'$' : '', true, false )
.draw();
);
column.data().unique().sort().each( function ( d, j )
select.append( '<option value="'+d+'">'+d+'</option>' );
);
);
);
);
这是从我的数据库加载或获取数据的 PHP 文件。 machine_dt.php
<?php
include '../environment.php';
include '../config/database.php';
$request=$_REQUEST;
$col =array(
0 => 'machid',
1 => 'machine',
2 => 'spec1',
3 => 'spec2',
4 => 'spec3',
5 => 'spec4',
6 => 'spec5',
7 => 'spec6',
8 => 'qty'
); //create column like table in database
$sql =" SELECT * FROM machinelist
/*WHERE qty != 'disable'*/
ORDER BY machine ASC;";
$query=mysqli_query($db,$sql);
$totalData=mysqli_num_rows($query);
$totalFilter=$totalData;
//Search
$sql =" SELECT * FROM machinelist
/*WHERE qty != 'disable'*/
WHERE 1=1
";
if(!empty($request['search']['value']))
$sql.=" AND (machine Like '%".$request['search']['value']."%' ";
$sql.=" OR brand Like '%".$request['search']['value']."%' ";
$sql.=" OR spec2 Like '%".$request['search']['value']."%' ";
$sql.=" OR spec3 Like '%".$request['search']['value']."%' ";
$sql.=" OR spec4 Like '%".$request['search']['value']."%'";
$sql.=" OR spec5 Like '%".$request['search']['value']."%' ";
$sql.=" OR spec6 Like '%".$request['search']['value']."%' ";
$sql.=" OR qty Like '%".$request['search']['value']."%' )";
$query=mysqli_query($db,$sql);
$totalData=mysqli_num_rows($query);
//Order
$sql.=" ORDER BY ".$col[$request['order'][0]['column']]." ".$request['order'][0]['dir']." LIMIT ".
$request['start']." ,".$request['length']." ";
$query=mysqli_query($db,$sql);
$data=array();
$i=1;
while($row=mysqli_fetch_array($query))
$subdata=array();
$subdata[]= $i++;
$subdata[]=$row[1];
$subdata[]=$row[2];
$subdata[]=$row[3];
$subdata[]=$row[4];
$subdata[]=$row[5];
$subdata[]=$row[6];
$subdata[]=$row[7];
$subdata[]=$row[8];
$subdata[]='<button type="button" class="btn btn-primary btn-sm" id="update" data-id="'.$row[0].'" >Edit</button>
<button type="button" class="btn btn-danger btn-sm" id="delete" data-id="'.$row[0].'" >Delete</button>';
$data[]=$subdata;
$json_data=array(
"draw" => intval($request['draw']),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFilter),
"data" => $data
);
echo json_encode($json_data);
?>
【问题讨论】:
当您使用服务器端模式时,客户端过滤被禁用。相反,draw()
调用(您仍然需要)将触发数据发送到服务器。 DataTables 会自动为您执行此操作。因此,您应该会在该请求中看到任何选定的下拉值 - 例如,在 columns[2][search][value]
中。请参阅 "Sent Parameters" 以获取作为请求一部分的字段的完整列表。
所以,问题是:您是否在这些请求字段中看到您选择的下拉值?在您的浏览器工具中查看请求 (F12)。
您不应该将用户输入直接放入 sql 语句中,否则您的网站很快就会被黑客入侵(请参阅SQL Injection)。您可以通过使用 PHP 中的 PDO 数据库接口或使用 PHP 代码过滤记录而不是在末尾添加有点笨拙的 AND 子句来解决此问题。
【参考方案1】:
$sql.=" AND (machine Like '%".$request['search']['value']."%' ";
$sql.=" OR brand Like '%".$request['search']['value']."%' ";
$sql.=" OR spec2 Like '%".$request['search']['value']."%' ";
$sql.=" OR spec3 Like '%".$request['search']['value']."%' ";
$sql.=" OR spec4 Like '%".$request['search']['value']."%'";
$sql.=" OR spec5 Like '%".$request['search']['value']."%' ";
$sql.=" OR spec6 Like '%".$request['search']['value']."%' ";
$sql.=" OR qty Like '%".$request['search']['value']."%' )";
对于玩具项目来说没问题。但它不会超过一千行。
如果您的老板需要大规模的灵活性和绩效,那么您需要将问题改成类似
如何有效地对多列进行文本搜索?
对于该问题,您将看到一个讨论 FULLTEXT 索引并将列组合成一个列。
【讨论】:
我在这里看到 SQL 注入了吗?用户直接输入 SQL?至少请添加一个警告,说明这应该在以前以某种方式完成。以上是关于如何将 DataTable 中的单个列搜索与服务器端处理一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
如果整个列数据与搜索字符串匹配,如何在jQUERY Datatable中显示/搜索数据?
jQuery DataTable 自定义按钮正则表达式列搜索
如何使用 Vue.js 将 DataTable() 与数组中的数据(v-for 循环)附加到现有的 HTML <table>?