Saturday, 8 June 2013

Showing Validation Messages In Bulk While Validating Form Using Angular JS

Form validation is an integral part of any typical business application. In one of my posts, I demonstrated validating user inputs using Angular JS. The approach used in that post shows the error messages as soon as the user enters some data in the input fields. But, in some scenarios the users like to see the error messages just before the values are submitted. In this post, we will see an example with such behavior.

Following is the HTML mark-up of the form that we will be validating in this post:

<div ng-app="shopping">
    <div ng-controller="ShoppingCartCtrl">
        <form novalidate name="itemForm">
     <table>
         <tr>
      <td>Name: </td>
          <td><input name="name" type="text" ng-model="item.Name" required ng-pattern="name" /></td>
         </tr>
  <tr>
      <td>Price: </td>
      <td><input name="price" type="text" ng-model="item.Price" required  valid-price /></td>
  </tr>
  <tr>
      <td>Quantity: </td>
                    <td><input name="quantity" type="number" ng-model="item.Quantity" min="1" max="90" ng-pattern="integerval" required /></td>
  </tr>
  <tr>
      <td colspan="2"><input type="Button" value="Add" ng-click="addItem(item)" /> </td>
         </tr>
     </table>
 </form>
 <div id="errMessages" class="errors">
     <ul>
         <li ng-repeat="message in failedValidations">{{message}}</li>
            </ul>
 </div>
    </div>
</div>

While debugging the script of this form using a browser’s developer tools, I found the property $scope.itemForm.$error set with details of failed validations in a form. Following screenshot shows the contents of this property at an instance:



One can easily observe the following in the above screenshot:
  • Three of the validations of the form were failed here: a pattern based validator, a required field validator and a custom validator that checks for validity of price
  • For each type of validation, an array gets created internally that holds the details of the fields on which the validations were failed
To show the messages in bulk, we need to inspect these arrays and append the error messages dynamically. To keep it simple, let’s store the error messages all of the fields in an object.

var errorMessages={
 name:function(){
  required="Name cannot be left blank";
  pattern="Name cannot contain numbers or special characters";
  return{
   required: required,
   pattern: pattern
  };
 }(),
 price:function(){
  required= "Price cannot be blank";
  validPrice="Price should be a number between 50 and 5000 with maximum 2 digits after decimal point"  
  return{
   required: required,
   validPrice:validPrice
  }
 }(),
 quantity:function(){
  required="Quantity cannot be blank";
  validQuantity="Quantity should be an integer between 1 and 90";
  return{
   required: required,
   min: validQuantity,
   max: validQuantity,
   pattern: validQuantity
  }
 }()      
};

As stated earlier, we have to loop through the properties of $error property to get the errors in the form. Using this data, we will pick the appropriate error message from the object created above and push the message into an array. Following code does this for us:
if($scope.itemForm.$dirty && $scope.itemForm.$invalid){
    for(validations in $scope.itemForm.$error){
 for(count=0;count<$scope.itemForm.$error[validations].length;count++){
            $scope.failedValidations.push(errorMessages[$scope.itemForm.$error[validations][count].$name][validations]);
        }
    }
}
else{
    $scope.itemForm.$setPristine();
    //Submit the form values to server
    item = {};
}

You can play with the sample on jsfiddle:



Happy coding!

No comments:

Post a Comment