You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:03:27