Sara Sameer
Sara Sameer

Reputation: 54

Form "Required" validation using Vanilla JavaScript

I want to show the error message of required if mandatory fields are left blank. I implement it using the following way but every time the function checkinput() is invoked it adds a new span element due to which "required" message is outputted multiple times. I want the span element to be added once and disappears when user fills in the requirement. Here is my code.

const checkinput=(event)=>{
        if(event.target.value===""){
            event.target.insertAdjacentHTML('afterend','<span class="text-danger">Required</span>')
        }
        if(event.target.value!==""){
            var child=document.querySelector('span');
            child.remove();
        }
        

    }
    document.getElementById("username").addEventListener('blur',checkinput);
    document.getElementById("password").addEventListener('blur',checkinput);
    document.getElementById("confirmPassword").addEventListener('blur',checkinput);

Upvotes: 1

Views: 2462

Answers (4)

Anurag Kumar
Anurag Kumar

Reputation: 129

May it help

    <style>
      .errorMsg {
        border: 1px solid red;
      }
      .err {
        color: red;
      }
    </style>
    <form>
      <input type="text" name="name" id="name">
      <input type="password" name="password" id="password">
      <button id="submit" type="submit">Submit</button>
    </form>

    <script>
      let nameTag = document.querySelector('#name');
      let passwordTag = document.querySelector('#password');
      let submitBtn = document.querySelector('#submit');

      nameTag.addEventListener('blur', e => validation(e));
      passwordTag.addEventListener('blur', e => validation(e));

      function validation(e) {
        if (e.target.value == '') {
          e.target.classList.add('errorMsg')
          submitBtn.setAttribute('disabled', true) // Disable submit that user cannot submit
          e.target.insertAdjacentHTML('afterend', `<span class="err ${e.target.id}">It is required</span>`) 
// In the above line we are inserting an element with class same as id of input that in the remove we remove a particular error message only
        } else {
          e.target.classList.remove('errorMsg')
          submitBtn.removeAttribute('disabled')
          document.querySelector(`.err.${e.target.id}`).remove();
//Here code is saying that the element with if 'err' and 'class same as id of input' if both class present then remove it 
        }
      }
    </script>
  • Adding the class = id that a special error message delete

Upvotes: 0

Yousaf
Yousaf

Reputation: 29281

Reason why new span element is added each time you have a empty input field is because you are calling insertAdjacentHTML each time and inserting a new span element.

What you should do is add span elements with each input field in the html and initially they should be empty.When you want to validate the input fields, if any of the input is empty, select the span element next to that input element and show the error message in that span element using .textContent property. To clear the error message, you just need to set .textContent of the span element to an empty string.

Following code snippets show different ways of validating form inputs.

Form validation on form submit

Following code snippet validates form inputs when form is submitted.

const form = document.querySelector('form');
const usernameError = document.querySelector('#usernameError');
const passwordError = document.querySelector('#passwordError');

form.addEventListener('submit', (event) => {
  event.preventDefault();

  const usernameValid = validateField(form, 'username', usernameError);
  const passwordValid = validateField(form, 'password', passwordError);

  if (usernameValid && passwordValid) {
    console.log('form submitted');
    form.reset();
  }
});

function validateField(form, fieldName, errorEl) {
  if (form.elements[fieldName].value == '') {
    errorEl.textContent = `${fieldName} is required`;
    return false;
  } else {
    errorEl.textContent = '';
    return true;
  }
}
form div {
  margin: 0 0 10px;
  display: flex;
  flex-direction: column;
  max-width: 200px;
}

form label { margin: 0 0 5px; }
span { color: red; }
<form>
  <div>
    <label>Username</label>
    <input type="text" name="username" />
    <span id="usernameError"></span>
  </div>
  <div>
    <label>Password</label>
    <input type="password" name="password" />
    <span id="passwordError"></span>
  </div>
  <button>Submit</button>
</form>

Form validation on input focus loose

Following code snippet validates form inputs when any of the input looses focus.

const form = document.querySelector('form');
const inputsContainer = document.getElementById('formInputsContainer');
const submitBtn = document.querySelector('button');

form.addEventListener('submit', (event) => {
  event.preventDefault();

  const usernameValid = validateField(form, 'username');
  const passwordValid = validateField(form, 'password');

  if (usernameValid && passwordValid) {
    console.log('form submitted');
    form.reset();
  }
});

submitBtn.addEventListener('focus', () => {
  form.requestSubmit();
});

inputsContainer.addEventListener('focusout', (event) => {
  validateField(form, event.target.name);
});

function validateField(form, fieldName) {
  const errorEl = document.getElementById(`${fieldName}Error`);

  if (form.elements[fieldName].value == '') {
    errorEl.textContent = `${fieldName} is required`;
    return false;
  } else {
    errorEl.textContent = '';
    return true;
  }
}
form div {
  margin: 0 0 10px;
  display: flex;
  flex-direction: column;
  max-width: 200px;
}

form label { margin: 0 0 5px; }
span { color: red; }
<form>
  <div id="formInputsContainer">
    <div>
      <label>Username</label>
      <input type="text" name="username" />
      <span id="usernameError"></span>
    </div>
    <div>
      <label>Password</label>
      <input type="password" name="password" />
      <span id="passwordError"></span>
    </div>
  </div>
  <button>Submit</button>
</form>

Form validation as user types in the input field

Following code snippet validates form input as user types in any input field.

const form = document.querySelector('form');
const inputsContainer = document.getElementById('formInputsContainer');

form.addEventListener('submit', (event) => {
  event.preventDefault();

  const usernameValid = validateField(form, 'username');
  const passwordValid = validateField(form, 'password');

  if (usernameValid && passwordValid) {
    console.log('form submitted');
    form.reset();
  }
});

inputsContainer.addEventListener('input', (event) => {
  validateField(form, event.target.name);
});

function validateField(form, fieldName) {
  const errorEl = document.getElementById(`${fieldName}Error`);

  if (form.elements[fieldName].value == '') {
    errorEl.textContent = `${fieldName} is required`;
    return false;
  } else {
    errorEl.textContent = '';
    return true;
  }
}
form div {
  margin: 0 0 10px;
  display: flex;
  flex-direction: column;
  max-width: 200px;
}

form label { margin: 0 0 5px; }
span { color: red; }
<form>
  <div id="formInputsContainer">
    <div>
      <label>Username</label>
      <input type="text" name="username" />
      <span id="usernameError"></span>
    </div>
    <div>
      <label>Password</label>
      <input type="password" name="password" />
      <span id="passwordError"></span>
    </div>
  </div>
  <button>Submit</button>
</form>

Upvotes: 2

Yves Kipondo
Yves Kipondo

Reputation: 5603

You can use this code which create a span which is add to the DOM with the ID which is based on the form element'sname attribute. And that element can be refered to based on the ID which was attach to it before It's been add to the DOM

const checkinput=(event)=>{
    if(event.target.value===""){
        let spanId = `input-${event.target.name}`
        let span = `<span id="${spanId}" class="text-danger">Required</span>`
        setTimeout(() =>{
            document.getElementById(spanId).remove();
        }, 5000);
        event.target.insertAdjacentHTML('afterend',span)

    }
}
document.getElementById("username").addEventListener('blur',checkinput);
document.getElementById("password").addEventListener('blur',checkinput);
document.getElementById("confirmPassword").addEventListener('blur',checkinput);
<form>
  <input type="text" name="username" id="username"/>
  <input type="text" name="password" id="password"/>
  <input type="text" name="confirmPassword" id="confirmPassword"/>
</form>

Upvotes: 0

akaphenom
akaphenom

Reputation: 6888

You need something like

    if(event.target.value==="" && document.querySelector('span') === null){
        event.target.insertAdjacentHTML('afterend','<span class="text-danger">Required</span>')
    }
    if(event.target.value!==""){
        var child=document.querySelector('span');
        child.remove();
    }

You only want to add a span IF the value is an empty string AND the span hsan't been added yet.

Upvotes: 1

Related Questions