Laravel Yajra DataTables带条件默认排序实现咨询
实现Yajra DataTables默认按status>0的数据升序排序
核心思路
由于Yajra DataTables服务端默认不支持带条件的排序,我们需要在后端查询构建阶段自定义排序逻辑:先将status > 0的记录排在前面,且这部分按status升序排列;剩余status ≤ 0的记录可按需(比如按status降序)排列,同时前端指定默认排序的列为status。
步骤1:前端代码调整
修改DataTables初始化的order配置,指定默认按status列(对应columns数组索引4)升序排序:
var table = $('#example').DataTable({ processing: true, serverSide: true, // 改为按status列(索引4)升序作为默认排序 order: [[4,'asc']], ajax: { url: "{{ route('voucher.data') }}", data:function (d) { d.merchant = merchant? merchant : ''; d.status = status? status : ''; d.daterange = daterange? daterange : ''; }, type:'POST', }, columns: [ {data: 'id', name: 'id'}, {data: 'requested_date', name: 'requested_date'}, {data: 'merchant.nama', name: 'merchant.nama'}, {data: 'total', name: 'total'}, {data: 'status', name: 'status', className: "text-center"}, {data: 'action', name: 'action', className: "text-center", visible: approvalAccess, orderable:false, sortable:false}, ] });
步骤2:后端(Laravel)处理自定义排序
假设你的DataTables服务端逻辑在VoucherDataController的data方法中,拦截status列的排序请求,替换为自定义条件排序:
use Yajra\DataTables\Facades\DataTables; public function data(Request $request) { $query = Voucher::with('merchant'); // 拦截status列的排序请求,自定义排序规则 if ($request->has('order')) { $order = $request->order[0]; $columnIndex = $order['column']; $columnName = $request->columns[$columnIndex]['name']; if ($columnName === 'status') { // 先分组:status>0的排在前面,再按status升序排列各组内数据 $query->orderByRaw('CASE WHEN status > 0 THEN 0 ELSE 1 END') ->orderBy('status', $order['dir']); // 构建查询并返回结果 return DataTables::of($query) ->filter(function ($query) use ($request) { // 原有过滤逻辑 if ($request->merchant) { $query->where('merchant_id', $request->merchant); } if ($request->status !== '') { $query->where('status', $request->status); } if ($request->daterange) { list($startDate, $endDate) = explode(' - ', $request->daterange); $query->whereBetween('requested_date', [$startDate, $endDate]); } }) ->make(true); } } // 其他列的默认排序逻辑 return DataTables::of($query) ->filter(function ($query) use ($request) { // 原有过滤逻辑 if ($request->merchant) { $query->where('merchant_id', $request->merchant); } if ($request->status !== '') { $query->where('status', $request->status); } if ($request->daterange) { list($startDate, $endDate) = explode(' - ', $request->daterange); $query->whereBetween('requested_date', [$startDate, $endDate]); } }) ->make(true); }
逻辑说明
- 前端:指定默认排序列为
status升序,告知服务端按该列排序。 - 后端:通过
CASE WHEN生成虚拟排序字段,将status > 0的记录标记为0(排在前),status ≤ 0的标记为1(排在后);随后在各自分组内按指定方向排序,最终呈现1→2→0→-1→-2的顺序。
若需调整status ≤0部分的排序规则,比如让-2→-1→0升序排列,保持orderBy('status', 'asc')即可;若想让Pending(0)排在Rejected前面,改为orderBy('status', 'desc')即可。
内容的提问来源于stack exchange,提问作者Rizdhanhr
相关产品推荐
相关产品推荐

