JavaScript Validation

A live validating JavaScript contact form

I am going to start out with a little theory behind what JavaScript validation should be used for. JavaScript validation can never exist by itself, there must always be server side validation. JavaScript validation only exists to aid in the user experience, which is a good reason why it should be validating live as the user types.

What we are going to build

In this example we will be building a simple contact form page and using JavaScript to validate it as users fill it out. This way it won’t be necessary for the user to submit the form before finding out something is wrong. They will be alerted in real time as they type.

See the Pen Display only by mitchel p Wassler (@MpWassler) on CodePen.

This is not a basic HTML and CSS tutorial however, so I will show the code for the form and styling but I will not discuss it in great detail. Ideally, the JavaScript we write here will be able to be ported to any form you choose.

The HTML

 

<body>
  <form>
    <h1>Contact Form</h1>
    <div>
      
      <span>name  </span><input  type="text" id="name" name="full_name" />
      <span>email</span><input type="text" id="email" name="email" />
      <span>phone</span><input type="text" id="phone" name="phone" />
    </div>
    <div>
      <span>comment</span><textarea name="message" id="message" name="message" cols="30" rows="8"></textarea>
      <input type="submit" id="submit" name="submitted" />
    </div>  
  </form>  
</body> 
  
 

See the Pen Live Validateing Form step1 by mitchel p Wassler (@MpWassler) on CodePen.

The CSS

 

input,textarea{
  display:block;
  padding-left: 10px;
  width:100%;
  border-radius:8px;
  background-color:#eeeeff;
            
}

h1{
  margin:0;
  font-weight:normal;
}
input{
  
  height:1.55em;
}
input[type="submit"]{
  width:80px;
  float:right;
  margin-top:1.5em;
  display:none;
}
input.pop{
  display:block;
}
body{
  width:100%;
  font-size:16px;
  color:#eeeeff;
  font-family:arial;
  background: #f2f6f8;
  background: -webkit-linear-gradient(#f2f6f8 0%, #d8e1e7 50%, #b5c6d0 51%, #e0eff9 100%);
  background: -moz-linear-gradient(#f2f6f8 0%, #d8e1e7 50%, #b5c6d0 51%, #e0eff9 100%);
  background: linear-gradient(#f2f6f8 0%, #d8e1e7 50%, #b5c6d0 51%, #e0eff9 100%); 
}
form{
  background-color: #437587;
  width:600px;
  padding:20px;
  border-radius:8px;
  margin: 40px auto auto 140px;
}
form:after{
  content:'.';
  display:table;
  clear:both;
  visibility:hidden;
}
form div{
  width:260px;
  line-height:1.8em;
  float:left;
  margin-right:40px;
}

span.error:after{
  content:'\2715';
  float:right;
    
}
span.no_error:after{
  content:'\2713';
  float:right;
}

See the Pen cssOnly by mitchel p Wassler (@MpWassler) on CodePen.

The JavaScript

We will start by defining the validate() function. All our code will go inside this function..next we will plan out what it is we need to do the steps are as follows

//select our form elements
//define regular expressions to check the form elements
//function check if all the form elements are filled out correctly 
//function to validate each form element
//add an event listener to listen for changes in the form input fields 

See the Pen Live Validateing Form step2 by mitchel p Wassler (@MpWassler) on CodePen.

Select our elements

Then we will select all the form elements using the querySelectior() method. The form elements are being selected by their name attribute

function valadate(){
//select our form elements
  
  var submit  = document.querySelector ( 'input[name="submitted"]' ),
      name    = document.querySelector ( 'input[name="full_name"]' ),
      email   = document.querySelector ( 'input[name="email"]'     ),
      phone   = document.querySelector ( 'input[name="phone"]'     ),
      message = document.querySelector ( 'textarea[name="message"]');
//define regular expressions to check the form elements
//function check if all the form elements are filled out correctly 
//function to validate each form element
//add an event listener to listen for changes in the form input fields 
}       
valadate();  

See the Pen Live Validateing Form step3 by mitchel p Wassler (@MpWassler) on CodePen.

Next we will add the various regular expressions which we will be using to validate our different form elements. Regular expressions, especially for emails, can get quite long. I wont pretend to be an expert on regular expressions and if they confuse you as well, don’t worry, you can usually find already made regular expressions for whatever you need with a quick Google search.

function valadate(){
//select our form elements
//define regular expressions to check the form elements
    var eRegX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
      pRegX = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
      nRegX = /^([^0-9]*)$/,
      mRegX = /.*/;
  
//function check if all the form elements are filled out correctly 
//function to validate each form element
//add an event listener to listen for changes in the form input fields 
}       
valadate();  

See the Pen Live Validateing Form step4 by mitchel p Wassler (@MpWassler) on CodePen.

Check all inputs

Next we will write a function to be called repeatedly that will check to see if all elements of the form are filled out correctly. This function will be called from within the function that checks each form element for errors. It is checking the noError property of each of the variables declared for different form elements. We will add this property in the next function as well.

 

For now, we are checking to see when we get all the noError properties to equal true, and then we add a CSS class to reveal the submit button. Keep in mind that this function will get called every time a user puts something in the input fields.

function valadate(){
//select our form elements
//define regular expressions to check the form elements
//function check if all the form elements are filled out correctly 
  function errorCheck(){
    
     if ( name.noError    == true &&
          phone.noError   == true &&
          email.noError   == true &&
          message.noError == true ){   
        
           submit.classList.add("pop");
      
     }else{ 
       
           submit.classList.remove("pop");
    } 
  }
//function to validate each form element
//add an event listener to listen for changes in the form input fields 
}       
valadate();  

See the Pen Live Validateing Form step5 by mitchel p Wassler (@MpWassler) on CodePen.

The first step is to declare our noError property and default it to false. Then we will define the check property as this.value. Remember we are going to be making the this keyword apply to the form elements themselves so this.value will be the user input in each element. Next, we check that there is a value and that the value is not an empty string. Then we will check it against the regular expression.  

function valadate(){
//select our form elements
//define regular expressions to check the form elements
//function check if all the form elements are filled out correctly 
//function to validate each form element
  function mainValidate(){
    
     this.noError = false;
    
     var check = this.value;
    
     if( check       &&
         check != '' &&
         arguments[0].test(check)){
       
         this.noError = true;
         this.previousElementSibling.classList.add    ( "no_error" );
         this.previousElementSibling.classList.remove ( "error"    );
       
     }else{
      
         this.previousElementSibling.classList.remove ( "no_error" );
         this.previousElementSibling.classList.add    ( "error"    );
    }
      return errorCheck();
  }
//add an event listener to listen for changes in the form input fields 
}       
valadate();  

See the Pen other by mitchel p Wassler (@MpWassler) on CodePen.

However, you might notice the regular expression is not anywhere to be found in this function. That is where the arguments keyword comes into play. The arguments keyword behaves like an array and allows you to access parameters passed to a function that were not defined when the function was created. Bear with me for a second; it will all make sense soon.

If it passes validation, we set the no error parameter to true and then walk up the dom to the previous element before the input field, which is the span tag label, and add a class that toggles a check mark. Here i’m using the previousElementSibling method, which is relatively new, so if you need to support older browsers you may have to use the previousSibling method and check each value returned until you find an element( it will also grab text nodes).

If it fails to validate, we remove the check mark and add an x. I’m using HTML special characters for the x and check mark to keep it simple, but you can use anything you want. The CSS is listed below.



span.error:after{
  content:'\2715';
  float:right;
    
}
span.no_error:after{
  content:'\2713';
  float:right;
}

See the Pen Live Validateing Form step1 by mitchel p Wassler (@MpWassler) on CodePen.

Make it work

The final part of this tutorial is to attach our event listeners to the form elements. To do this we will use window.addEventListener, listen for the “input” event, then call our mainValidate function. To make this work for each individual form element we use the bind method on our function call. Bind allows us to change the target of a functions this keyword. Basically we are now using each of our four form element variables as individual objects now (in JavaScript everything is technically an object).   To make this work for each individual form element we use the bind method on our function call. Bind allows us to change the target of a function’s this keyword. Basically, we are now using each of our four form element variables as individual objects. In JavaScript everything is technically an object.

function valadate(){
//select our form elements
//define regular expressions to check the form elements
//function check if all the form elements are filled out correctly 
//function to validate each form element
//add an event listener to listen for changes in the form input fields
  window.addEventListener( 'input', mainValidate.bind (name,    nRegX),  false);
  window.addEventListener( 'input', mainValidate.bind (email,   eRegX),  false);
  window.addEventListener( 'input', mainValidate.bind (phone,   pRegX),  false);
  window.addEventListener( 'input', mainValidate.bind (message, mRegX),  false);
}       
valadate();  

See the Pen Live Validateing Form step6 by mitchel p Wassler (@MpWassler) on CodePen.

The second parameter of the bind method allows us to pass extra parameters into the function we are calling it on. We are doing it this way so that we can pass in parameters without invoking the function immediately or using anonymous functions. The parameters we are passing in are our regex variables. These will take the place of the arguments keyword in the mainValidate function.

 

And there you have it. We have an extremely lightweight, simple, user friendly form validation. Again, remember to always validate on the server as well and feel free to make any changes and use it however you would like.

function valadate(){
  //select our form elements
  var submit  = document.querySelector ( 'input[name="submitted"]' ),
      name    = document.querySelector ( 'input[name="full_name"]' ),
      email   = document.querySelector ( 'input[name="email"]'     ),
      phone   = document.querySelector ( 'input[name="phone"]'     ),
      message = document.querySelector ( 'textarea[name="message"]');
  //define regular expressions to check the form elements
  var eRegX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
      pRegX = /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
      nRegX = /^([^0-9]*)$/,
      mRegX = /.*/;
  // check if all the form elements are filled out correctly 
  function errorCheck(){
    
     if ( name.noError    == true &&
          phone.noError   == true &&
          email.noError   == true &&
          message.noError == true ){   
        
           submit.classList.add("pop");
      
     }else{ 
       
           submit.classList.remove("pop");
    } 
  }
  //function to validate each form element
  function mainValidate(){
    
     this.noError = false;
    
     var check = this.value;
    
     if( check       &&
         check != '' &&
         arguments[0].test(check)){
       
         this.noError = true;
         this.previousElementSibling.classList.add    ( "no_error" );
         this.previousElementSibling.classList.remove ( "error"    );
       
     }else{
      
         this.previousElementSibling.classList.remove ( "no_error" );
         this.previousElementSibling.classList.add    ( "error"    );
    }
      return errorCheck();
  }
  //add an event listener to listen for changes in the form input fields 
  window.addEventListener( 'input', mainValidate.bind (name,    nRegX),  false);
  window.addEventListener( 'input', mainValidate.bind (email,   eRegX),  false);
  window.addEventListener( 'input', mainValidate.bind (phone,   pRegX),  false);
  window.addEventListener( 'input', mainValidate.bind (message, mRegX),  false);
  
}       
valadate();  

See the Pen Live Validateing Contact Form by mitchel p Wassler (@MpWassler) on CodePen.

Awwwards