DataTable默认有一个单一的搜索框,用于全局搜索。
如果默认的搜索过滤器不能满足你的要求,那么你可以定制和添加你自己的过滤器元素,如 - 下拉菜单,日期过滤器,文本框等。
在本教程中,我展示了如何在Laravel 9的DataTable AJAX分页中添加自定义过滤器。

1. 数据库配置
打开.env 文件。
指定主机、数据库名称、用户名和密码。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tutorial
DB_USERNAME=root
DB_PASSWORD=
2. 表的结构
- 使用迁移创建一个新的表
employees。
php artisan make:migration create_employees_table
- 现在,从项目根目录导航到
database/migrations/文件夹。 - 找到一个以
create_employees_table结尾的PHP文件并打开它。 - 在
up()方法中定义表的结构。
public function up()
{
Schema::create('employees', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('username',60);
$table->string('name');
$table->string('email',80);
$table->string('city',80);
$table->string('gender',10);
$table->timestamps();
});
}
- 运行迁移------。
php artisan migrate
- 表已经创建,我向它添加了一些记录。
3. 下载
- 从这里下载DataTables库,同时下载jQuery库。
- 将下载的文件解压到
public/文件夹中。 - 同时,将jQuery库复制到
public/文件夹中。 - 你也可以使用CDN。
<!-- Datatable CSS -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css"/>
<!-- jQuery Library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Datatable JS -->
<script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
4. 模型
- 创建
Employees模型。
php artisan make:model Employees
- 打开
app/Models/Employees.php文件。 - 使用
$fillable属性指定大量可分配的模型属性 - 用户名、姓名、电子邮件、性别和城市。
完成的代码
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Employees extends Model
{
use HasFactory;
protected $fillable = [
'username','name','email','gender','city'
];
}
5. 控制器
- 创建
EmployeesController控制器。
php artisan make:controller EmployeesController
- 导入
Employees模型。
创建2个方法 -
- **index() -**从
employees表中获取不同的城市记录并分配给$data['cities']。加载index视图并传递给$data。 - **getEmployees() -**使用这个方法返回DataTable记录。
读取DataTable的值并将其分配给变量。
读取自定义过滤器的值(searchCity,searchGender和searchName)并将其分配给变量。
从employees 表中获取带和不带过滤器的总记录。在计算记录时,如果变量值不是空的,在where 子句中添加自定义过滤器。
从employees 表中获取记录,如果变量不为空,在where 子句中指定自定义过滤器的值。
在获取的记录上循环,并将值分配给$data_arr 数组。
用draw, iTotalRecords, iTotalDisplayRecords, 和aaData键初始化$response 数组。
以JSON格式返回$response 数组。
完成的代码
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Employees;
class EmployeesController extends Controller {
public function index(){
$data['cities'] = Employees::distinct()->get(['city']);
return view('index',$data);
}
// Fetch DataTable data
public function getEmployees(Request $request){
## Read value
$draw = $request->get('draw');
$start = $request->get("start");
$rowperpage = $request->get("length"); // Rows display per page
$columnIndex_arr = $request->get('order');
$columnName_arr = $request->get('columns');
$order_arr = $request->get('order');
$search_arr = $request->get('search');
$columnIndex = $columnIndex_arr[0]['column']; // Column index
$columnName = $columnName_arr[$columnIndex]['data']; // Column name
$columnSortOrder = $order_arr[0]['dir']; // asc or desc
$searchValue = $search_arr['value']; // Search value
// Custom search filter
$searchCity = $request->get('searchCity');
$searchGender = $request->get('searchGender');
$searchName = $request->get('searchName');
// Total records
$records = Employees::select('count(*) as allcount');
## Add custom filter conditions
if(!empty($searchCity)){
$records->where('city',$searchCity);
}
if(!empty($searchGender)){
$records->where('gender',$searchGender);
}
if(!empty($searchName)){
$records->where('name','like','%'.$searchName.'%');
}
$totalRecords = $records->count();
// Total records with filter
$records = Employees::select('count(*) as allcount')->where('name', 'like', '%' .$searchValue . '%');
## Add custom filter conditions
if(!empty($searchCity)){
$records->where('city',$searchCity);
}
if(!empty($searchGender)){
$records->where('gender',$searchGender);
}
if(!empty($searchName)){
$records->where('name','like','%'.$searchName.'%');
}
$totalRecordswithFilter = $records->count();
// Fetch records
$records = Employees::orderBy($columnName,$columnSortOrder)
->select('users_4.*')
->where('users_4.name', 'like', '%' .$searchValue . '%');
## Add custom filter conditions
if(!empty($searchCity)){
$records->where('city',$searchCity);
}
if(!empty($searchGender)){
$records->where('gender',$searchGender);
}
if(!empty($searchName)){
$records->where('name','like','%'.$searchName.'%');
}
$employees = $records->skip($start)
->take($rowperpage)
->get();
$data_arr = array();
foreach($employees as $employee){
$username = $employee->username;
$name = $employee->name;
$email = $employee->email;
$gender = $employee->gender;
$city = $employee->city;
$data_arr[] = array(
"username" => $username,
"name" => $name,
"email" => $email,
"gender" => $gender,
"city" => $city,
);
}
$response = array(
"draw" => intval($draw),
"iTotalRecords" => $totalRecords,
"iTotalDisplayRecords" => $totalRecordswithFilter,
"aaData" => $data_arr
);
return response()->json($response);
}
}
6. 路线
- 打开
routes/web.php文件。 - 定义2个路由 -
- **/ -**加载
index视图。 - **/getEmployees -**这是AJAX请求的GET类型的路线,以加载可数据化的数据。
- **/ -**加载
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EmployeesController;
Route::get('/', [EmployeesController::class, 'index']);
Route::get('/getEmployees', [EmployeesController::class, 'getEmployees'])->name('getEmployees');
7. 视图
在resources/views/ 中创建index.blade.php 文件。
包括DataTables和jQuery库在<head > 部分。
HTML -
- 自定义过滤器
我创建了3个过滤元素 -
-
- 第一个元素是一个下拉元素,用于存储城市列表。
- 第2个元素是一个下拉元素,存储性别名称。
- 第3个元素是一个文本框元素,用于按姓名过滤记录。
- 数据表
创建<table id="empTable" > 来初始化数据表格。
脚本 -
在#empTable 上初始化DataTable,并将实例分配给empTable 。向route('getEmployees') 发送AJAX请求。
传递自定义过滤值
使用data 选项来发送自定义过滤值 -data.searchCity,data.searchGender, 和data.searchName 。
在columns 选项中指定在成功回调时被读取的键名。
在#sel_city,#sel_gender上定义change 事件,在#searchName上定义keyup 事件。
当事件触发时,在DataTable实例上调用draw() -empTable.draw(); 。使用这个重绘DataTable。
完成的代码
<!DOCTYPE html>
<html>
<head>
<title>How to add Custom filter in DataTable AJAX pagination in Laravel 9</title>
<!-- Meta -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<!-- Datatable CSS -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css"/>
<!-- jQuery Library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<!-- Datatable JS -->
<script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
</head>
<body>
<!-- Search filter -->
<div>
<!-- City -->
<select id='sel_city'>
<option value=''>-- Select city --</option>
@foreach($cities as $city){
<option value='{{ $city->city }}'>{{ $city->city }}</option>
@endforeach
</select>
<!-- Gender -->
<select id='sel_gender'>
<option value=''>-- Select Gender --</option>
<option value='male'>Male</option>
<option value='female'>Female</option>
</select>
<!-- Name -->
<input type="text" id="searchName" placeholder="Search Name">
</div>
<table id='empTable' width='100%' border="1" style='border-collapse: collapse;'>
<thead>
<tr>
<th>Username</th>
<th>Name</th>
<th>Email</th>
<th>Gender</th>
<th>City</th>
</tr>
</thead>
</table>
<!-- Script -->
<script type="text/javascript">
$(document).ready(function(){
// DataTable
var empTable = $('#empTable').DataTable({
processing: true,
serverSide: true,
ajax: {
url:"{{route('getEmployees')}}",
data: function(data){
data.searchCity = $('#sel_city').val();
data.searchGender = $('#sel_gender').val();
data.searchName = $('#searchName').val();
}
},
columns: [
{ data: 'username' },
{ data: 'name' },
{ data: 'email' },
{ data: 'gender' },
{ data: 'city' },
]
});
$('#sel_city,#sel_gender').change(function(){
empTable.draw();
});
$('#searchName').keyup(function(){
empTable.draw();
});
});
</script>
</body>
</html>
8. 演示
9. 总结
当自定义过滤器事件被触发时,你需要在DataTable实例上调用draw()来获取过滤的记录。
如果你的项目是在Laravel 8上,你可以使用同样的代码。
如果你觉得这个教程有帮助,那么别忘了分享。