Hey everyone, I have followed the "Wix Website Tutorial: Custom Forms 3 Ways" from Wixwiz as close as I could. When I followed before refactoring, I could fill in the fields one at a time and the code would recognise the remaining fields I need to fill by showing the error.
But when I refactored, I noticed that when I fill the field one at a time and then check with submitting the form, the code behaves as if no fields has been filled out. The error would show all fields need to be filled.
import wixData from 'wix-data';
$w.onReady(function () {
$w("#submitButton").onClick(submit);
const inputElements = [$w("#firstName"), $w("#email")]
async function submit() {
await $w("#errorMsg").hide();
await $w("#submitButton").disable();
await $w("#loader").show();
const isValid = await validate();
if (!isValid) {
return;
}
const firstName = $w("#firstName").value;
const email = $w("#email").value;
//these details are what are used to save to collection
const formSubmission = {
name,
email
}
try {
const savedSubmissions = await wixData.save("profileapplicants", formSubmission);
console.log(savedSubmissions);
await showSuccessMessage("Your form has been submitted")
inputElements.forEach(async (element) => {
element.value = null;
await element.resetValidityIndication();
})
} catch (error) {
//optional: can convey specific error but note that error code can be complex and unclear and misleading
console.log(error);
await showErrorMessage("There was an issue submitted please try again");
}
}
async function validate() {
let valid = true;
let errormsg = "Please fill out the following fields:"
inputElements.reverse().forEach(async (element) => {
valid = valid && element.valid
errormsg += ` ${element.label},`;
await element.updateValidityIndication();
await element.scrollTo();
})
// valid = firstNameIsValid && emailIsValid;
if (!valid) {
await showErrorMessage(errormsg);
}
return valid;
}
async function showErrorMessage(message) {
$w("#errorMsg").text = message || "There was some error";
await $w("#errorMsg").show();
await $w("#submitButton").enable();
await $w("#loader").hide();
}
async function showSuccessMessage(message) {
$w("#successMsg").text = message || "Your form has been submitted";
await $w("#successMsg").show();
await $w("#loader").hide();
}
});
The end result. Note that I was only testing name and email:
I found that changing the validate function worked, with help gpt:
async function validate() {
let valid = true;
let errormsg = "Please fill out the following fields:"
for (const element of inputElements.slice().reverse()) {
const isValidElement = await element.valid;
valid = valid && element.valid;
if (!isValidElement) {
errormsg += ` ${element.label},`;
}
await element.updateValidityIndication();
await element.scrollTo();
}
if (!valid) {
const lastIndex = errormsg.lastIndexOf(',');
if (lastIndex !== -1) {
errormsg = errormsg.substring(0, lastIndex) + '.' + errormsg.substring(lastIndex + 1);
}
await showErrorMessage(errormsg);
}
return valid;
}
What I don't know is whether this is best practice.
Hi,
If I understand correctly the issue you experienced is that if you submitted the form with no fields filled, the error message under the submit button would show all the fields as not filled and continue to do so even as the fields are filled. The issue stems from the fact that: 1. The .hide() is only begin applied to the error message when the submit button is begin clicked. 2. The validate function is only running when the submit button is clicked. These can be resolved by adding an .onChange event handler to the inputs that runs the validation and adding the $w("#errorMsg").hide() to the validation function. Please let me know if that helps. Eitan