I am trying to validate the email input box to return an error when it is empty or when it does not match the email regex pattern. If email input is empty I should get an error and if email input is not empty but does not meet the pattern I should get a new error. So far I am only getting one error
const form = document.querySelector("form"),
user = document.getElementById("name"),
email = document.getElementById("email"),
emailField = document.getElementById("email-field"),
msg = document.getElementById("comment"),
errorMsg = document.getElementsByClassName("error"),
container1 = document.getElementById("form-container"),
container2 = document.getElementById("form-container2");
let field = (id, serial, message) => {
if (id.value.trim() === "") {
errorMsg[serial].innerHTML = message;
id.classList.add("invalid");
} else {
errorMsg[serial].innerHTML = "";
id.classList.remove("invalid");
}
}
// Email Validtion
function checkEmail() {
const emaiPattern = /^[^ ]+#[^ ]+\.[a-z]{2,3}$/;
if (!email.value.match(emaiPattern)) {
console.log("no match");
errorMsg[1].innerHTML = "message";
// email.classList.add("invalid"); //adding invalid class if email value do not mathced with email pattern
} else {
console.log("matches");
// emailField.classList.remove("invalid"); //removing invalid class if email value matched with emaiPattern
}
}
form.addEventListener("submit", (e) => {
e.preventDefault();
field(user, 0, "Name cannot be blank");
field(email, 1, "Email cannot be blank");
field(msg, 2, "Message cannot be blank");
checkEmail();
if (!user.classList.contains("invalid") &&
!email.classList.contains("invalid") &&
!msg.classList.contains("invalid")
) {
location.href = form.getAttribute("action");
container1.classList.add("hide");
container2.classList.remove("hide");
}
});
<div class="form-field">
<input type="text" id="email" placeholder="Email Address">
<div class="error"></div>
</div>
Related
I am creating a JavaScript form with validation. It is functional on first data entry into the form, however, once you correctly receive a data validation error for an incorrect input, then the functionality stops, the submit button stays locked and I do not know how to undo it.
I have used the ".preventDefault()" to stop inputs going through, but I do not know how to undo this method after a data validation error has already been given.
client-side-form-validation.js
const signupForm = document.getElementById('signup-form');
const email = document.getElementById('email');
const password = document.getElementById('password');
const emailError = document.getElementById('email-error');
const passwordError = document.getElementById('password-error');
// Email field client side form validation
signupForm.addEventListener('submit', (e) => {
let emailMessages = []
if (email.value === '' || email.value == null){
emailMessages.push('Email is required')
}
if (!(/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/).test(email.value)){
emailMessages.push('Email is invalid')
}
if(emailMessages.length > 0){
e.preventDefault()
emailError.innerHTML = emailMessages.join('<br>')
}
});
// Password field client side form validation
signupForm.addEventListener('submit', (e) => {
let passwordMessages = []
if (password.value === '' || password.value == null){
passwordMessages.push('Password is required')
}
if(passwordMessages.length > 0){
e.preventDefault()
passwordError.innerHTML = passwordMessages.join('<br>')
}
});
signup.ejs
<form id="signup-form" action='/signup' method="post">
<label for="email">Email:</label><br>
<input type="text" id="email" name="email"><br>
<div class="signup-error" id="email-error"></div>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br>
<div class="signup-error" id="password-error"></div>
<input type="submit" value="Submit">
</form>
Thanks for your time :)
I played around with the code for a little and came up with my own answer.
My answer involved attaching a else statement to the if statements, deleting the array and then posting the deleted array to the error message in the form.
if(emailMessages.length > 0){
e.preventDefault();
emailError.innerHTML = emailMessages.join('<br>');
}else{
delete emailMessages;
emailError.innerHTML = emailMessages.join('<br>');
}
Then do the same for the password validation.
It seems to work here.
Update: made it more friendly by checking the error on change as well as on submit.
const signupForm = document.getElementById('signup-form');
const email = document.getElementById('email');
const password = document.getElementById('password');
const emailError = document.getElementById('email-error');
const passwordError = document.getElementById('password-error');
signupForm.addEventListener('submit', (e) => {
if (!validate_email()) {
e.preventDefault()
}
if (!validate_password()) {
e.preventDefault()
}
// continue to submit
});
email.addEventListener('change', validate_email);
password.addEventListener('change', validate_password);
function validate_email() {
let messages = []
if (email.value === '' || email.value == null) {
messages.push('Email is required')
}
if (!(/^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/).test(email.value)) {
messages.push('Email is invalid')
}
var valid = !messages.length;
emailError.innerHTML = valid ? "" : messages.join('<br>')
return valid;
}
function validate_password() {
let messages = []
if (password.value === '' || password.value == null) {
messages.push('Password is required')
}
var valid = !messages.length;
passwordError.innerHTML = valid ? "" : messages.join('<br>')
return valid;
}
.signup-error {
color: red;
}
.form-group {
margin-bottom: 10px;
}
<form id="signup-form" action='/signup' method="post">
<div class="form-group">
<label for="email">Email:</label><br>
<input type="text" id="email" name="email"><br>
<div class="signup-error" id="email-error"></div>
</div>
<div class="form-group">
<label for="password">Password:</label><br>
<input type="password" id="password" name="password"><br>
<div class="signup-error" id="password-error"></div>
</div>
<input type="submit" value="Submit">
</form>
Ok with the help of stackers I was able to get an error message to show up below input form.
What I need is the error message to not be displayed when the user enters in any input in the form. What am I doing wrong?
Heres the HTML
<form id="url">
<input type="text" name="urlName">
<input type="submit" value="Build Your App"></input>
</form>
<div id="error-message">
</div>
Heres the JS
document.getElementById("url").addEventListener("submit", (event) => {
event.preventDefault()
let errorMessage = document.getElementById("error-message").innerHTML = "Please provide your store URL";
let myForm = document.getElementById("url");
let formData = new FormData(myForm);
if (formData.get("urlName") === "")
return errorMessage;
EndOfUrl = sanitizeDomainInput(formData.get("urlName"));
newUrl = redirectLink(EndOfUrl);
window.location.href = newUrl;
return false;
});
function sanitizeDomainInput(input) {
input = input || 'unknown.com'
if (input.startsWith('http://')) {
input = input.substr(7)
}
if (input.startsWith('https://')) {
input = input.substr(8)
}
var regexp = new RegExp(/^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$/)
return regexp.test(input) ? input : 'unknown.com';
}
function redirectLink(domain) {
return `https://dashboard.getorda.com/signup/?state=${domain}`;
}
You are assigning the error message to the error message container div regardless of if there's an error which is causing the message to appear in ANY case.
Refer below snippet where I've moved the error message assignment inside the error condition.
document.getElementById("url").addEventListener("submit", (event) => {
event.preventDefault()
let errorMessage = "Please provide your store URL";
let myForm = document.getElementById("url");
let formData = new FormData(myForm);
if (formData.get("urlName") === "") {
document.getElementById("error-message").innerHTML = errorMessage;
}
EndOfUrl = sanitizeDomainInput(formData.get("urlName"));
newUrl = redirectLink(EndOfUrl);
window.location.href = newUrl;
return false;
});
function sanitizeDomainInput(input) {
input = input || 'unknown.com'
if (input.startsWith('http://')) {
input = input.substr(7)
}
if (input.startsWith('https://')) {
input = input.substr(8)
}
var regexp = new RegExp(/^(([a-zA-Z]{1})|([a-zA-Z]{1}[a-zA-Z]{1})|([a-zA-Z]{1}[0-9]{1})|([0-9]{1}[a-zA-Z]{1})|([a-zA-Z0-9][a-zA-Z0-9-_]{1,61}[a-zA-Z0-9]))\.([a-zA-Z]{2,6}|[a-zA-Z0-9-]{2,30}\.[a-zA-Z]{2,3})$/)
return regexp.test(input) ? input : 'unknown.com';
}
function redirectLink(domain) {
return `https://dashboard.getorda.com/signup/?state=${domain}`;
}
<form id="url">
<input type="text" name="urlName">
<input type="submit" value="Build Your App"></input>
</form>
<div id="error-message">
</div>
I have a form, a simple form:
<form>
<input class="u-full-width" type="text" placeholder="First Name" id="firstNameInput">
<span class="error" aria-live="polite"></span>
<input class="u-full-width" type="text" placeholder="Last Name" id="lastNameInput">
<span class="error" aria-live="polite"></span>
<input class="u-full-width" type="email" placeholder="Email" id="emailInput">
<span class="error" aria-live="polite"></span>
<select class="u-full-width" name="state" id="stateInput">
<option value="selectstate">State</option>
</select>
<span class="error" aria-live="polite"></span>
<input id="submit" class="button-primary submit_button" type="submit" value="Submit">
<span class="success" aria-live="polite"></span>
</form>
Essentially I have a eventHandler wired to the form which is listening for the submit event.
theForm.addEventListener('submit', function(e) {
var x = validate(e);
if (x) {
formData['firstName'] = firstNameInput.value;
formData['lastName'] = lastNameInput.value;
formData['email'] = emailInput.value;
formData['stateInput'] = stateInput.value;
console.log('There is now data from the form: :) ');
for (var prop in formData) {
console.log(prop + ' : ' + formData[prop]);
}
}
}, false);
The validate function:
function validate(e) {
var formData = {
'firstName': null,
'lastName': null,
'email': null,
'stateInput': null
}
// Error tracking variable
var error = false;
// Do validations
var emailPattern = /^(([^<>()\[\]\\.,;:\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,}))$/;
if ((firstNameInput.value == '') || (firstNameInput.value == null)) {
firstNameInput.classList.add('invalid-input');
firstNameInput.nextElementSibling.style.display = 'block';
firstNameInput.nextElementSibling.innerHTML = 'Not valid!';
error = true;
}
if ((lastNameInput.value == '') || (lastNameInput.value == null)) {
lastNameInput.classList.add('invalid-input');
lastNameInput.nextElementSibling.style.display = 'block';
lastNameInput.nextElementSibling.innerHTML = 'Not valid!';
error = true;
}
if (!emailPattern.test(emailInput.value)) {
emailInput.classList.add('invalid-input');
emailInput.nextElementSibling.style.display = 'block';
emailInput.nextElementSibling.innerHTML = 'Please enter valid email address!';
error = true;
}
if ((stateInput.value == 'selectstate')) {
stateInput.classList.add('invalid-input');
stateInput.nextElementSibling.style.display = 'block';
stateInput.nextElementSibling.innerHTML = 'Not valid!';
error = true;
}
// If error, stop the event
if (error) {
e.preventDefault();
e.stopPropagation();
console.log('There is no data from the form: ');
for (var prop in formData) {
console.log(prop + ' : ' + formData[prop]);
}
return false;
} else {
return true;
}
}
I would think the conditional in the handler would work like this:
It would only fire if the x was true; which it would be if there was a true outcome i.e. the form submitted successfully. the obj, would get filled with the dat and then I would console.log the fields via a for in loop
I am having problems understanding why you can't get data from this function?
Any help would be appreciated...
var formData = { is contained within your validate() function but you are trying to access it from within the anonymous form submit function.
To access it in both places, you either need to pass it as an argument or declare it in a higher scope, outside of both functions like this:
var formData = {
firstName: null,
lastName: null,
email: null,
stateInput: null
}
function validate(e){
}
theForm.addEventListener('submit', function(e) {
});
Additionally, right now, your "State" dropdown will always fail validation because you only have one choice and that choice is considered invalid by your validation function.
Your tests for input in the text fields that check for null is not going to help you at all because an input that contains no data will always return '', which you are already testing for, so just that one test is fine, although you may want to change it to test for: input.value.trim() === '' because the trim() function will remove any leading or trailing spaces in the input.
Finally, when all the form data is valid, you will only see the console report for a brief moment, because the form will submit and cause a redirect to the form's action, so the current page will unload and the console will clear itself out.
Here's the whole thing put together:
var formData = {
firstName: null,
lastName: null,
email: null,
stateInput: null
}
var theForm = document.querySelector("form");
var firstNameInput = document.getElementById("firstNameInput");
var lastNameInput = document.getElementById("lastNameInput");
var emailInput = document.getElementById("emailInput");
var stateInput = document.getElementById("stateInput");
theForm.addEventListener('submit', function(e) {
if (validate(e)) {
formData['firstName'] = firstNameInput.value;
formData['lastName'] = lastNameInput.value;
formData['email'] = emailInput.value;
formData['stateInput'] = stateInput.value;
logger('There is now data from the form: :) ');
}
}, false);
function validate(e) {
// Error tracking variable
var error = false;
// Do validations
var emailPattern = /^(([^<>()\[\]\\.,;:\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,}))$/;
if (firstNameInput.value.trim() === '') {
firstNameInput.classList.add('invalid-input');
firstNameInput.nextElementSibling.style.display = 'block';
firstNameInput.nextElementSibling.innerHTML = 'Not valid!';
error = true;
}
if (lastNameInput.value.trim() === '') {
lastNameInput.classList.add('invalid-input');
lastNameInput.nextElementSibling.style.display = 'block';
lastNameInput.nextElementSibling.innerHTML = 'Not valid!';
error = true;
}
if (!emailPattern.test(emailInput.value.trim())) {
emailInput.classList.add('invalid-input');
emailInput.nextElementSibling.style.display = 'block';
emailInput.nextElementSibling.innerHTML = 'Please enter valid email address!';
error = true;
}
if (stateInput.value === 'selectstate') {
stateInput.classList.add('invalid-input');
stateInput.nextElementSibling.style.display = 'block';
stateInput.nextElementSibling.innerHTML = 'Not valid!';
error = true;
}
// If error, stop the event
if (error) {
e.preventDefault();
e.stopPropagation();
logger('There is at least one empty field in the form: ');
return false;
} else {
return true;
}
}
function logger(message){
console.clear();
console.log(message);
for (var prop in formData) {
console.log(prop + ' : ' + formData[prop]);
// This line will fail here in Stack Overflow, but is correct and
// will work in a real browser environment. Uncomment it for your use.
// localStorage.setItem(prop, formData[prop]);
}
}
#spacer { height:100px; }
<form>
<input class="u-full-width" type="text" placeholder="First Name" id="firstNameInput">
<span class="error" aria-live="polite"></span>
<input class="u-full-width" type="text" placeholder="Last Name" id="lastNameInput">
<span class="error" aria-live="polite"></span>
<input class="u-full-width" type="email" placeholder="Email" id="emailInput">
<span class="error" aria-live="polite"></span>
<select class="u-full-width" name="state" id="stateInput">
<option value="selectstate">State</option>
<option value="someSate">Some State</option>
</select>
<span class="error" aria-live="polite"></span>
<input id="submit" class="button-primary submit_button" type="submit" value="Submit">
<span class="success" aria-live="polite"></span>
</form>
<div id='spacer'></div>
I have a form which lets the user to enter the email address twice. i need to validate that the email is like the regex and that the two emails match.
Something is wrong with my code. Please note that i am restricted to use javascript only. Thanks,
this is my javascript
function checkEmail(theForm) {
var re = /^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*#"+"[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$/i;
if (theForm.EMAIL_1.value != re) {
alert('invalid email address');
return false;
} else if (theForm.EMAIL_1.value != theForm.EMAIL_2.value) {
alert('Those emails don\'t match!');
return false;
} else {
return true;
}
}
Your issue your not actually performing a regex. Your just comparing a regex string to an email.
if(theForm.EMAIL_1.value != re) /// <--- wrong.
{
alert('invalid email address');
return false;
}
On errors, use Event.preventDefault(); to prevent the form submit
Check for email validity only on the first input value
Than check to string equality on both input fields
function checkEmail (event) {
const e1 = this.EMAIL_1.value;
const e2 = this.EMAIL_2.value;
//Email Regex from //stackoverflow.com/a/46181/383904
const re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
const isEmail = re.test( e1 );
const isMatch = e1 === e2;
if( !isEmail ){
event.preventDefault();
alert('Invalid email address');
}
else if ( !isMatch ){
event.preventDefault();
alert("Those emails don't match!");
}
}
document.querySelector("#theForm").addEventListener("submit", formSubmitHandler);
<form id="theForm">
Email address:<br>
<input name="EMAIL_1" type="text"><br>
Confirm Email address:<br>
<input name="EMAIL_2" type="text"><br>
<input type="submit">
</form>
Since you might have more forms where an email is required (Contact form, Login form, Newsletter form, etc etc...) for more modularity you could create a reusable function for validation and than a specific form submit handler separately:
/**
* #param {string} a Email address 1
* #param {string} b Email address 2
* #return {string} Error message
*/
function invalidEmails (a, b) {
a = a.trim();
b = b.trim();
if (!a || !b) return "Missing email";
// Email Regex from stackoverflow.com/a/46181/383904
const re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
const isEmail = re.test(a);
const isMatch = a === b;
if (!isEmail) return "Invalid email";
else if (!isMatch) return "Emails do not match";
}
// Handle your form here
function formSubmitHandler (evt) {
const is_emails_invalid = invalidEmails(this.EMAIL_1.value, this.EMAIL_2.value);
if (is_emails_invalid) {
evt.preventDefault(); // Prevent form submit
alert(is_emails_invalid); // Show error message
}
}
document.querySelector("#theForm").addEventListener("submit", formSubmitHandler);
<form id="theForm">
Email address:<br>
<input name="EMAIL_1" type="text"><br>
Confirm Email address:<br>
<input name="EMAIL_2" type="text"><br>
<input type="submit">
</form>
You cant compare the first value with a regex. You have to use a regexp object. For more information read at
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec
Try this below function to validate your email.
And after the validation, compare the 2nd email.
Please note that regex test method is used in the validateEmail method.
function validateEmail(email) {
var re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(email);
}
The below should work perfectly!
function validateForm(theForm) {
if (theForm.Email_1.value != theForm.Email_2.value)
{
alert('Emails don\'t match!');
return false;
} else {
return true;
}
}
Im validating a form but im struggling to get it to only accept letters for firstname and lastname fields
hope u can help
heres my code:
$(document).ready(function(){
// Place ID's of all required fields here.
required = ["firstname", "lastname", "email"];
// If using an ID other than #email or #error then replace it here
email = $("#email");
errornotice = $("#error");
// The text to show up within a field when it is incorrect
emptyerror = "Please fill out this field.";
emailerror = "Please enter a valid e-mail.";
onlyletters = "Only letters allowed.";
$("#theform").submit(function(){
//Validate required fields
for (i=0;i<required.length;i++) {
var input = $('#'+required[i]);
if ((input.val() == "") || (input.val() == emptyerror)) {
input.addClass("needsfilled");
input.val(emptyerror);
errornotice.fadeIn(750);
} else {
input.removeClass("needsfilled");
}
}
// Only Letters.
if (!/^([a-zA-Z])+$/.test(errornotice.val())) {
errornotice.addClass("needsfilled");
errornotice.val(onlyletters);
}
// Validate the e-mail.
if (!/^([a-zA-Z0-9_\.\-])+\#(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(email.val())) {
email.addClass("needsfilled");
email.val(emailerror);
}
//if any inputs on the page have the class 'needsfilled' the form will not submit
if ($(":input").hasClass("needsfilled")) {
return false;
} else {
errornotice.hide();
return true;
}
});
// Clears any fields in the form when the user clicks on them
$(":input").focus(function(){
if ($(this).hasClass("needsfilled") ) {
$(this).val("");
$(this).removeClass("needsfilled");
}
});
});
Should this line be testing against errornotice.val() or firstname.val()?
if (!/^([a-zA-Z])+$/.test(errornotice.val())) {
// Maybe this is what you intended.
// This requires adding some more variables earlier when you set email and errornotice
email = $("#email");
errornotice = $("#error");
// Add vars for first/lastname
firstname = $("#firstname");
lastname = $("#lastname");
if (!/^([a-zA-Z])+$/.test(firstname.val())) {
firstname.addClass("needsfilled");
firstname.val(onlyletters);
}
// then do the same for lastname
if (!/^([a-zA-Z])+$/.test(lastname.val())) {
lastname.addClass("needsfilled");
lastname.val(onlyletters);
}
However, your regex of letters only is going to eliminate a lot of valid names including apostrophes, diacritics, umlauts, etc.