Following on from a previous question I asked Submit button not working with JS validation
I have been really struggling with getting the checkbox being checked to be part of the form validation.
my html is
<h1>Applicant Form</h1>
<div >
<form action="create-lead.php" id="newLead" method="POST">
<div >
<label for="firstName">First Name</label>
<input type="text" name="firstName" id="firstName" id="firstName">
<small></small>
</div>
<div >
<label for="lastName">Last Name</label>
<input type="text" name="lastName" id="lastName" id="lastName">
<small></small>
</div>
<div >
<label for="email">Email</label>
<input type="text" name="email" id="email">
<small></small>
</div>
<div >
<label for="telephone">Telephone</label>
<input type="text" name="telephone" id="telephone">
<small></small>
</div>
<div >
<label for="buyerType" >Application Type</label>
<select name="buyerType" id="buyerType">
<option value="Purchase">Purchase</option>
<option value="FirstTimeBuyer">First Time Buyer</option>
<option value="Remortgage">Remortgage</option>
<option value="RaiseFunds">Raise Funds</option>
</select>
</div>
<div >
<label for="accept">
<input type="checkbox" id="accept" name="accept" value="yes">
I agree to the <a href="#">terms and conditions</a>
</label>
<small></small>
</div>
<div >
<input type="submit" name="submitButton" id="submitButton">
<input type="reset" name="reset" id="reset">
</div>
</form>
</div>
<script src="js/app.js"></script>
and the app.js is
const firstNameEl = document.querySelector('#firstName');
const lastNameEl = document.querySelector('#lastName');
const emailEl = document.querySelector('#email');
const telephoneEl = document.querySelector('#telephone');
const checkedEl = document.getElementById('#accept');
const submitButton = document.getElementById('#submitButton');
const form = document.querySelector('#newLead');
const checkFirstName = () => {
let valid = false;
const firstName = firstNameEl.value.trim();
if (!isRequired(firstName)) {
showError(firstNameEl, 'First name cannot be left blank');
} else if (!isFirstNameValid(firstName)) {
showError(firstNameEl, 'First name must only contain letters');
} else {
showSuccess(firstNameEl);
valid = true;
};
return valid;
};
const checkLastName = () => {
let valid = false;
const lastName = lastNameEl.value.trim();
if (!isRequired(lastName)) {
showError(lastNameEl, 'Last name cannot be left blank');
} else if (!isLastNameValid(lastName)) {
showError(lastNameEl, 'Last name must only contain letters');
} else {
showSuccess(lastNameEl);
valid = true;
}
return valid;
};
const checkEmail = () => {
let valid = false;
const email = emailEl.value.trim();
if (!isRequired(email)) {
showError(emailEl, 'Email field cannot be left blank');
} else if (!isEmailValid(email)) {
showError(emailEl, 'Email is not valid')
} else {
showSuccess(emailEl);
valid = true;
}
return valid;
};
const checkTelephone = () => {
let valid = false;
const telephone = telephoneEl.value.trim();
if (!isRequired(telephone)) {
showError(telephoneEl, 'Telephone field cannot be left blank');
} else if (!isTelephoneValid(telephone)) {
showError(telephoneEl, 'Number is not valid')
} else {
showSuccess(telephoneEl);
valid = true;
}
return valid;
};
// const checkedElValid = () => {
// if (!document.querySelector('#submitButton').checked) {
// showError(, 'You must accept the terms to continue')
// } else {
// showSuccess(accept);
// valid = true;
// }
// return valid;
// };
const isFirstNameValid = (firstName) => {
const re = /^[a-zA-Z] $/;
return re.test(firstName);
};
const isLastNameValid = (lastName) => {
const re = /^[a-zA-Z] $/;
return re.test(lastName);
};
const isEmailValid = (email) => {
const re = /^(([^<>()\[\]\\.,;:\s@"] (\.[^<>()\[\]\\.,;:\s@"] )*)|(". "))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9] \.) [a-zA-Z]{2,}))$/;
return re.test(email);
};
const isTelephoneValid = (telephone) => {
const re = /^[0-9] $/;
return re.test(telephone);
};
const isRequired = value => value === '' ? false : true;
const showError = (input, message) => {
const formField = input.parentElement;
formField.classList.remove('success');
formField.classList.add('error');
const error = formField.querySelector('small');
error.textContent = message;
};
const showSuccess = (input) => {
const formField = input.parentElement;
formField.classList.remove('error');
formField.classList.add('success');
const error = formField.querySelector('small');
error.textContent = '';
}
form.addEventListener('submit', function(e) {
//validate fields
let isFirstNameValid = checkFirstName(),
isLastNameValid = checkLastName(),
isEmailValid = checkEmail(),
isTelephoneValid = checkTelephone();
IsCheckedElValid = checkedElValid();
let
isFormValid =
isFirstNameValid &&
isLastNameValid &&
isEmailValid &&
isTelephoneValid &&
IsCheckedElValid;
if (!isFormValid) {
e.preventDefault();
submitButton.disabled;
} else {
submitButton.disabled == false;
};
});
// real time validation
const debounce = (fn, delay = 500) => {
let timeoutId;
return (...args) => {
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(() => {
fn.apply(null, args)
}, delay);
};
};
//event delegation
form.addEventListener('input', debounce(function(e) {
switch (e.target.id) {
case 'firstName':
checkFirstName();
break;
case 'lastName':
checkLastName();
break;
case 'email':
checkEmail();
break;
case 'telephone':
checkTelephone();
break;
}
}));
I have included the commented out section because that is the function I am working on to try and include the checkbox as part of the validation.
Everything else works perfectly, but I need to ensure the user accepts the terms and conditions before the form can be sent.
It seems that e.preventDefault()
and submitButton.disabled
aren't working as expected, unless I am missing something..
I am relatively new, and don't have the experience to get this working properly!
edit
On the advice of https://stackoverflow.com/a/72778291/18227124
I am rewriting the final validation to
form.addEventListener("submit", function() {
//validate fields
let isFirstNameValid = checkFirstName(),
isLastNameValid = checkLastName(),
isEmailValid = checkEmail(),
isTelephoneValid = checkTelephone();
let
isFormValid =
isFirstNameValid &&
isLastNameValid &&
isEmailValid &&
isTelephoneValid;
if (isFormValid) {
let submitBtn = document.querySelector("button");
let checkBox = document.getElementById("accept");
checkBox.addEventListener("click", function () {
if (checkBox.checked) {
submitBtn.disabled == false;
} else {
submitBtn.disabled == true;
}
});
};
});
but again, I don't think I have implemented it correctly
CodePudding user response:
Your code is too long and involved to examine, but the basic idea is not to let the user click the submit button until they have passed all validations, rather than allow them to click submit and then see if everything is valid.
So we set up a click
event handler on the checkbox that simply enables or disables the submit button based on whether the checkbox is checked. When done this way, there is no need for preventDefault()
.
Here's a scaled down example that you can incorporate into your code:
let submitBtn = document.querySelector("button");
document.querySelector("input").addEventListener("click", function(){
if(this.checked){
submitBtn.disabled = false;
} else {
submitBtn.disabled = true;
}
});
<input type="checkbox"> I agree to the terms.
<button disabled>Submit</button>