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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 09:15:02