Thursday, 16 April 2015

Form Validation in Ionic or AngularJS

On this post we will see how to do form validation in AngularJS or Ionic framework. At the moment, Ionic framework does not have its own validation features and relies on the underlying framework.

Basic Usage with Built-In Validators
To begin, first we need to make sure that we have a reference to angular.js file. Then we need to do the following steps:
- give a name to our form
- put novalidate="" attribute on the form
So we should have something like this on our form:
<form name="myForm" novalidate="" ng-submit="" >
 . . .
</form>
- add a unique name to each input field
- add validation attributes that we need on the input fields. AngularJS provides some validation directives such as these; required, pattern, minlength, maxlength, min and max. It also has basic built-in validators for these input types; text, number, url, email and date.
An example on an input field:
<input type="text" name="name" ng-model="vm.input.name" required />
- add an error message to be displayed for each validator checking the corresponding property name on input field's $error object in conditional statement like ng-if or ng-show. Properties under $error object with the same names as the validators' names exist for us to use. The properties are on this format; formName.fieldName.$error.builtInValidatorName. For example:
<span ng-show="myForm.name.$error.required == true">* required</span>
- on a method that is called in ng-submit, check whether the form is valid using formName.$valid before doing any action

Below is a complete example:
<!-- HTML page -->
<body ng-app="validationExample">
    <div ng-controller="MyCtrl as vm">
      <form name="myForm" novalidate="" ng-submit="vm.submitted(myForm, vm.input)">
        <div>
          <input type="text" name="name" ng-model="vm.input.name" required>
          <span ng-show="myForm.name.$error.required == true">test: * required</span>
        </div>
        <button>submit</button>
      </form>
    </div>
</body>

// JavaScript codes
var myApp = angular.module('validationExample', [])

myApp.controller('MyCtrl', [function () {
    var vm = this;
    vm.submitted = function(form, input) {
      if(form.$valid) {
        // post the form
        . . .
      }
    }
} ]);
See these codes on Plunker.


Creating Custom Validator
If we would like to create a custom validator, we would need to do these in addition of the above steps:
- create a directive
- on the directive's link function, use the new AngularJS $validators object on ngModel controller to do the validation. We need to create a function property on ngModel.$validators. By doing so, we register the function as a new validation rule. Each time the model changes, the validation rule is invoked. For example:
link: function(scope, element, attributes, ngModel) {
 ngModel.$validators.wrongInitial = function(modelValue) {
   . . .
 };
}
A corresponding property on input field's $error object is also created that can be used for checking validity.
- similar like in using built-in validator, we need to add an error message to be displayed by checking the newly created corresponding property on the input field's $error object:
<span ng-show="myForm.name.$error.wrongInitial == true">* must start with letter r</span>

Additional codes to be added from the first example:
<!-- HTML page -->
<input type="text" name="name" ng-model="vm.input.name" start-with-r />
<span ng-show="myForm.name.$error.wrongInitial == true">* must start with letter r</span>

// JavaScript codes
myApp.directive("startWithR", function() {
    return {
      restrict: "A",
      require: "?ngModel",
      link: function(scope, element, attributes, ngModel) {
        ngModel.$validators.wrongInitial = function(modelValue) {
          if (modelValue) {
            return modelValue.charAt(0).toUpperCase() == 'R';
          }
          else {
            return true;
          }
        };
      }
    };
});
See a complete example on Plunker.


Using ngMessages to Display Error Messages
In the recent version of AngularJS, started with version 1.3, there is a new feature that we could use to display messages including form error messages. To use this, we need to:
- include a reference to angular-messages.js file in our page
- inject ngMessages module to our AngularJS app
var myApp = angular.module('validationExample', ['ngMessages'])
- if there are only a few fields to be validated, we could specify each error message for each field like this:
<!-- use ng-messages with each field's $error object in this format; formName.fieldName.$error -->
<div ng-messages="myForm.name.$error" >  
        <!-- specify an error message for each validator -->
 <span ng-message="required">Name is required!</span>
 <span ng-message="wrongInitial">Name must start with letter r</span>
</div>
- however if we know that we are going to repeat this multiple times, we could use a template instead:
<!-- create a template by using script tag with type="text/ng-template" and give an Id -->
<script id="errors-template.html" type="text/ng-template" >  
        <!-- specify an error message for each validator -->
 <span ng-message="required">* required!</span>
 <span ng-message="wrongInitial">* must start with letter r!</span>
</script>
Then use the template to display error message(s) on each field:
<!-- use ng-messages with each field's $error object and ng-messages-include referring to the template Id -->
<span ng-messages="myForm.name.$error" ng-messages-include="errors-template.html" />
See the complete example on Plunker.


References:
Working with Validators and Messages in AngularJS
Validation in Ionic Framework Apps with ngMessages

2 comments:

Raju Kumar said...

Excellent information with unique content and it is very useful to know about the information based on blogs.this is valuable information for learners.thanks
Angularjs Training In Hyderabad

Kate said...

Great explanation.We can also use ng-pristane ,ng-dirty etc to know the field state.

AngularJs Course
AngularJs Training in Chennai