Hello, I would like to add custom validation messages to Contact form. For example instead of default “Please fill out this field”, I want to put “Please enter first name”, “Please enter last name”, “Email address is invalid”.
I added js on event “on(‘submit’, function(event)” to validate the fields and use my validation messages and it works.
However, the problem seems that with the new Shopify hCaptcha it still submits the form instantaneously upon submit. Meaning, the on(‘submit’) gets triggered and my custom validation messages appear, but the form is submitted immediately; it doesn’t stay on the page to show the validation messages.
We don’t want to disable hCaptcha. I tried adding " event.preventDefault()" but it still calls hCaptcha and the page forwards upon clicking Submit. It seems the hCaptcha code is overriding something that doesn’t allow “preventDefault()” from firing.
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('form'); // Adjust selector if needed
form.addEventListener('submit', function (event) {
event.preventDefault(); // Prevent form submission
// Your custom validation logic
let isValid = true;
const firstName = document.querySelector('[name="first_name"]'); // Adjust selector if needed
const lastName = document.querySelector('[name="last_name"]'); // Adjust selector if needed
const email = document.querySelector('[name="email"]'); // Adjust selector if needed
if (!firstName.value) {
isValid = false;
showError('first_name', 'Please enter first name');
}
if (!lastName.value) {
isValid = false;
showError('last_name', 'Please enter last name');
}
if (!validateEmail(email.value)) {
isValid = false;
showError('email', 'Email address is invalid');
}
if (isValid) {
// Trigger hCaptcha after custom validation
if (typeof grecaptcha !== 'undefined') {
grecaptcha.execute(); // Assuming you're using reCAPTCHA v3
} else {
form.submit(); // Fallback if hCaptcha is not found
}
}
});
function showError(fieldName, message) {
// Your logic to display the error message
// For example, update a specific element's text content
document.querySelector(`#${fieldName}-error`).textContent = message;
}
function validateEmail(email) {
// Simple email validation regex
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
});
Handle hCaptcha Callback
Code example
function onSubmit(e) {
e.preventDefault();
grecaptcha.execute();
}
function onCaptchaSuccess(token) {
// Submit form after successful hCaptcha validation
document.querySelector('form').submit();
}
function onCaptchaError() {
// Handle hCaptcha error if needed
}
grecaptcha.ready(function () {
document.querySelector('form').addEventListener('submit', onSubmit);
grecaptcha.execute = function () {
// Your hCaptcha execution logic
// On success, call onCaptchaSuccess(token);
// On error, call onCaptchaError();
}
});
Did this get resolved? I have the same issue as the form goes through the validation but then hcaptcha submits it independently on the result. The code above is for grecaptcha which does not exist in the latest shopify, but hcaptcha exists.
Is there anything else we can do to avoid the submissions unless via javascript we say form.submit() ?
Once you get the form element set the action to nothing, i.e. ‘javascript:’ for example, and store the real action in an attribute.
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector('#yourformid');
form.setAttribute('data-action', form.action) // Save the action
form.action = 'javascript:;'
}
When the submit event arrives, if form is validated call the submit with the saved attribute action.
form.addEventListener('submit', function (event) {
event.preventDefault() // Prevent form submission
... code to validate the fields...
if (isValid) {
event.target.action = event.target.getAttribute('data-action')
if (window.Shopify?.captcha?.protect) {
window.Shopify.captcha.protect(form, () => {
new FormData(event.target);
});
} else {
new FormData(event.target);
} else {
return false
}
}