Laravel非AJAX日期范围筛选问题:选日期后查询无响应求解决
日期范围筛选无更新问题排查与非AJAX解决方案
上级要求实现日期范围筛选功能,且不能使用AJAX。目前日期筛选控件能正常显示,但选择日期后查询结果并未更新。以下是对现有代码的问题分析及可行解决方案:
现有代码问题分析
控制器代码(问题点)
public function daterange(Request $request) { // 冗余变量定义,$daterange未使用 $daterange = $dateRange = DB::table('order_items') ->whereBetween('created_at', array( (Carbon::parse($request->input('datepicker_from'))->format('Y-m-d')), (Carbon::parse($request->input('datepicker_to'))->format('Y-m-d')) ) ) ->get(); return view('profiles.dateRange', ['date_range' => $dateRange]); }
- 存在冗余代码
$daterange =,无实际作用 - 未处理日期参数为空的情况,可能导致SQL查询报错
- 未结合DataTables逻辑,直接返回原始数据集,但视图中使用
{!! $dataTable->table() !!}渲染,控制器应传递DataTable实例而非集合
视图模板代码(问题点)
@section('styles') @include('layouts.datatables_css') @endsection <tbody><tr> <td>Minimum date:</td> <td><input type="text" id="datepicker_from" name="datepicker_from"></td> </tr> <tr> <td>Maximum date:</td> <td><input type="text" id="datepicker_to" name="datepicker_to"></td> </tr> <!-- <input type="button" name="search" id="search" value="Search" class="btn btn-info" /> --> </tbody></table> <div class="table-responsive"> {!! $dataTable->table(['width' => '100%'], true) !!} </div> @section('scripts') @include('layouts.datatables_js') {!! $dataTable->scripts() !!} <script> $('#dataTableBuilder thead').append('<tr class="column-search"></tr>'); $('#dataTableBuilder thead th').each(function() { var title = $(this).text(); if(title === 'Action') { $('.column-search').append('<td></td>'); } else { $('.column-search').append('<td><input type="text" placeholder="Search '+title+'" /></td>'); } }); var table = $('#dataTableBuilder').DataTable(); var idx = 0; table.columns().every(function() { var that = this; $('input', $('.column-search td').get(idx)).on('keyup change', function() { if (that.search() !== this.value) { that .search(this.value) .draw(); } }); idx++; // 错误:在columns循环内重复初始化日期选择器,导致事件绑定混乱 $("#datepicker_from").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', onselect: function (dateText) { $("#datepicker_to").datepicker('option', 'minDate', dateText); } }); $("#datepicker_to").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', }); }); // 重复初始化日期选择器,完全冗余 $("#datepicker_from").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', onselect: function (dateText) { $("#datepicker_to").datepicker('option', 'minDate', dateText); } }); $("#datepicker_to").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', }); </script> @endsection
- 日期输入框未包裹在
<form>标签内,无提交路径,无法将日期参数传递给控制器 - 两次重复初始化日期选择器,导致事件绑定混乱
- 日期选择器的
onselect拼写错误(应为onSelect,首字母大写),最小日期限制失效 - 无触发筛选的逻辑,选择日期后无法触发页面刷新或数据更新
非AJAX解决方案(两种可行方式)
方式一:表单提交刷新页面(推荐,适合大数据量)
核心思路:用表单包裹日期输入框,点击筛选按钮后提交表单,控制器接收参数后重新渲染带筛选结果的DataTables页面。
1. 修改视图模板
@section('styles') @include('layouts.datatables_css') @endsection <!-- 新增表单,指定提交到控制器的daterange路由 --> <form method="GET" action="{{ route('daterange') }}"> <table> <tbody> <tr> <td>起始日期:</td> <td> <input type="text" id="datepicker_from" name="datepicker_from" value="{{ request('datepicker_from') }}"> </td> </tr> <tr> <td>结束日期:</td> <td> <input type="text" id="datepicker_to" name="datepicker_to" value="{{ request('datepicker_to') }}"> </td> </tr> <tr> <td colspan="2"> <button type="submit" class="btn btn-info">筛选</button> </td> </tr> </tbody> </table> </form> <div class="table-responsive"> {!! $dataTable->table(['width' => '100%'], true) !!} </div> @section('scripts') @include('layouts.datatables_js') {!! $dataTable->scripts() !!} <script> // 仅初始化一次日期选择器 $("#datepicker_from").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', onSelect: function (dateText) { $("#datepicker_to").datepicker('option', 'minDate', dateText); } }); $("#datepicker_to").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', }); // 保留原有的列搜索逻辑 $('#dataTableBuilder thead').append('<tr class="column-search"></tr>'); $('#dataTableBuilder thead th').each(function() { var title = $(this).text(); if(title === 'Action') { $('.column-search').append('<td></td>'); } else { $('.column-search').append('<td><input type="text" placeholder="搜索 '+title+'" /></td>'); } }); var table = $('#dataTableBuilder').DataTable(); var idx = 0; table.columns().every(function() { var that = this; $('input', $('.column-search td').get(idx)).on('keyup change', function() { if (that.search() !== this.value) { that.search(this.value).draw(); } }); idx++; }); </script> @endsection
2. 修改控制器代码(结合DataTables)
假设使用yajra/laravel-datatables包,控制器应返回DataTable实例:
use App\DataTables\OrderItemsDataTable; public function daterange(Request $request, OrderItemsDataTable $dataTable) { // 处理日期参数,为空则返回全部数据 $query = DB::table('order_items'); if ($request->has('datepicker_from') && $request->has('datepicker_to')) { $from = Carbon::parse($request->datepicker_from)->format('Y-m-d'); $to = Carbon::parse($request->datepicker_to)->format('Y-m-d'); $query->whereBetween('created_at', [$from, $to]); } // 将筛选后的查询传递给DataTable return $dataTable->with(['query' => $query])->render('profiles.dateRange'); }
同时修改OrderItemsDataTable类的query()方法:
public function query(OrderItem $model) { if (request()->has('query')) { return request()->get('query'); } return $model->newQuery(); }
方式二:前端本地筛选(适合小数据量)
核心思路:页面加载时获取全部数据,选择日期后用DataTables的search()方法在前端过滤数据,无需请求后端。
修改视图中的脚本部分
var table = $('#dataTableBuilder').DataTable(); // 日期筛选逻辑 function filterByDate() { var fromDate = $('#datepicker_from').datepicker('getDate'); var toDate = $('#datepicker_to').datepicker('getDate'); table.columns('created_at:name').search('').draw(); // 清空之前的搜索 if (fromDate && toDate) { // 转换为YYYY-MM-DD格式,匹配数据库存储格式 var fromStr = $.datepicker.formatDate('yy-mm-dd', fromDate); var toStr = $.datepicker.formatDate('yy-mm-dd', toDate); // 自定义筛选规则 table.columns('created_at:name').search(fromStr + '|' + toStr, true, false).draw(); } } // 绑定日期选择后的事件 $("#datepicker_from").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', onSelect: function() { filterByDate(); } }); $("#datepicker_to").datepicker({ changeMonth: true, changeYear: true, format: 'DD-MM-YYYY', onSelect: function() { filterByDate(); } });
注意:此方式要求DataTables加载全部数据,数据量过大时会影响页面性能,仅适合小数据集场景。
内容的提问来源于stack exchange,提问作者Amiko
相关产品推荐
相关产品推荐

