Remix Protocol
Remix Protocol

Reputation: 97

How to display form validation error messages accurately for more than two input fields using only JavaScript?

I have created a JavaScript function that checks a form during submitting the input and displays an error message if there's no input.

It works perfectly when none input is given. It displays all the error messages correctly.

The Problem: But if I leave just the first field blank i.e, the fullname; the if loop stops there and doesn't display the second or third error messages i.e, the streetaddr & quantity.

NOTE: This error happens only when one of streetaddr or quantity is not given with addition to the first field i.e, fullname.

What should I do to display the error messages correctly. According to the blank input regardless the input field comes first or second or third.

Also, I prefer to do this with just Vanilla JavaScript, no frameworks/libraries. I'm trying to learn!

Link(s): This is a challenge from Wikiversity

/* Checking form function */
function checkForm(){
	window.alert("You clicked Submit!");
	var fullNameCheck = document.getElementById("fullname");
	var addressCheck = document.getElementById("streetaddr");
	var quantityCheck = document.getElementById("quantity");
	var is_valid = false;
	/* If statements to check if text box is empty */
	if (fullNameCheck.value=="" && addressCheck.value=="" && quantityCheck.value=="") {
		document.getElementById("nameerrormsg").style.display="inline";
		document.getElementById("addrerrormsg").style.display="inline";
		document.getElementById("qtyerrormsg").style.display="inline";
		is_valid = false;
	} else if(fullNameCheck.value==""){
		document.getElementById("nameerrormsg").style.display="inline";
		document.getElementById("addrerrormsg").style.display="none";
		document.getElementById("qtyerrormsg").style.display="none";
		is_valid = false;
	} else if (addressCheck.value==""){
		document.getElementById("addrerrormsg").style.display="inline";
		document.getElementById("nameerrormsg").style.display="none";
		document.getElementById("qtyerrormsg").style.display="none";
		is_valid = false;
	} else if (quantityCheck.value==""){
		document.getElementById("qtyerrormsg").style.display="inline";
		document.getElementById("nameerrormsg").style.display="none";
		document.getElementById("addrerrormsg").style.display="none";
		is_valid = false;
	} else {
		document.getElementById("nameerrormsg").style.display="none";
		document.getElementById("addrerrormsg").style.display="none";
		document.getElementById("qtyerrormsg").style.display="none";
		is_valid = true;

	} return is_valid;
}

	
.errormsg{
	color: red;
	background-color: yellow;
	display: none;
}
<form action="mailto:[email protected]" onsubmit="return checkForm();">
    <fieldset>

      <legend>Personal details</legend>
      <p>
        <label>
          Full name:
          <input type="text" name="fullname" id="fullname">
        </label>
      </p>
      <p class="errormsg" id="nameerrormsg">Please enter your name above</p>

      <p>
        <label>
          Street Address:
          <input type="text" name="streetaddr" id="streetaddr">
        </label>
      </p>
      <p class="errormsg" id="addrerrormsg">Please enter your street address</p>

      <!-- Quantity input -->
      <p>
        <label>
          Quantity:
          <input type="text" name="quantity" id="quantity">
        </label>
      </p>
      <p class="errormsg" id="qtyerrormsg">Please enter your quantity</p>

    </fieldset>
    <input type="submit" value="Submit it!"> 
  </form>

Upvotes: 0

Views: 13116

Answers (2)

CertainPerformance
CertainPerformance

Reputation: 370779

I'd prefer to just make the fields required, no Javascript needed:

<form action="mailto:[email protected]" onsubmit="return checkForm();">
  <fieldset>

    <legend>Personal details</legend>
    <p>
      <label>
          Full name:
          <input type="text" name="fullname" id="fullname" required>
        </label>
    </p>

    <p>
      <label>
          Street Address:
          <input type="text" name="streetaddr" id="streetaddr" required>
        </label>
    </p>

    <!-- Quantity input -->
    <p>
      <label>
          Quantity:
          <input type="text" name="quantity" id="quantity" required>
        </label>
    </p>

  </fieldset>
  <input type="submit" value="Submit it!">
</form>

Otherwise, you can first hide all the error messages. Iterate over all inputs in the form, and if invalid (missing), navigate to its ancestor p and then to the adjacent .errormsg and set its display.

It would also be a good idea to avoid inline handlers entirely, they have too many problems to be worth using. Attach listeners properly using addEventListener in Javascript instead.

document.querySelector('form').addEventListener('submit', () => {
  for (const errormsg of document.querySelectorAll('.errormsg')) {
    errormsg.style.display = 'none';
  }
  let valid = true;
  for (const input of document.querySelectorAll('form input')) {
    if (input.value) {
      // valid
      continue;
    }
    valid = false;
    input.closest('p').nextElementSibling.style.display = 'inline';
  }
  return valid;
});
.errormsg{
	color: red;
	background-color: yellow;
	display: none;
}
<form action="mailto:[email protected]">
    <fieldset>

      <legend>Personal details</legend>
      <p>
        <label>
          Full name:
          <input type="text" name="fullname" id="fullname">
        </label>
      </p>
      <p class="errormsg" id="nameerrormsg">Please enter your name above</p>

      <p>
        <label>
          Street Address:
          <input type="text" name="streetaddr" id="streetaddr">
        </label>
      </p>
      <p class="errormsg" id="addrerrormsg">Please enter your street address</p>

      <!-- Quantity input -->
      <p>
        <label>
          Quantity:
          <input type="text" name="quantity" id="quantity">
        </label>
      </p>
      <p class="errormsg" id="qtyerrormsg">Please enter your quantity</p>

    </fieldset>
    <input type="submit" value="Submit it!"> 
  </form>

Upvotes: 3

prasanth
prasanth

Reputation: 22500

You could hide all the error text as initially. Then show the error text based on respected input failure

/* Checking form function */
function checkForm() {
  window.alert("You clicked Submit!");
  var fullNameCheck = document.getElementById("fullname");
  var addressCheck = document.getElementById("streetaddr");
  var quantityCheck = document.getElementById("quantity");
  var is_valid = false;
  /* If statements to check if text box is empty */
  document.getElementById("nameerrormsg").style.display = "none";
  document.getElementById("addrerrormsg").style.display = "none";
  document.getElementById("qtyerrormsg").style.display = "none";
  is_valid = true;

  if (fullNameCheck.value == "") {
    document.getElementById("nameerrormsg").style.display = "inline";
    is_valid = false;
  }
  if (addressCheck.value == "") {
    document.getElementById("addrerrormsg").style.display = "inline";
    is_valid = false;
  }
  if (quantityCheck.value == "") {
    document.getElementById("qtyerrormsg").style.display = "inline";
    is_valid = false;
  }
  return is_valid;
}
.errormsg {
  color: red;
  background-color: yellow;
  display: none;
}
<form action="mailto:[email protected]" onsubmit="return checkForm();">
  <fieldset>

    <legend>Personal details</legend>
    <p>
      <label>
          Full name:
          <input type="text" name="fullname" id="fullname">
        </label>
    </p>
    <p class="errormsg" id="nameerrormsg">Please enter your name above</p>

    <p>
      <label>
          Street Address:
          <input type="text" name="streetaddr" id="streetaddr">
        </label>
    </p>
    <p class="errormsg" id="addrerrormsg">Please enter your street address</p>

    <!-- Quantity input -->
    <p>
      <label>
          Quantity:
          <input type="text" name="quantity" id="quantity">
        </label>
    </p>
    <p class="errormsg" id="qtyerrormsg">Please enter your quantity</p>

  </fieldset>
  <input type="submit" value="Submit it!">
</form>

Upvotes: 1

Related Questions