Laravel中Bootstrap Validator触发验证后表单无法提交问题求助
Laravel + Bootstrap Validator 表单提交异常问题排查与解决
问题描述
我在Laravel项目里用Bootstrap Validator的时候遇到了个头疼的问题:表单触发验证后,就算把所有错误都修正了,表单还是提交不了;但要是没触发过验证,表单就能正常提交。
我的表单是用Laravel Collective Form构建的,代码如下:
{!! Form::open(["method" => "POST", "action" => "user\UserWalletController@transfer", "id" => "transferModal", "class" => "modal fade", "aria-labelledby" => "transferModal", "aria-hidden" => "true"]) !!} <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h5 class="modal-title colorOrange1">Transfer</h5> </div> <div class="modal-body"> ... <div class="row"> <div class="col-xs-12"> <div class="form-group"> <div class="checkbox checkbox-primary"> {!! Form::checkbox("agreeTermsOfUse", null, null, ["id" => "termsOfUse", "data-error" => "You must agree Terms of Use", "required"]) !!} <label for="termsOfUse"> I agree with Terms Of Use </label> <div class="help-block with-errors"></div> </div> </div> </div> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-info" data-dismiss="modal">Close</button> <button type="submit" id="submitTransferDetails" class="btn bgTeal1" name="operationBtn" value="transferFund">Submit</button> </div> </div> <!-- /.modal-content --> </div> {!! Form::close() !!}
最初只写了一行验证代码:
$('#transferModal').validator();
后来我试着修改了JS代码,表单能提交了,但会疯狂输出上千次console.log("eooer")之后才完成提交,修改后的代码是这样的:
$('#transferModal').validator().on('submit', function (e) { if ($("input[name='transferPasswordStatus']").val() == "true") { if (e.isDefaultPrevented()) { // handle the invalid form... } else { console.log("eooer"); $(this).submit(); } } else if ($("input[name='transferPasswordStatus']").val() == "false") { alert("Password mismatch"); } });
问题根源
兄弟,你这段修改后的代码里藏着个大坑:在submit事件处理函数里调用$(this).submit(),这会再次触发表单的submit事件,而这个事件又会进入你写的处理函数,再次调用$(this).submit(),无限循环下去,直到浏览器因为递归次数过多强制停止,这就是为什么你会看到上千次的console.log输出。
至于最初的代码里验证后无法提交,大概率是因为Bootstrap Validator在验证通过后没有正确放行原生的提交事件,或者你的表单结构里有其他影响事件冒泡的因素,但修改后的代码直接引入了更严重的递归问题。
解决方案
我们需要避免递归触发submit事件,同时保证验证通过后能正常提交表单,这里给你两种可行的方案:
方案一:使用原生DOM元素的submit方法
jQuery的submit()方法会触发绑定的事件监听,而原生DOM的submit()不会,所以我们可以改成调用原生方法:
$('#transferModal').validator().on('submit', function (e) { const passwordStatus = $("input[name='transferPasswordStatus']").val(); if (passwordStatus === "true") { if (e.isDefaultPrevented()) { // 处理验证不通过的情况,比如提示用户修正错误 return; } // 调用原生submit,不会触发jQuery的submit事件监听,完美避免递归 this.submit(); } else if (passwordStatus === "false") { alert("Password mismatch"); // 阻止默认提交行为,避免表单提交 e.preventDefault(); } });
方案二:先阻止默认行为,验证通过后手动提交(更清晰)
这种方式逻辑更直观,先阻止所有默认提交,再根据条件判断是否提交:
$('#transferModal').validator().on('submit', function (e) { // 先阻止默认提交行为,把控制权握在自己手里 e.preventDefault(); const passwordStatus = $("input[name='transferPasswordStatus']").val(); if (passwordStatus === "false") { alert("Password mismatch"); return; } // 检查表单是否已经通过Bootstrap Validator的验证 if (!e.isDefaultPrevented()) { // 验证通过,提交表单 this.submit(); } else { // 验证不通过,这里可以加自定义提示,比如显示错误汇总 alert("请修正表单中的错误后再提交"); } });
额外注意事项
- 确保你的Bootstrap Validator版本是最新的,旧版本可能存在一些事件处理的bug
- 检查表单里的其他元素是否有阻止事件冒泡的代码(比如
return false),这也可能导致验证后无法提交 - 如果遇到浏览器原生验证和Bootstrap Validator冲突的情况,可以给提交按钮添加
formnovalidate属性,禁用原生验证
内容的提问来源于stack exchange,提问作者chengwei




