Bootstrap 4表单验证后隐藏问题:点击事件覆盖验证如何解决?
解决Bootstrap 4表单验证与表单切换冲突的问题
你遇到的问题很典型:直接给按钮绑定onclick事件会绕开Bootstrap的表单验证流程,不管表单填得对不对都直接切换了。要解决这个问题,我们需要把表单切换逻辑和Bootstrap的验证结果绑定,只有当验证通过时才执行切换。
下面是具体的修改步骤和完整代码:
步骤1:移除按钮上的onclick属性
首先把第一个表单的提交按钮上的onclick="hideEmailForm()"删掉,因为我们要把逻辑移到表单的submit事件里(这是Bootstrap验证触发的核心事件):
<button type="submit" class="btn btn-primary" id="SendOTPButton">Send OTP</button>
步骤2:修改验证脚本,绑定切换逻辑
Bootstrap的表单验证是在表单提交时触发的,我们可以在验证通过的分支里加入表单切换的代码。修改原来的通用验证脚本,让它针对第一个表单单独处理:
// Disable form submissions if there are invalid fields. (function() { 'use strict'; window.addEventListener('load', function() { // Get the forms we want to add validation styles to. var forms = document.getElementsByClassName('needs-validation'); // Loop over them and prevent submission var validation = Array.prototype.filter.call(forms, function(form) { form.addEventListener('submit', function(event) { if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } else { // 判断当前是否是第一个表单(通过父元素的id识别) if (form.parentElement.id === 'emailDiv') { // 验证通过,切换表单 document.getElementById("emailDiv").style.display="none"; document.getElementById("otpDiv").style.display="block"; // 阻止默认的表单提交行为(因为我们只是前端切换,不需要跳转到action的#) event.preventDefault(); } } form.classList.add('was-validated'); }, false); }); }, false); })();
你也可以保留原来的hideEmailForm函数,把上面的切换代码换成调用hideEmailForm(),效果是一样的:
// 验证通过时调用函数 if (form.parentElement.id === 'emailDiv') { hideEmailForm(); event.preventDefault(); }
步骤3:保留初始隐藏/显示逻辑
原来的初始状态设置脚本可以保留,确保页面加载时只显示第一个表单:
document.getElementById("emailDiv").style.display="block"; document.getElementById("otpDiv").style.display="none";
完整修改后的代码
<main role="main" class="container"> <div class="container" id="emailDiv"> <form action="#" class="needs-validation" novalidate> <div class="form-group"> <label for="email">Email Address:</label> <input type="email" class="form-control" id="email" placeholder="Enter registered email" name="email" required> <div class="valid-feedback">Entry validated!</div> <div class="invalid-feedback">Please fill out this mandatory field.</div> </div> <div class="form-group form-check"> <label class="form-check-label"> <input class="form-check-input" type="checkbox" name="checkterms" required> Terms & Conditions <div class="valid-feedback">You have accepted the terms & conditions.</div> <div class="invalid-feedback">Acceptance of the terms & conditions is mandatory.</div> </label> </div> <button type="submit" class="btn btn-primary" id="SendOTPButton">Send OTP</button> </form> </div> <div class="container" id="otpDiv"> <form action="#" class="needs-validation" novalidate> <div class="form-group mt-3"> <label for="otp">Enter OTP:</label> <input type="text" class="form-control" id="otp" placeholder="Enter the OTP which has been sent to your registered email address." name="otp" required> <div class="valid-feedback">OTP entered.</div> <div class="invalid-feedback">Please enter the mandatory OTP.</div> </div> <button type="submit" class="btn btn-success">Submit</button> </form> </div> <br> <script> // Disable form submissions if there are invalid fields. (function() { 'use strict'; window.addEventListener('load', function() { // Get the forms we want to add validation styles to. var forms = document.getElementsByClassName('needs-validation'); // Loop over them and prevent submission var validation = Array.prototype.filter.call(forms, function(form) { form.addEventListener('submit', function(event) { if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } else { // 仅对第一个表单执行切换逻辑 if (form.parentElement.id === 'emailDiv') { document.getElementById("emailDiv").style.display="none"; document.getElementById("otpDiv").style.display="block"; event.preventDefault(); } } form.classList.add('was-validated'); }, false); }); }, false); })(); </script> <script> // 初始状态设置 document.getElementById("emailDiv").style.display="block"; document.getElementById("otpDiv").style.display="none"; </script> </main>
为什么这样修改有效?
Bootstrap的表单验证机制是通过监听表单的submit事件实现的:当用户点击提交按钮时,表单会先执行checkValidity()检查所有必填项和格式是否合法。
- 如果验证失败:阻止表单提交,显示错误提示,不会执行切换逻辑。
- 如果验证通过:才会执行我们添加的表单切换代码,同时阻止默认的提交行为(因为我们不需要跳转到
#)。
这样就完美实现了先验证,再切换的需求。
内容的提问来源于stack exchange,提问作者Strootaay
相关产品推荐
相关产品推荐

