阻止表单提交 Bootstrap 5
Prevent Form Submission Bootstrap 5
我需要回答我在下面的 js 中做错了什么。我有一个 bs5 表单,如果字段留空或无效,提交不会被阻止。当字段无效但仍允许提交时,html/css 验证工作正常。
我不精通写作 javascript(如您所知),非常感谢您的帮助!
(function () {
"use strict";
// Fetch all the forms we want to apply custom Bootstrap validation styles to
let forms = document.querySelectorAll(".needs-validation");
// Loop over them and prevent submission
Array.from(forms).forEach(function (form) {
form.addEventListener("submit", function (event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false
);
});
forms.forEach( function(e) {
e.addEventListener('submit', function(event) {
event.preventDefault();
let thisForm = this;
let action = thisForm.getAttribute('action');
let recaptcha = thisForm.getAttribute('data-recaptcha-site-key');
if( ! action ) {
displayError(thisForm, 'The form action property is not set!')
return;
}
thisForm.querySelector('.loading').classList.add('d-block');
thisForm.querySelector('.error-message').classList.remove('d-block');
thisForm.querySelector('.sent-message').classList.remove('d-block');
let formData = new FormData( thisForm );
if ( recaptcha ) {
if(typeof grecaptcha !== "undefined" ) {
grecaptcha.ready(function() {
try {
grecaptcha.execute(recaptcha, {action: 'php_email_form_submit'})
.then(token => {
formData.set('recaptcha-response', token);
php_email_form_submit(thisForm, action, formData);
})
} catch(error) {
displayError(thisForm, error)
}
});
} else {
displayError(thisForm, 'The reCaptcha javascript API url is not loaded!')
}
} else {
php_email_form_submit(thisForm, action, formData);
}
});
});
function php_email_form_submit(thisForm, action, formData) {
fetch(action, {
method: 'POST',
body: formData,
headers: {'X-Requested-With': 'XMLHttpRequest'}
})
.then(response => {
if( response.ok ) {
return response.json()
} else {
throw new Error(`${response.status} ${response.statusText} ${response.url}`);
}
})
.then(data => {
thisForm.querySelector('.loading').classList.remove('d-block');
if (data.type === 'success') {
thisForm.querySelector('.sent-message').classList.add('d-block');
thisForm.reset();
} else {
throw new Error(data ? data : 'Form submission failed and no error message returned from: ' + action);
}
})
.catch((error) => {
displayError(thisForm, error);
});
}
function displayError(thisForm, error) {
thisForm.querySelector('.loading').classList.remove('d-block');
thisForm.querySelector('.error-message').innerHTML = error;
thisForm.querySelector('.error-message').classList.add('d-block');
}
})();
为了使第一个声明中的 event.stopPropagation()
命令生效,您必须将 true
而不是 false
传递给 [=15] 的 useCapture
参数=]函数。
否则两者将同时触发并且 none 将优先于另一个,并且 stopPropagation
将实现的唯一行为是停止从 submit 事件,这对您要实现的目标没有帮助。
编辑:正如评论中所述,另一种解决方案是让代码的验证和执行都在同一个侦听器下进行。
// code before ...
forms.forEach(function(e) {
e.addEventListener('submit', function(event) {
event.preventDefault();
if (!e.checkValidity()) {
e.removeClass("was-validated");
return; // interrupts the code to happen due to being invalid
}
e.addClass("was-validated");
//...rest of the code
})
});
// code after ...
相关说明:为了在浏览器 Firefox
中实现相同的行为,可能需要 event.stopImmediatePropagation()
我需要回答我在下面的 js 中做错了什么。我有一个 bs5 表单,如果字段留空或无效,提交不会被阻止。当字段无效但仍允许提交时,html/css 验证工作正常。
我不精通写作 javascript(如您所知),非常感谢您的帮助!
(function () {
"use strict";
// Fetch all the forms we want to apply custom Bootstrap validation styles to
let forms = document.querySelectorAll(".needs-validation");
// Loop over them and prevent submission
Array.from(forms).forEach(function (form) {
form.addEventListener("submit", function (event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add("was-validated");
}, false
);
});
forms.forEach( function(e) {
e.addEventListener('submit', function(event) {
event.preventDefault();
let thisForm = this;
let action = thisForm.getAttribute('action');
let recaptcha = thisForm.getAttribute('data-recaptcha-site-key');
if( ! action ) {
displayError(thisForm, 'The form action property is not set!')
return;
}
thisForm.querySelector('.loading').classList.add('d-block');
thisForm.querySelector('.error-message').classList.remove('d-block');
thisForm.querySelector('.sent-message').classList.remove('d-block');
let formData = new FormData( thisForm );
if ( recaptcha ) {
if(typeof grecaptcha !== "undefined" ) {
grecaptcha.ready(function() {
try {
grecaptcha.execute(recaptcha, {action: 'php_email_form_submit'})
.then(token => {
formData.set('recaptcha-response', token);
php_email_form_submit(thisForm, action, formData);
})
} catch(error) {
displayError(thisForm, error)
}
});
} else {
displayError(thisForm, 'The reCaptcha javascript API url is not loaded!')
}
} else {
php_email_form_submit(thisForm, action, formData);
}
});
});
function php_email_form_submit(thisForm, action, formData) {
fetch(action, {
method: 'POST',
body: formData,
headers: {'X-Requested-With': 'XMLHttpRequest'}
})
.then(response => {
if( response.ok ) {
return response.json()
} else {
throw new Error(`${response.status} ${response.statusText} ${response.url}`);
}
})
.then(data => {
thisForm.querySelector('.loading').classList.remove('d-block');
if (data.type === 'success') {
thisForm.querySelector('.sent-message').classList.add('d-block');
thisForm.reset();
} else {
throw new Error(data ? data : 'Form submission failed and no error message returned from: ' + action);
}
})
.catch((error) => {
displayError(thisForm, error);
});
}
function displayError(thisForm, error) {
thisForm.querySelector('.loading').classList.remove('d-block');
thisForm.querySelector('.error-message').innerHTML = error;
thisForm.querySelector('.error-message').classList.add('d-block');
}
})();
为了使第一个声明中的 event.stopPropagation()
命令生效,您必须将 true
而不是 false
传递给 [=15] 的 useCapture
参数=]函数。
否则两者将同时触发并且 none 将优先于另一个,并且 stopPropagation
将实现的唯一行为是停止从 submit 事件,这对您要实现的目标没有帮助。
编辑:正如评论中所述,另一种解决方案是让代码的验证和执行都在同一个侦听器下进行。
// code before ...
forms.forEach(function(e) {
e.addEventListener('submit', function(event) {
event.preventDefault();
if (!e.checkValidity()) {
e.removeClass("was-validated");
return; // interrupts the code to happen due to being invalid
}
e.addClass("was-validated");
//...rest of the code
})
});
// code after ...
相关说明:为了在浏览器 Firefox
中实现相同的行为,可能需要event.stopImmediatePropagation()