skip to Main Content

I am new to programming and am trying to build this form validation function to check the validity of different input types and throw relevant errors. The part I am struggling with is incorporating iteration so that it runs through my array of different input types and checks their validity.

I do not know if this is the most effective way of doing it but this is all I could think of for now.

This is the code I am working on and at the moment it only works with the input type ’email’.

What I thought I could do is add a loop function to iterate through my inputTypes array and check validity (perhaps with checkValidity()?) for each of the input types listed and if invalid then send it over to the showError function.

However, where and how can I fit it in so that it works with the dot notation?
Should it be within the event listener or the showError function or entirely separate?

I would be very grateful for any hints or critiques.

const form = document.querySelector("form");
const email = document.querySelector('input[type=email]');
const tel = document.querySelector('input[type=tel]');
const text = document.querySelector('input[type=text]');
const radio = document.querySelector('input[type=radio]');
const inputTypes = [email,tel,text,radio];

const emailError = document.querySelector('input[type=email] + span.error');

//detect when user stops typing and check if content is valid

email.addEventListener("keyup", (event) =>{
      if (email.validity.valid) {
      emailError.textContent = "";
      emailError.className = "error";
      } 
      else {
        setTimeout(() =>{
          showError();
         },2000);
      }
});

//prevent form from being submitted if the value isn't valid

form.addEventListener("submit", (event) => {
  if (!email.validity.valid) {
    showError();
    event.preventDefault();
  }
});

//match appropriate error messages with relevant constraint violations of an input type

function showError() {
  if (email.validity.valueMissing) {
    emailError.textContent = "You need to enter an email address."; 
  } else if (email.validity.typeMismatch) {
    emailError.textContent = "Entered value needs to be an email address.";
  } else if (email.validity.tooShort) {
    emailError.textContent = `Email should be at least ${inputTypes.minLength} characters; you entered ${inputTypes.value.length}.`;
  }
  emailError.className = "error active";
}

2

Answers


  1. Why not just make it required, then you get the HTML5 input validation without having to code it yourself?

    Only drawback I see right now, is that name@somewhere is seen as valid in the built-in test

    <form>
    <input type="email" minlength="5" required />
    </form>
    Login or Signup to reply.
  2. You can use the invalid event on the form to display feedback to the user. Then, when the user starts to type you can evaluate the input using input.validity.valid.

    In the case of the radio buttons both are valid is one is checked. This is a special case in the input event listener. If more radio buttons have the same name (a group) they are all valid if one is valid, so the invalid class name has to be removed from all of them.

    //detect when and input element is invalid
    
    document.forms.form01.addEventListener("invalid", (event) => {
      event.preventDefault();
      let input = event.target;
      input.closest('label').classList.add('invalid');
    }, true);
    
    //detect when user stops typing and check if content is valid
    
    document.forms.form01.addEventListener("input", (event) => {
      let input = event.target;
      let group = input.form[input.name];
      if (input.validity.valid) {
        if (input == group) { // only one input with that name
          input.closest('label').classList.remove('invalid');
        } else { // a radionodelist with more input elements
          group.forEach(input => input.closest('label').classList.remove('invalid'));
        }
      }
    });
    form {
      display: flex;
      flex-direction: column;
      align-items: flex-start;
    }
    
    .error {
      font-size: small;
      visibility: hidden;
    }
    
    label.invalid+.error {
      visibility: visible;
    }
    <form name="form01">
      <label>Email: <input type="email" name="email" required></label>
      <div class="error">You need to enter an email address.</div>
      <label>Telephone: <input type="tel" name="telephone" required></label>
      <div class="error">You need to enter a telephone number.</div>
      <label>Name: <input type="text" name="username" required></label>
      <div class="error">You need to enter a name.</div>
      <label>On: <input type="radio" name="onoff" required></label>
      <label>Off: <input type="radio" name="onoff" required></label>
      <div class="error">You need to select on or off.</div>
      <button type="submit">Submit</button>
    </form>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search