I have a text input field, where I want to display 2 error messages on eventListener "input", (as the user types).
I've kind of got this half working.
And the problem I have, is that my validation isn't working properly.
If I enter valid text, my second error message appears. If I remove the valid text, both error messages appear.
I think the first error message is working fine.
I just only want the second error message to appear as the user types, (not when they have removed the text).
What's the best way to achieve this?
Thanks!
What's the best way to format logic like this, (using JavaScript only, not jQuery).
function checkFirstNameValidity(value) {
return /^[^0-9+;:""`|!?<>().,\/\\@#$£%^&*]{1,30}$/.test(value);
};
const firstNameField = document.getElementById("n-form-first-name");
const nameError1 = document.getElementById("n-form-first-name-error-1");
const nameError2 = document.getElementById("n-form-first-name-error-2");
let isFirstNameFieldValid = "";
let isSecondNameFieldValid = "";
function validateFirstName(e) {
e.preventDefault();
isFirstNameFieldValid = true;
if (!firstNameField.value) {
// nameError.outerText = "Please enter a first name";
nameError1.classList.add("visible");
firstNameField.classList.add("invalid");
nameError1.setAttribute("aria-hidden", false);
nameError1.setAttribute("aria-invalid", true);
return isFirstNameFieldValid = false;
}
else if (firstNameField.value && !checkFirstNameValidity.value) {
// nameError2.outerText = "Please enter a valid first name";
nameError2.classList.add("visible");
firstNameField.classList.add("invalid");
nameError2.setAttribute("aria-hidden", false);
nameError2.setAttribute("aria-invalid", true);
return isSecondNameFieldValid = false;
}
// return isFirstNameFieldValid;
};
function myFunction() {
if (isFirstNameFieldValid === true) {
console.log("isFirstNameFieldValid", isFirstNameFieldValid);
nameError1.classList.remove("visible");
firstNameField.classList.remove("invalid");
} else {
console.log("isFirstNameFieldValid", isFirstNameFieldValid);
}
if (isSecondNameFieldValid === true) {
console.log("isSecondNameFieldValid", isSecondNameFieldValid);
nameError2.classList.remove("visible");
firstNameField.classList.remove("invalid");
} else {
console.log("isSecondNameFieldValid", isSecondNameFieldValid);
}
};
firstNameField.addEventListener("input", validateFirstName);
/* First name */
#n-form-first-name-error-1, #n-form-first-name-error-2 {
display: none;
font-size: 0.8em;
}
#n-form-first-name-error-1.visible {
display: block;
}
#n-form-first-name-error-2.visible {
display: block;
}
input[type=text].invalid {
border-color: red;
}
input[type=text].valid {
border-color: #f60;
}
<form>
<div class="n-form-booker-contact-details">
<!-- Contact Fields -->
<div class="n-form-details">
<!-- First Name -->
<input type="text" id="n-form-first-name" name="n-form-first-name" placeholder="First name" onfocusout="myFunction()" required>
<label for="n-form-first-name">First name</label>
<span class="error" id="n-form-first-name-error-1" aria-live="polite">Please enter a first name</span>
<span class="error" id="n-form-first-name-error-2" aria-live="polite">Please enter a valid first name</span>
</div>
</form>
This may not be what you're after, but I simplified things a bit in this function. There's no need to have your errors already sitting there waiting to be turned on/off as separate elements. You can just have a single error element and populate it with the error message.
function validateFirstName(e) {
e.preventDefault();
nameError = document.querySelector('#n-form-first-name-error');
nameError.style.display = "none";
let error = '';
if (firstNameField.value.trim() == "") {
error = "Please enter a first name";
} else if (!checkFirstNameValidity(firstNameField.value.trim())) {
error = "Please enter a valid first name";
}
if (error) {
nameError.style.display = "block";
nameError.innerHTML = error
}
}
function checkFirstNameValidity(value) {
return /^[^0-9+;:""`|!?<>().,\/\\@#$£%^&*]{1,30}$/.test(value);
};
const firstNameField = document.getElementById("n-form-first-name");
const nameError1 = document.getElementById("n-form-first-name-error-1");
const nameError2 = document.getElementById("n-form-first-name-error-2");
let isFirstNameFieldValid = "";
let isSecondNameFieldValid = "";
function validateFirstName(e) {
e.preventDefault();
nameError = document.querySelector('#n-form-first-name-error');
nameError.style.display = "none";
let error = '';
if (firstNameField.value.trim() == "") {
error = "Please enter a first name";
} else if (!checkFirstNameValidity(firstNameField.value.trim())) {
error = "Please enter a valid first name";
}
if (error) {
nameError.style.display = "block";
nameError.innerHTML = error
}
};
function myFunction() {
if (isFirstNameFieldValid === true) {
console.log("isFirstNameFieldValid", isFirstNameFieldValid);
nameError1.classList.remove("visible");
firstNameField.classList.remove("invalid");
} else {
console.log("isFirstNameFieldValid", isFirstNameFieldValid);
}
if (isSecondNameFieldValid === true) {
console.log("isSecondNameFieldValid", isSecondNameFieldValid);
nameError2.classList.remove("visible");
firstNameField.classList.remove("invalid");
} else {
console.log("isSecondNameFieldValid", isSecondNameFieldValid);
}
};
firstNameField.addEventListener("input", validateFirstName);
/* First name */
#n-form-first-name-error-1,
#n-form-first-name-error-2 {
display: none;
font-size: 0.8em;
}
#n-form-first-name-error-1.visible {
display: block;
}
#n-form-first-name-error-2.visible {
display: block;
}
input[type=text].invalid {
border-color: red;
}
input[type=text].valid {
border-color: #f60;
}
<form>
<div class="n-form-booker-contact-details">
<!-- Contact Fields -->
<div class="n-form-details">
<!-- First Name -->
<input type="text" id="n-form-first-name" name="n-form-first-name" placeholder="First name" onfocusout="myFunction()" required>
<label for="n-form-first-name">First name</label>
<div class="error" id="n-form-first-name-error" aria-live="polite">Please enter a first name</div>
</div>
</form>