Thursday, June 06, 2013

Add custom method to jQuery Form Validation plugin

We have used JQuery form validation plugin many times like in "contact us" forms. Problem occurs when any field has a hint text specified. For example, suppose "firstname" text input field has a hint-text "Enter firstname here". When this plugin validates for  emptiness, the value "Enter firstname here" successfully passes the test but this is not right.

In such situations we would require to add custom validation method to jQuery Validator plugin.

I am showing one "contact us" form with 2 required fields "firstname" and "lastname". Here is the code and HTML.

<script>
  $(document).ready(function(){
   
    // Contact Form Submission Handler
    $("#contactUsForm").validate(
    {
    messages:
    {
         firstname: "Enter your firstname",
         lastname:  "Enter your lastname",
        },
   
    submitHandler: function(form)
    {
      jQuery.ajax(
      {
        url: form.action,
        type: form.method,
        data: $(form).serialize(),
        success: function(response)
        {
          if( response == "1") // Success
          {
            // Reset the form
            document.getElementById("contactUsForm").reset()
          }
          else // Failure
          {
            // Do stuff when failed
          }
       }           
     });
    }
     });
  });
</script>

<form id='contactUsForm' method="post">

<input type="text" name="firstname"  id="firstname" class="required">
<input type="text" name="lastname" id="lastname" class="required">
<input class="form-element" name="Submit" value="Submit" type="submit">

</form>


JQuery validation plugin needs class='required' to be added to the required fields. The messages parameters holds all error messages to be shown for each element specified. When the Submit button is clicked, the form is validated through the validation plugin. Error messages are shown if  required fields are empty. If any "email" field is given class='required email', then that field would be checked for both emptiness and email format. But what if the fields have hint-text as shown below? These fields get validated and they pass in empty testing which should not be the case.

<input type="text" name="firstname" id="firstname" value='Your First Name' onfocus="javascript:if(this.value=='Your First Name') this.value='';" onblur="javascript:if(this.value=='') this.value='Your First Name';" >

<input type="text" name="lastname" id="lastname" value='Your Last Name' onfocus="javascript:if(this.value=='Your Last Name') this.value='';" onblur="javascript:if(this.value=='') this.value='Your Last Name';">


To manage such situations we need to add some custom methods to the jQuery Validator object as shown below. We also need to add new Rule to it.

<script>
  $(document).ready(function(){
   
    // Our NEW custom method   
    jQuery.validator.addMethod("rem_default_val", function(value, element)
    {
       // Default Value Check for firstname
       if(element.value == "Your First Name" && element.name == "firstname")
       { jQuery('#firstname').focus(); return false; }

       // Default Value Check for lastname
       if(element.value == "Your Last Name" && element.name == "lastname")
       { jQuery('#lastname').focus(); return false; }
      
    });
   
   
    // Contact Form Submission Handler
    $("#contactUsForm").validate(
    {
    // Define a new Rule
    rules:
    {
       firstname: "required rem_default_val",
       lastname: "required rem_default_val",
    },
   
    messages:
    {
         firstname: "Enter your firstname",
         lastname:  "Enter your lastname",
        },
   
    submitHandler: function(form)
    {
      /// .... AJAX form submissions
    }
     });
  });
</script>


Notice that class='required' may not be required if we add 'required' as a rule. We also add a method called rem_default_val() as a rule which means elements have to pass this validation method which is defined using addMethod() function.

New rules have been defined here ::

rules:
{
   firstname: "required rem_default_val",
   lastname: "required rem_default_val",
}


Our new custom validation method rem_default_val() tests default values in elements and returns FALSE if certain predefined values or hint-text or default text found.

jQuery.validator.addMethod("rem_default_val", function(value, element)
{
  // Default Value Check for firstname
  if(element.value == "Your First Name" && element.name == "firstname")
  { jQuery('#firstname').focus(); return false; }

  // Default Value Check for lastname
  if(element.value == "Your Last Name" && element.name == "lastname")
  { jQuery('#lastname').focus(); return false; }

});


This way, we can validate a form with elements having hint texts in them.

No comments: