Form Validation for Optional Fields - javascript

What I'm trying to do is make it so if a text field does not contain the "required" class and the field is empty, no error message will show up when the form is validated. The problem I have right now is that the password error message still shows up for the field without the "required" class. I've tried adding an if statement to the validate field function to check if the field doesn't contain the "required" class, but that doesn't appear to be working. Help much appreciated.
Functions:
const validateForm = (e) => {
e = e.target;
let messages = [];
validateRequired(e, messages);
validatePassword(e, messages);
if (messages.length > 0) {
let ul = document.createElement("ul");
for (const message of messages) {
let li = document.createElement("li")
li.textContent = message;
ul.appendChild(li);
}
e.parentElement.getElementsByClassName("errors")[0].innerHTML = "";
e.parentElement.getElementsByClassName("errors")[0].appendChild(ul);
return false;
}
return true;
}
const validateRequired = (e, messages) => {
let fields = e.getElementsByClassName("required");
for (const field of fields) {
let input = field.value;
if (input.trim().length === 0) {
messages.push("Error.");
break;
}
}
}
const validatePassword = (e, messages) => {
let fields = e.getElementsByClassName("password");
for (const field of fields) {
let input = field.value;
let allCharacters = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$!%*?&])[A-Za-z\d#$!%*?&]*$/;
if (!input.match(allCharacters)) {
messages.push("Error.");
break;
}
}
}
Form:
<div>
<label for="password">Password : </label>
<input type="text" name="password" id="password" class="password" />
</div>
<div>
<label for="requiredPassword">Required and Password : </label>
<input type="text" name="requiredPassword" id="requiredPassword" class="required password" />

Related

Proper HTML Form Validation with JAVASCRIPT

here's simple html form validated with JavaScript , it show error message when the required fields are empty and when username is short(not satisfy the required length)..but form is sending data when submit button is clicked even if errors are displayed....how can i properly validate this form?
here's the code
let form = document.getElementById("signUp");
let uname = document.querySelector("#userName");
let uemail = document.querySelector("#userEmail");
const showError = (input, message) => {
// get the form-field element
const formField = input.parentElement;
// show the error message
const error = formField.querySelector('small');
error.textContent = message;
};
const showSuccess = (input) => {
// get the form-field element
const formField = input.parentElement;
// hide the error message
const error = formField.querySelector('small');
error.textContent = '';
}
const validateForm = () => {
if (uname.value.trim() == "") {
showError(uname, "name is empty");
return false;
} else {
showSuccess(uname);
}
if (uemail.value.trim() == "") {
showError(uemail, "email is empty");
return false;
} else {
showSuccess(uemail);
}
return true;
}
const checkUsername = () => {
const username = uname.value.trim();
if (username.length < 3) {
showError(uname, 'Username must be atleast 4 characters')
return false;
} else {
showSuccess(uname);
}
return true;
}
form.addEventListener('input', (event) => {
switch (event.target.id) {
case 'userName':
checkUsername();
break;
}
});
form.addEventListener("submit", function(e) {
if (!validateForm()) {
e.preventDefault();
}
});
<h2>JavaScript Validation</h2>
<form id="signUp" name="myForm">
<div>
Name: <input type="text" name="uname" id="userName">
<small id="showMessage" class="form-text text-muted"></small>
</div>
<div>
<br> Email: <input type="email" name="email" id="userEmail">
<small id="showMessage" class="form-text text-muted"></small>
</div>
<div>
<button type="submit">sign up</button>
</form>

Form validation -> error message taken from label element .innerText

I'm trying to validate a form of which i want to show an error if the requirements are not met.
In this error i want to re-use the label text.
I didn't get very far, hence the error the console gives me:
Uncaught TypeError: Cannot read properties of null (reading
'innerText')
at onSubmit (app.js:40:71)
at HTMLFormElement.onsubmit (contact.html?userName=&userEmail=&userComment=:43:69)
As to my understanding the text in the element/label(name, email, comments) should be stored to let label. But it gives me and error at .innerText.
'use strict';
const onSubmit = event => {
event.preventDefault()
for (let element of event.target)
if (element.required) {
let label = document.getElementById(`${element.id}-label`).innerText
let error = ""
switch (element.type) {
case 'text':
if (!isNullOrEmpty(element.value)) {
if (!isMinLength(element.value, element.dataset.requiredMin)) {
error = `Your ${label.toLocaleLowerCase()} must contain at least ${element.dataset.requiredMin} letters.`
}
} else {
error = `You must enter a ${label.toLocaleLowerCase()}`
}
console.log('validera text');
break;
case 'email':
console.log('validera email');
break;
case 'textarea':
console.log('validera lösenord');
break;
}
document.getElementById(`${element.id}-error`).innerText = error
}
}
const isNullOrEmpty = value => {
if (value.length === 0)
return true
return false
}
const isMinLength = (value, minLength = 2) => {
if (value.length >= minLength)
return true
return false
}
<section class="form container">
<h1>Come in Contact with Us</h1>
<form onsubmit="onSubmit(event)" class="contact" novalidate>
<div class="name_email">
<span>
<label id="userName-label" for="userName-input">Name</label>
<input type="text" name="userName" id="userName-input" placeholder="Your Name" required data-required-min="2">
<div id="userName-error"></div>
</span>
<span>
<label id="userEmail-label" for="userEmail-input">Email</label>
<input type="email" name="userEmail" id="userEmail-input" placeholder="Your Email" required>
<div id="userEmail-error"></div>
</span>
</div>
<div>
<label id="userComment-label" for="userComment-input">Comments</label>
<textarea type="text" name="userComment" id="userComment-input" placeholder="Comments" required data-required-min="10"></textarea>
<div id="userComment-error"></div>
</div>
<div class="submitbutton">
<button type="submit" class="button bg-red">Post Comments</button>
</div>
</form>
</section>
The problem is in the parameters of the document.getElementById. Your for loop goes through input elements, not label.
Just change the id value of your inputs in your Html, remove the -input at the end. Or,
Something like this should work.
'use strict';
const onSubmit = event => {
event.preventDefault()
console.log("el:",event.target)
for (let element of event.target)
if (element.required) {
console.log("=>",element.id)
// look at it
let label = document.getElementById(`${element.id}`.replace('input','label').innerText
let error = ""
switch(element.type) {
case 'text':
if (!isNullOrEmpty(element.value)) {
if (!isMinLength(element.value, element.dataset.requiredMin)) {
error = `Your ${label.toLocaleLowerCase()} must contain at least ${element.dataset.requiredMin} letters.`
}
} else {
error = `You must enter a ${label.toLocaleLowerCase()}`
}
console.log('validera text');
break;
case 'email':
console.log('validera email');
break;
case 'textarea':
console.log('validera lösenord');
break;
}
// look at it
document.getElementById(`${element.id}`.replace("input","error")).innerText = error
}
}
const isNullOrEmpty = value =>{
if (value.length === 0)
return true
return false
}
const isMinLength = (value, minLength = 2) =>{
if (value.length >= minLength)
return true
return false
}

How to remove unwanted element

I'm trying to write easy validation code and I have trouble. I've created element div '._error-alert' and I cant remove it if the input isn't empty.
When I press submit appears my element '._error-alert' but it doesnt disapear when I try to type something there. I'll be very grateful if u help or at least show me the other path to solve it
const form = document.querySelector('.validation__form'),
reqItems = document.querySelectorAll('._req'),
emailTest = /^(([^<>()\[\]\.,;:\s#\"]+(\.[^<>()\[\]\.,;:\s#\"]+)*)|(\".+\"))#(([^<>()\.,;\s#\"]+\.{0,1})+[^<>()\.,;:\s#\"]{2,})$/,
onlyTextTest = /^[a-zA-Z0-9#]+$/,
onlyNums = /^[0-9]+$/;
const inputTest = (example, input) => example.test(input.value);
const formAddError = (input) => {
if (input.classList.contains('_req')) {
const createBlock = document.createElement('div');
createBlock.classList.add('_error-alert');
input.parentElement.insertAdjacentElement("beforeend", createBlock);
createBlock.innerText = `Invalid ${input.getAttribute("name")}!`;
}
input.parentElement.classList.add('_error');
input.classList.add('_error');
};
const formRemoveError = (input) => {
input.parentElement.classList.remove('_error');
input.classList.remove('_error');
};
// validates form if function validateForm didn't have any errors and removes my created elements '._error-alert'
const sendValidatedForm = (e) => {
e.preventDefault();
let error = validateForm(form);
if (error === 0) {
console.log('fine');
form.reset();
document.querySelectorAll('._error-alert').forEach((errorAlert) => {
errorAlert.remove();
});
}
};
form.addEventListener('submit', sendValidatedForm);
// there I want to check input and remove '._error-alert' if input isnt wrong
const checkInput = () => {
reqItems.forEach((reqInput, index) => {
reqInput.addEventListener('input', () => {
formRemoveError(reqInput);
});
});
};
checkInput();
const validateForm = (form) => {
let error = 0;
reqItems.forEach(reqInput => {
reqInput.value.trim();
formRemoveError(reqInput);
if (reqInput.getAttribute("name") == "email") {
if (!inputTest(emailTest, reqInput)) {
formAddError(reqInput);
error++;
}
} else if (reqInput.getAttribute("name") == "phone") {
if (!inputTest(onlyNums, reqInput) && reqInput.value.length < 8) {
formAddError(reqInput);
error++;
}
} else if (reqInput.getAttribute("name") == "name") {
if (!inputTest(onlyTextTest, reqInput)) {
formAddError(reqInput);
error++;
}
}
});
console.log(error);
return error;
};
<form action="" class="validation__form">
<div class="validation__input-list">
<div class="validation__input-item">
<input type="text" class="validation__input-input _req" name="name" placeholder="Name">
</div>
<div class="validation__input-item">
<input type="text" class="validation__input-input" name="surname" placeholder="Surname">
</div>
<div class="validation__input-item">
<input type="text" class="validation__input-input _req" name="phone" placeholder="Phone">
</div>
<div class="validation__input-item">
<input type="text" class="validation__input-input _req" name="email" placeholder="Email">
</div>
<div class="validation__input-item">
<input type="text" class="validation__input-input" name="password" placeholder="Password">
</div>
</div>
<button class="validation__form-btn">Submit</button>
</form>
Set the css visibility property of the element to hidden.
const error_element = document.getElementsByClassName('_error-alert')
error_element.style.visibility = 'hidden'

Form Validation: messages not displaying when all input fields are left empty

So I am practicing Javascript and right now I am trying to implement form validation.
One of the issues I am having is that when I click on the button when all of the input fields are empty, the first one (Full Name) only highlights and displays a message (Please checkout snippet). I was wondering is that how it works - can only one message be displayed at a time or is there a way to get all of the input fields to change color and display messages for each empty field?
function validateForm(e) {
const eName = document.getElementById("FullName");
const eMail = document.getElementById("Email");
const ePhone = document.getElementById("PhoneNumber");
const ePass = document.getElementById("Password");
const eCnfmPass = document.getElementById("ConfirmPassword");
const phoneno = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/;
const fullNameText = "Oops, please fill out your name";
const emailText = "Please enter a valid email";
const phoneText = "Please enter a valid phone number";
const passText = "Please enter a valid password";
const confirmText = "Please confirm your password";
//Name input validation - If input is left empty
if (eName.value === "") {
e.preventDefault();
document.getElementById("FullName").style.borderColor = "red";
document.getElementById("FullNameLabel").innerHTML = fullNameText;
document.getElementById("FullNameLabel").style.color = "red";
return false;
}
//Email input validation - If input is left empty
if (eMail.value === "") {
e.preventDefault();
document.getElementById("Email").style.borderColor = "red";
document.getElementById("EmailLabel").innerHTML = emailText;
document.getElementById("EmailLabel").style.color = "red";
return false;
}
//Phone number input validation - If input is left empty
if (ePhone.value === "") {
e.preventDefault();
document.getElementById("PhoneNumber").style.borderColor = "red";
document.getElementById("PhoneNumberLabel").innerHTML = phoneText;
document.getElementById("PhoneNumberLabel").style.color = "red";
return false;
}
//Phone number input validation - checks to see if there is a missing number or character that is not a number
if (ePhone.value.match(phoneno)) {
return true;
} else {
alert("Please check your phone number and enter it again")
// document.getElementById("PhoneNumber").style.borderColor = "red";
// document.getElementById("PhoneNumberLabel").innerHTML = phoneText;
// document.getElementById("PhoneNumberLabel").style.color = "red";
return false;
}
//Password input validation - If input is left empty
if (ePass.value === "") {
e.preventDefault();
document.getElementById("Password").style.borderColor = "red";
document.getElementById("PasswordLabel").innerHTML = passText;
document.getElementById("PasswordLabel").style.color = "red";
return false;
}
//Confirm password input validation - If input is left empty
if (eCnfmPass.value === "") {
e.preventDefault();
document.getElementById("ConfirmPassword").style.borderColor = "red";
document.getElementById("ConfirmPswdLabel").innerHTML = confirmText;
document.getElementById("ConfirmPswdLabel").style.color = "red";
}
}
//Checks to make sure that both password and confirm passwords match
var passConfirm = function() {
if (document.getElementById("Password").value ==
document.getElementById("ConfirmPassword").value) {
document.getElementById("Message").style.color = "green";
document.getElementById("Message").style.fontWeight = "Heavy";
document.getElementById("Message").innerHTML = "Passwords match!"
} else {
document.getElementById("Message").style.color = "red";
document.getElementById("Message").style.fontWeight = "Heavy";
document.getElementById("Message").innerHTML = "Passwords do NOT match!"
}
}
<div class="container">
<form class="form" onsubmit="validateForm(event)">
<div>
<label id="FullNameLabel">Full Name</label></br>
<input type="text" placeholder="John Doe" id="FullName" />
</div>
<div>
<label id="EmailLabel">Email</label></br>
<input type="text" placeholder="johndoe#email.com" id="Email" />
</div>
<div>
<label id="PhoneNumberLabel">Phone Number</label></br>
<input type="text" placeholder="(123) 456-7890" id="PhoneNumber" />
</div>
<div>
<label id="PasswordLabel">Password</label></br>
<input name="Password" id="Password" type="Password" placeholder="Password" onkeyup='passConfirm();' />
</div>
<div>
<label id="ConfirmPswdLabel">Confirm Password</label></br>
<input name="ConfirmPassword" id="ConfirmPassword" type="Password" placeholder="Confirm Password" onkeyup='passConfirm();' />
</div>
<span id="Message"></span>
<button type="submit" value="submit">Sign Me Up!</button>
</form>
</div>
You have too much javascript code, you can simplify that, alot.
to check if any of the inputs are empty, you can first store all the inputs in a variable like that:
let inputs = document.querySelectorAll('.form input') //This will make a Nodelist array of all the inputs inside the form.
let labels = document.querySelectorAll('.form label') //This will make a Nodelist array of the label tags inside the form
after that you can loop through the inputs array to find if any of the inputs are empty:
for (let i = 0; i < inputs.length; i++) {
if (inputs.value.length == 0) {
inputs[i].style.borderColor = 'red'
label[i].textContent = 'Please fill in this input'
}
}
Require your inputs. Why go through all that trouble making sure they're filled out?
<input required>

JS Form event and validation

I hope somebody can help me find the error in this code, i need to use simple js to create a form that only submits if there are no errors, The user name must be a valid email. The password and retyped password must be 8 characters and include one uppercase, one lowercase and one numeric. The password
and the retyped password must match. I need to make use of a regular
expression to constrain the password.
If the data rules are violated, a appropriate error messages should be displayed
and the form should be stopped from submitting.Can someone help me with why it is not doing what it is supposed to? Im still new to js and any hel would be appreciated.
function handleInvalidities(input) {
let errMsg = " ";
if (!input.validity.paternMismatch) {
errMsg = "Invalid entry. Enter your details in the format shown.";
}
if (!input.validity.paternMismatch) {
errMsg = "Invalid entry. This field cannot be empty. Please enter a value.";
}
return errMsg;
}
function displayInvalidities(errMsg, elem) {
let elemPos = document.getElementById(elem);
let errElem = document.createElement("span");
errElem.setAttribute("class", "error");
let errText = document.createTextNode(errMsg);
errElem.appendChild(errText);
elemPos.parentNode.insertBefore(errElem, elemPos.nextSibling);
}
function cleanUpErrors() {
let errors = document.getElementsByClassName("error");
for (let i = 0; i < errors.length; i++) {
errors[i].style.display = "none";
}
}
window.onload = () => {
let theForm = document.getElementById("loginform");
theForm.addEventListener("submit");
(event) => {
let stopSubmit = false;
cleanedUpErrors();
for (let i = 0; i < theForm.elements.length; i++) {
if (!theForm.elements[i].checkValidity()) {
displayInvalidities(handleInvalidities(theForm.elements[i]), theForm.Elements[i].id);
stopSubmit = true;
}
}
if (stopSubmit) {
event.preventDefault();
}
}, (false);
}
<section>
<h1>Form: validated using Javascript</h1>
<p>Try entering the following:</p>
<ul>
<li>Password longer or shorter than 8 characters and/or without an uppercase, lowercase or a numeric.</li>
<li>Passwords that do not match</li>
</ul>
<h2>Register</h2>
<p>* = Required Field</p>
<div id="formcontainer">
<form id="regsiterdetails" action="fma_t3confirm.html">
<div>
<label for="username">* Userame:</label>
<input type="text" id="username">
</div>
<div>
<label for="password">* Password (Must be 8 characters and include one uppercase, one lowercase and one numeric):</label>
<input type="password" id="password">
<input type="checkbox" id="showpasswords">
<label id="showpasswordslabel" for="showpasswords">Show passwords</label>
</div>
<div>
<label for="retypedpassword">* Retype your password:</label>
<input type="password" id="retypedpassword">
<span id="passwordmatcherror"></span>
</div>
<div>
<button type="submit" id="registerButton">Register</button>
</div>
</form>
</div>
</section>
You need to fix your event handlers and spelling (Elements) and form ID (registerdetails) and spelling of function names like cleanUpErrors
window.addEventListener("load", () => {
document.getElementById("registerdetails").addEventListener("submit", event => {
const theForm = event.target;
let stopSubmit = false;
cleanUpErrors();
for (let i = 0; i < theForm.elements.length; i++) {
if (!theForm.elements[i].checkValidity()) {
displayInvalidities(handleInvalidities(theForm.elements[i]), theForm.elements[i].id);
stopSubmit = true;
}
}
if (stopSubmit) {
event.preventDefault();
}
})
})
You are setting event listener without any function. Change in your code like this:
window.onload = () => {
let theForm = document.getElementById("regsiterdetails");
theForm.addEventListener("submit",(event) => {
let stopSubmit = false;
cleanedUpErrors();
for (let i = 0; i < theForm.elements.length; i++) {
if (!theForm.elements[i].checkValidity()){
displayInvalidities(handleInvalidities(theForm.elements[i]), theForm.Elements[i].id);
stopSubmit = true;
}
}
if (stopSubmit) {
event.preventDefault();
}
}, (false);
)
}
Also check your code as there is no element with id loginform. I think you should use regsiterdetails instead of loginform.
There was no form element with the id that you're trying to get. Try to get with the actual id which is regsiterdetails and fix your addEventListener parameter list.
function handleInvalidities(input) {
let errMsg = " ";
if (!input.validity.paternMismatch) {
errMsg = "Invalid entry. Enter your details in the format shown.";
}
if (!input.validity.paternMismatch) {
errMsg = "Invalid entry. This field cannot be empty. Please enter a value.";
}
return errMsg;
}
function displayInvalidities(errMsg, elem) {
let elemPos = document.getElementById(elem);
let errElem = document.createElement("span");
errElem.setAttribute("class", "error");
let errText = document.createTextNode(errMsg);
errElem.appendChild(errText);
elemPos.parentNode.insertBefore(errElem, elemPos.nextSibling);
}
function cleanUpErrors() {
let errors = document.getElementsByClassName("error");
for (let i = 0; i < errors.length; i++) {
errors[i].style.display = "none";
}
}
window.onload = () => {
let theForm = document.getElementById("regsiterdetails");
theForm.addEventListener("submit", (event) => {
let stopSubmit = false;
cleanedUpErrors();
for (let i = 0; i < theForm.elements.length; i++) {
if (!theForm.elements[i].checkValidity()) {
displayInvalidities(handleInvalidities(theForm.elements[i]), theForm.Elements[i].id);
stopSubmit = true;
}
}
if (stopSubmit) {
event.preventDefault();
}
}, (false));
}
<section>
<h1>Form: validated using Javascript</h1>
<p>Try entering the following:</p>
<ul>
<li>Password longer or shorter than 8 characters and/or without an uppercase, lowercase or a numeric.</li>
<li>Passwords that do not match</li>
</ul>
<h2>Register</h2>
<p>* = Required Field</p>
<div id="formcontainer">
<form id="regsiterdetails" action="fma_t3confirm.html">
<div>
<label for="username">* Userame:</label>
<input type="text" id="username">
</div>
<div>
<label for="password">* Password (Must be 8 characters and include one uppercase, one lowercase and one numeric):</label>
<input type="password" id="password">
<input type="checkbox" id="showpasswords">
<label id="showpasswordslabel" for="showpasswords">Show passwords</label>
</div>
<div>
<label for="retypedpassword">* Retype your password:</label>
<input type="password" id="retypedpassword">
<span id="passwordmatcherror"></span>
</div>
<div>
<button type="submit" id="registerButton">Register</button>
</div>
</form>
</div>
</section>

Categories

Resources