JavaScript client side form validation, an issue with posting data after a validation block

Viewed 23

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 :)

2 Answers

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>

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.

Related