GeorgeS
GeorgeS

Reputation: 107

Validation form with JavaScript

I'm trying to create a form validation, in pure JavaScript. I have two elements to validate, a select option and a checkbox, but I can't manage to make the select-option to work.

This is the first time I try this, please be patient:

var registrationForm, elSelectGender, elGenderHint, elTerms, elTermsHint; // Declare variables
registrationForm = document.getElementById('registrationForm'); // Store elements
elSelectGender = document.getElementById('gender');
elGenderHint = document.getElementById('genderHint');
elTerms = document.getElementById('terms');
elTermsHint = document.getElementById('termsHint');
elName = document.getElementById('firstName');
elNameHint = document.getElementById('nameHint');

function checkName(event) {
  if (elSelectGender.valueOf() == null) { // If name not entered
    elNameHint.innerHTML = 'You must insert your name.'; // Show message
    event.preventDefault(); // Don't submit form
  }
}

function checkGender(event) {
  if (elSelectGender.valueOf() == 'Select an option:') { // If gender not selected
    elGenderHint.innerHTML = 'You must select a gender.'; // Show message
    event.preventDefault(); // Don't submit form
  }
}

function checkTerms(event) {
  if (!elTerms.checked) { // If check-box ticked
    elTermsHint.innerHTML = 'You must agree to the terms.'; // Show message
    event.preventDefault(); // Don't submit form
  }
}

//Create event listeners: submit calls checkTerms(), change calls packageHint()
registrationForm.addEventListener('submit', checkName, false);
registrationForm.addEventListener('submit', checkGender, false);
registrationForm.addEventListener('submit', checkTerms, false);
<!DOCTYPE HTML>
<html>
<form id="registrationForm" name="registrationForm" method="post" action="example.html">

  <div>
    <label for="firstName" class="input"> Name: </label>
    <input name="firstName" class="form-control" id="firstName" placeholder="First Name" type="text" />
    <div id="nameHint" class="warning"></div>
  </div>

  <div>
    <label for="gender" class="selectbox"> Gender: </label>
    <select id="gender">
      <option value="Select an option:">Select an option:</option>
      <option value="Male">Male</option>
      <option value="Female">Female</option>
      <option value="I prefer not to say">I prefer not to say</option>
    </select>
    <div id="genderHint" class="warning"></div>
  </div>

  <div>
    <input type="checkbox" id="terms" />
    <label for="terms" class="checkbox"> Check to agree to terms &amp; conditions</label>
    <div id="termsHint" class="warning"></div>
  </div>

  <input class="btn btn-primary" id="submitButton" type="submit" value="Sign up for G Holiday" />
</form>

</html>

I expect to have a warning message and validation for all three elements. If one of the three elements is not validated, it shouldn't go to the next page. It only works for the checkbox for some reason, the other two elements are ignored.

Upvotes: 3

Views: 143

Answers (2)

Roko C. Buljan
Roko C. Buljan

Reputation: 206689

I'd wrap the selects and inputs into label and use CSS to display the .warning error messages.
Than I'd use Array.prototype.some() to check for any of my elements does not passes a check to than use ev.preventDefault() and display the warnings:

const EL = sel => document.querySelector(sel),
  warning = (el, err) => [err, el.closest('label').classList.toggle('is-error', err)][0],
  noValue = el => warning(el, !el.value.trim()),
  noCheck = el => warning(el, !el.checked),
  checkFormRegistration = ev => {
    const isSomeInvalid = [
      noValue(EL('#firstName')),
      noValue(EL('#gender')),
      noCheck(EL('#terms'))
    ].some(b => b);
    if (isSomeInvalid) ev.preventDefault();
  };

EL('#registrationForm').addEventListener('submit', checkFormRegistration);
label.is-error > *{
  outline: 1px solid red;
  outline-offset: -1px;
}
label + .warning {
  display: none;
  color: red;
}
label.is-error + .warning {
  display: block;
}
<form id="registrationForm" name="registrationForm" method="post" action="example.html">

  <div>
    <label> Name:
      <input name="firstName" class="form-control" id="firstName" placeholder="First Name" type="text">
    </label>
    <div class="warning">Please, enter a name</div>
  </div>

  <div>
    <label> Gender: 
      <select id="gender">
        <option value="">Select an option:</option>
        <option value="Male">Male</option>
        <option value="Female">Female</option>
        <option value="I prefer not to say">I prefer not to say</option>
      </select>
    </label>
    <div class="warning">Please, select a gender</div>
  </div>

  <div>
    <label>
      <input type="checkbox" id="terms">
      Check to agree to terms &amp; conditions
    </label>
    <div class="warning">You must agree to the terms</div>
  </div>

  <input class="btn btn-primary" id="submitButton" type="submit" value="Sign up for G Holiday">
</form>

Upvotes: 2

carkod
carkod

Reputation: 2230

I changed valueOf() to value equal to empty (when form is initialized, the field is empty, it is not null).

Make sure that your HTML elements are correct, I saw it was wrong before, now it seems to have been corrected.

I added an else statement to handle the errors in the case where the user corrects the validation errors.

Still, this is quite a simplification of validation, it takes a lot more work (things like min-length, max-length you might want to consider them too, as well as sanitization, trimming as mentioned by some commenters, which I will leave it to you).

var registrationForm, elSelectGender, elGenderHint, elTerms, elTermsHint; // Declare variables
registrationForm = document.getElementById('registrationForm'); // Store elements
elSelectGender = document.getElementById('gender');
elGenderHint = document.getElementById('genderHint');
elTerms = document.getElementById('terms');
elTermsHint = document.getElementById('termsHint');
elName = document.getElementById('firstName');
elNameHint = document.getElementById('nameHint');

function checkName(event) {
  if (elName.value == '') { // If name not entered
    elNameHint.innerHTML = 'You must insert your name.'; // Show message
    event.preventDefault(); // Don't submit form
  } else {
    elNameHint.innerHTML = '';
  }
}

function checkGender(event) {
  if (elSelectGender.value == 'Select an option:') { // If gender not selected
    elGenderHint.innerHTML = 'You must select a gender.'; // Show message
    event.preventDefault(); // Don't submit form
  } else {
    elGenderHint.innerHTML = '';
  }
}

function checkTerms(event) {
  if (!elTerms.checked) { // If check-box ticked
    elTermsHint.innerHTML = 'You must agree to the terms.'; // Show message
    event.preventDefault(); // Don't submit form
  } else {
    elTermsHint.innerHTML = '';
  }
}

//Create event listeners: submit calls checkTerms(), change calls packageHint()
registrationForm.addEventListener('submit', checkName, false);
registrationForm.addEventListener('submit', checkGender, false);
registrationForm.addEventListener('submit', checkTerms, false);
<!DOCTYPE HTML>
<html>
<form id="registrationForm" name="registrationForm" method="post" action="example.html">

  <div>
    <label for="firstName" class="input"> Name: </label>
    <input name="firstName" class="form-control" id="firstName" placeholder="First Name" type="text" />
    <div id="nameHint" class="warning"></div>
  </div>

  <div>
    <label for="gender" class="selectbox"> Gender: </label>
    <select id="gender">
      <option value="Select an option:">Select an option:</option>
      <option value="Male">Male</option>
      <option value="Female">Female</option>
      <option value="I prefer not to say">I prefer not to say</option>
    </select>
    <div id="genderHint" class="warning"></div>
  </div>

  <div>
    <input type="checkbox" id="terms" />
    <label for="terms" class="checkbox"> Check to agree to terms &amp; conditions</label>
    <div id="termsHint" class="warning"></div>
  </div>

  <input class="btn btn-primary" id="submitButton" type="submit" value="Sign up for G Holiday" />
</form>

</html>

Upvotes: 1

Related Questions