Laravel表单验证失败时如何保持modal模态框不关闭并展示错误
实现方案
问题核心是**同步提交表单会触发页面刷新,导致modal默认关闭,后端校验的错误信息只能在再次打开modal时渲染展示,有两种成熟的实现方式可选:
方案1:前端实时校验(提交前即可看到错误)
直接复用Bootstrap自带的表单错误样式,替换alert提示,无需提交就能实时提示用户输入异常:
修改视图代码
给起始里程输入框补充对应id,同时给表单绑定提交校验逻辑:
<!-- 起始里程输入框示例,id需和你实际字段对应 --> <div class="mb-3"> <label class="col-form-label">起始里程</label> <input type="number" style="width: 7em" name="start_odo" class="form-control" id="start_odo" min="0" required> </div> <div class="mb-3"> <label for="recipient-name" class="col-form-label">结束里程</label> <input type="number" style="width: 7em" name="end_odo" class="form-control @error('end_odo') is-invalid @enderror" id="end_odo" min="0" required> <span class="invalid-feedback" id="end_odo_error">结束里程必须大于起始里程</span> @error('end_odo') <span class="invalid-feedback">{{ $message }}</span> @enderror </div> <!-- 表单绑定提交校验事件 --> <form onsubmit="return validate()"> <!-- 其他表单元素 --> <button type="submit" class="btn btn-primary">提交</button> </form>
优化JS校验代码
<script type="text/javascript"> function validate() { let startOdo = parseFloat(document.getElementById('start_odo').value) || 0; let endOdo = parseFloat(document.getElementById('end_odo').value) || 0; let endOdoInput = document.getElementById('end_odo'); let endOdoError = document.getElementById('end_odo_error'); if (endOdo > startOdo) { // 校验通过,移除错误样式 endOdoInput.classList.remove('is-invalid'); endOdoError.style.display = 'none'; return true; } else { // 校验不通过,显示错误提示,阻止提交 endOdoInput.classList.add('is-invalid'); endOdoError.style.display = 'block'; return false; } } // 可选配置:输入时实时校验,无需等待用户点击提交 document.getElementById('start_odo').addEventListener('input', validate); document.getElementById('end_odo').addEventListener('input', validate); </script>
方案2:后端校验后modal不关闭,直接展示错误
如果需要保留后端校验逻辑,不做前端重复校验,改用AJAX提交表单即可避免页面刷新导致modal关闭:
1. 控制器调整
校验失败时返回JSON格式的错误信息,校验成功返回成功状态:
public function store(Request $request) { $validator = Validator::make($request->all(), [ 'start_odo' => 'required', 'end_odo' => 'required|gt:start_odo', ]); if ($validator->fails()) { return response()->json(['errors' => $validator->errors()], 422); } // 原有存储逻辑 return response()->json(['status' => 'success', 'message' => '记录添加成功']); }
2. 前端AJAX提交逻辑
<script type="text/javascript"> // 给表单绑定提交事件,阻止默认同步提交 document.querySelector('form').addEventListener('submit', function(e) { e.preventDefault(); let formData = new FormData(this); fetch('你的表单提交路由地址', { method: 'POST', body: formData, headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content } }).then(response => { if (response.ok) { // 提交成功,关闭modal,可补充刷新列表等后续操作 alert('提交成功'); document.getElementById('你的modal元素id').modal('hide'); } else if (response.status === 422) { response.json().then(data => { // 渲染后端返回的错误信息 if (data.errors.end_odo) { let endOdoInput = document.getElementById('end_odo'); endOdoInput.classList.add('is-invalid'); endOdoInput.nextElementSibling.textContent = data.errors.end_odo[0]; } }) } }) }) </script>
注:确保页面头部存在Laravel默认的csrf-token meta标签即可正常提交请求。
内容的提问来源于stack exchange,提问作者voxire
相关产品推荐
相关产品推荐

