Laravel Blade表单提交后如何保留年月下拉框选中值
解决Laravel Blade动态生成下拉框提交后保留选中状态的问题
你遇到的问题很典型——因为下拉框选项是通过JavaScript动态生成的,页面加载时这些选项还不存在,所以Laravel的withInput()或者old()助手没法直接帮你设置选中状态。下面给你两种可行的解决方案,你可以根据自己的习惯选择:
方案一:在JavaScript中获取旧值并设置选中
这个方案保留你原来的JS动态生成逻辑,只需要添加一小段代码来设置选中状态:
步骤1:在Blade中传递旧值给JS
你可以通过隐藏输入框的方式,把用户提交的年份和月份传递给JavaScript,这样更清晰直观:
<form id="commissionReportPanel" method="POST" action="{{route('commission-data')}}" > @csrf <!-- 替换原来的csrf隐藏字段,Laravel 5.6+支持这种更简洁的写法 --> <input type="hidden" id="selectedYear" value="{{ old('year') }}"> <input type="hidden" id="selectedMonth" value="{{ old('month') }}"> <div class="row"> <div class="col-md-3"> <label class="col-form-label header-style">Select Month</label> <div class="input-group"> <select class="dob input-sm" id="year" name="year"></select> <select class="dob input-sm" id="month" name="month"></select> </div> </div> <div class="col-md-3" style="margin-top: 23px;"> <button class="btn btn-primary" type="submit" id="search" onclick="return check_year()">Submit</button> </div> </div> </form>
步骤2:修改JavaScript代码,生成选项后设置选中状态
在生成完年份和月份的选项后,添加代码读取隐藏字段的值,然后设置对应的选中状态:
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; var qntYears = 20; var selectYear = $("#year"); var selectMonth = $("#month"); var currentYear = new Date().getFullYear(); // 生成年份选项 for (var y = 0; y < qntYears; y++){ let date = new Date(currentYear); var yearElem = document.createElement("option"); yearElem.value = currentYear yearElem.textContent = currentYear; selectYear.append(yearElem); currentYear--; } // 生成月份选项 for (var m = 0; m <12; m++){ let monthNum = new Date(2018, m).getMonth(); let month = monthNames[monthNum]; var monthElem = document.createElement("option"); monthElem.value = monthNum; monthElem.textContent = month; selectMonth.append(monthElem); } // 读取旧值并设置选中状态 const selectedYear = document.getElementById('selectedYear').value; const selectedMonth = document.getElementById('selectedMonth').value; // 设置年份选中,无旧值则默认选当前年 if (selectedYear) { selectYear.val(selectedYear); } else { selectYear.val(new Date().getFullYear()); } // 设置月份选中,无旧值则默认选当前月 if (selectedMonth) { selectMonth.val(selectedMonth); } else { selectMonth.val(new Date().getMonth()); }
方案二:用Laravel直接生成下拉框选项(更简洁易维护)
其实你完全可以不用JavaScript生成选项,直接在Blade模板中用PHP循环生成,这样就能直接利用Laravel的old()助手设置选中状态,代码逻辑更清晰:
步骤1:传递月份名称数组到视图
在控制器中处理视图时,传递月份名称数组:
// 控制器对应方法 public function showCommissionForm() { $monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; return view('your-view-name', compact('monthNames')); }
步骤2:在Blade中直接生成下拉框
用循环生成选项,并通过old()判断是否选中:
<form id="commissionReportPanel" method="POST" action="{{route('commission-data')}}" > @csrf <div class="row"> <div class="col-md-3"> <label class="col-form-label header-style">Select Month</label> <div class="input-group"> <select class="dob input-sm" id="year" name="year"> @for($y = now()->year; $y >= now()->year - 19; $y--) <option value="{{ $y }}" {{ old('year') == $y ? 'selected' : '' }}>{{ $y }}</option> @endfor </select> <select class="dob input-sm" id="month" name="month"> @foreach($monthNames as $index => $month) <option value="{{ $index }}" {{ old('month') == $index ? 'selected' : '' }}>{{ $month }}</option> @endforeach </select> </div> </div> <div class="col-md-3" style="margin-top: 23px;"> <button class="btn btn-primary" type="submit" id="search" onclick="return check_year()">Submit</button> </div> </div> </form>
这样一来,当你在控制器中使用return redirect()->back()->withInput();时,old()助手会自动帮你设置对应的选中状态,完全不需要JavaScript干预。
为什么之前的withInput()没用?
因为withInput()是让Laravel在表单字段中填充旧值,但你的下拉框选项是在页面加载完成后通过JS动态生成的——当Laravel渲染页面时,这些选项还不存在,所以old()没法找到对应的选项去设置选中状态。必须等JS生成完选项后手动设置,或者直接在Blade中提前生成选项。
内容的提问来源于stack exchange,提问作者ganesh
相关产品推荐
相关产品推荐

