Laravel Yajra Datatables服务端模式下列搜索失效问题
服务端处理Datatable后单独列搜索功能失效的解决方案
原本使用客户端模式处理Datatable,通过Penulis::all()拉取全量数据,但数据量过大导致加载缓慢,切换至服务端处理后,表格的单独列搜索功能失效。以下是问题排查及解决步骤:
一、相关代码参考
1. 前端表格结构
<table id="penulisTable" class="table table-striped"> <thead> <tr> <th>ID</th> <th>Nama</th> <th>Email</th> <th>Telepon</th> <th>Aksi</th> </tr> </thead> <tbody></tbody> </table>
2. Datatable jQuery配置(初始版本)
$(document).ready(function() { $('#penulisTable').DataTable({ processing: true, serverSide: true, ajax: '{{ route('penulis.data') }}', columns: [ { data: 'id', name: 'id' }, { data: 'nama', name: 'nama' }, { data: 'email', name: 'email' }, { data: 'telepon', name: 'telepon' }, { data: 'aksi', name: 'aksi', orderable: false, searchable: false } ] }); });
3. Laravel控制器代码(初始版本)
<?php namespace App\Http\Controllers; use App\Models\Penulis; use Illuminate\Http\Request; use DataTables; class PenulisController extends Controller { public function data(Request $request) { $query = Penulis::query(); return DataTables::of($query)->make(true); } }
4. PostgreSQL表DDL
CREATE TABLE penulis ( id SERIAL PRIMARY KEY, nama VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, telepon VARCHAR(20), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
二、问题原因及解决步骤
服务端模式下,Datatable不会自动处理列搜索逻辑,所有过滤操作需要后端主动接收前端传递的搜索参数并执行数据库查询过滤。
步骤1:完善前端列搜索交互
给表头添加搜索输入框,并监听输入事件触发列搜索:
$(document).ready(function() { var table = $('#penulisTable').DataTable({ processing: true, serverSide: true, ajax: { url: '{{ route('penulis.data') }}', headers: { 'X-CSRF-TOKEN': '{{ csrf_token() }}' } }, columns: [ { data: 'id', name: 'id' }, { data: 'nama', name: 'nama' }, { data: 'email', name: 'email' }, { data: 'telepon', name: 'telepon' }, { data: 'aksi', name: 'aksi', orderable: false, searchable: false } ] }); // 给可搜索列添加输入框 $('#penulisTable thead th').each(function() { var title = $(this).text(); if (title !== 'Aksi') { $(this).html(`<input type="text" placeholder="Cari ${title}" class="form-control form-control-sm" />`); } }); // 监听输入,触发列搜索 table.columns().every(function() { var that = this; $('input', this.header()).on('keyup change clear', function() { if (that.search() !== this.value) { that.search(this.value).draw(); } }); }); });
步骤2:后端处理列搜索参数
在控制器中遍历前端传递的列搜索参数,对数据库查询添加过滤条件:
public function data(Request $request) { $query = Penulis::query(); // 处理列搜索逻辑 if ($request->has('columns')) { foreach ($request->input('columns') as $column) { $columnName = $column['name']; $searchValue = trim($column['search']['value']); // 跳过空搜索值和不可搜索列 if (!empty($searchValue) && $columnName !== 'aksi') { // PostgreSQL用ILIKE实现不区分大小写模糊搜索,MySQL替换为LIKE $query->where($columnName, 'ILIKE', "%{$searchValue}%"); } } } return DataTables::of($query)->make(true); }
若为数值类型列(如
id),可将ILIKE替换为精确匹配=,或根据需求调整为范围查询。
步骤3:验证参数传递(可选)
可在控制器中临时打印请求参数,确认前端传递的搜索值是否正确:
dd($request->all());
若参数未正常传递,检查ajax路径是否正确,或CSRF令牌是否配置到位。
内容的提问来源于stack exchange,提问作者Yusuf Giovanno
相关产品推荐
相关产品推荐

