Proper HTML Form Validation with JAVASCRIPT - 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>

Related

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
}

JavaScript , validate html form for both onkeyup and submit

I've see a lot of solution and questions similar to this but none of them helped me out
here is a simple html form with JavaScript validation
log error message on key up when the value of input fields are less than required length (less than 5)
log error message on submit when input fields are empty (first Name and last Name)
problem is when I click submit button form is submitted regardless of errors
I have tried preventDefault() and return false but none of them worked out
how can I improve the code to make them work correctly? for both key up and submit
let fname = document.getElementById('fname');
let lname = document.getElementById('lname');
form = document.querySelector('#myForm');
function checkFirstName() {
let valid = true;
if (fname.value.length < 5) {
console.log('first name must be greater than 5');
valid = false;
}
}
function checkLastName() {
let valid = true;
if (lname.value.length < 5) {
console.log('last name must be greater than 5');
valid = false;
}
}
form.addEventListener('input', function(e) {
switch (e.target.id) {
case 'fname':
checkFirstName();
break;
case 'lname':
checkLastName();
break;
}
});
form.addEventListener('submit', function(e) {
let isFormField = true;
if (fname.value === '') {
console.log('first name is required')
isFormField = false;
}
if (lname.value === '') {
console.log('last name is required')
isFormField = false;
}
if (!isFormField) {
e.preventDefault();
return
}
});
<form method="get" id="myForm">
<div>
<input type="text" class="form-control" id="fname" name="fname"></br>
<small class="small" id="small"></small>
</div>
<div>
<input type="text" class="form-control" id="lname" name="lname"></br>
<small class="small" id="small"></small>
</div>
<button type="submit" name="send">submit</button>
</form>
I've moved all the validation of firstname in the function checkFirstName and lastname in checkLastName. Just to be concise
You can make it separate, But you have to remember that form will only submit if checkFirstName and checkLastName returns true
let fname = document.getElementById('fname');
let lname = document.getElementById('lname');
form = document.querySelector('#myForm');
function checkFirstName() {
if (fname.value.length >= 5) return true;
if (fname.value === "") {
console.log('Last name is required')
return false
}
console.log('first name must be greater than 5');
return false;
}
function checkLastName() {
if (lname.value.length >= 5) return true;
if (lname.value === "") {
console.log('Last name is required')
return false
}
console.log('last name must be greater than 5');
return false;
}
form.addEventListener('input', function(e) {
switch (e.target.id) {
case 'fname':
checkFirstName();
break;
case 'lname':
checkLastName();
break;
}
});
form.addEventListener('submit', function(e) {
if (!checkFirstName() || !checkLastName()) {
e.preventDefault();
return
}
});
<form method="get" id="myForm">
<div>
<input type="text" class="form-control" id="fname" name="fname"></br>
<small class="small" id="small"></small>
</div>
<div>
<input type="text" class="form-control" id="lname" name="lname"></br>
<small class="small" id="small"></small>
</div>
<button type="submit" name="send">submit</button>
</form>

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'

How to redirect to another page when using preventDefault()? [duplicate]

This question already has answers here:
How do I redirect to another webpage?
(58 answers)
Closed 1 year ago.
Can someone help me to redirect to another page(in my case, redirect to "cart page"). Im using preventDefault() to avoid from go to the other page before validate but after i use preventDefault(), even after the validation, im still on the same page. PLEASE HELP ME:(
<script type="text/javascript">
const form = document.getElementById('form');
const email = document.getElementById('email');
const password = document.getElementById('password');
form.addEventListener('submit', e => {
e.preventDefault();
checkInputs();
});
function checkInputs() {
// trim to remove the whitespaces
const emailValue = email.value.trim();
const passwordValue = password.value.trim();
if(emailValue === '') {
setErrorFor(email, 'This field is required');
} else if (!isEmail(emailValue)) {
setErrorFor(email, 'Not a valid email');
} else {
setSuccessFor(email);
}
if(passwordValue === '') {
setErrorFor(password, 'This field is required');
} else {
setSuccessFor(password);
}
function setErrorFor(input, message) {
const formValidate = input.parentElement;
const small = formValidate.querySelector('small');
formValidate.className = 'form-validate error';
small.innerText = message;
}
function setSuccessFor(input) {
const formValidate = input.parentElement;
formValidate.className = 'form-validate success';
}
function isEmail(email) {
return /^(([^<>()\[\]\\.,;:\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,}))$/.test(email);
}
}
</script>
<form id="form" action="cart.html" method="get">
<div class="form-validate">
<label class="form-label" for="email">Email</label>
<input class="form-input" id="email" type="text">
<small>Error message</small>
</div>
<div class="form-validate">
<label class="form-label" for="password">Password</label>
<input class="form-input" id="password" type="password">
<small>Error message</small>
</div>
<div class="form-validate text-center">
<button class="btn btn-outline-dark" type="submit"><i class="fa fa-sign-in-alt me-2"></i> Log in</button>
</div>
</form>
Store whether the form is valid in a variable named isValid and set it to false in your if statements should one of the fields be invalid.
After validation, check whether isValid is true. If it is, submit the form with form.submit():
const form = document.getElementById('form');
const email = document.getElementById('email');
const password = document.getElementById('password');
form.addEventListener('submit', e => {
e.preventDefault();
checkInputs();
});
function checkInputs() {
// trim to remove the whitespaces
const emailValue = email.value.trim();
const passwordValue = password.value.trim();
var isValid = true;
if (emailValue === '') {
setErrorFor(email, 'This field is required');
isValid = false;
} else if (!isEmail(emailValue)) {
setErrorFor(email, 'Not a valid email');
isValid = false;
} else {
setSuccessFor(email);
}
if (passwordValue === '') {
setErrorFor(password, 'This field is required');
isValid = false;
} else {
setSuccessFor(password);
}
if (isValid) {
form.submit();
}
function setErrorFor(input, message) {
const formValidate = input.parentElement;
const small = formValidate.querySelector('small');
formValidate.className = 'form-validate error';
small.innerText = message;
}
function setSuccessFor(input) {
const formValidate = input.parentElement;
formValidate.className = 'form-validate success';
}
function isEmail(email) {
return /^(([^<>()\[\]\\.,;:\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,}))$/.test(email);
}
}
<form id="form" action="cart.html" method="get">
<div class="form-validate">
<label class="form-label" for="email">Email</label>
<input class="form-input" id="email" type="text">
<small>Error message</small>
</div>
<div class="form-validate">
<label class="form-label" for="password">Password</label>
<input class="form-input" id="password" type="password">
<small>Error message</small>
</div>
<div class="form-validate text-center">
<button class="btn btn-outline-dark" type="submit"><i class="fa fa-sign-in-alt me-2"></i> Log in</button>
</div>
</form>

Form Validation for Optional Fields

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" />

Categories

Resources