Pages

Monday, 27 October 2014

AngularJS 1.3 was released around two weeks back. As the core Angular team says, it is the best AngularJS released till date. It comes with a bunch of new features and performance improvements.

One of the key changes in this release is the changes made to forms. The directives form and ngModel went through a number of changes to make it easier to perform validation. The framework has a new module, ngMessages that makes the job of displaying validation messages easier.

In the current release, FormController have following additional APIs:

$setUntouched(): A method that sets all controls in the form to untouched. It is good to call this method along with $setPristine()

$setSubmitted(): A method that sets the state of the form to submitted

$submitted: A boolean property that indicates if the form is submitted

NgModelController has the following additional APIs:

$setUntouched(): A method that sets the control to untouched state

$setTouched(): A method that sets the control to touched state

$validators: A list of synchronous validators that are executed when $validate method is called

$asyncValidators: A list of asynchronous validators that are executed when $validate method is called

$validate(): A method that executes all validators applied on the control. It calls all synchronous validators followed by asynchronous validators

$touched: Boolean property that indicates if the control is touched. It is automatically set to true as soon as cursor moves into the control

$untouched: Boolean property that indicates if the control is untouched

Note: Notice name of the form in the above snippet. It is not the way we usually name the HTML elements. We assigned a property of an object instead of a plain string name. Reason for using this is to make the form available in the controller instance. This approach is very useful in case of controllerAs syntax. (Credits: Josh Caroll’s blog post)

The process of defining custom validations has been simplified in AngularJS 1.3 with $validators and $asyncValidators. We don’t need to deal anymore with $setValidity() to set validity of the control.

In case of synchronous validations, we need to return a boolean value from the validator function. The validation is passed when result of the validator function is true; otherwise, it fails.

In the form, we are accepting min price and max price values. The form should validate that the value of min price is always less than value of max price. Following is the directive for this validation:

If the above validation fails, it sets invalid flag to greaterThan validation on the control. Name of the method set to $validators is used as the validator string.

Custom Asynchronous Validations

In some scenarios, we may have to query a REST API to check for validity of data. As AJAX calls happen asynchronously, the validator function has to deal with promises to perform the task.

For the demo, I created a dummy asynchronous method inside a factory that checks for existence of the new item name in a static array and resolves a promise with a boolean value. Following is the service:

The difference between synchronous and asynchronous validators is the API used to resister the validator and the return value of the validator method. As already stated, $asyncValidators of NgModelController is used to register the validator and the validator method has to return a promise. The validation passes when promise is resolved and the validation fails if the promise is rejected.

Following is the custom asynchronous validator that checks for unique name:

Displaying validation messages of the form in AngularJS had not been too good earlier. It used to take a lot of mark-up and conditions to make them look user-friendly. AngularJS 1.3 has a new module, ngMessages that simplifies this task. If you refer to the module definition statement in the controller script, it has a dependency on ngMessages module. This module doesn’t come by default as part of the core framework, we have a separate file for this module.

The ngMessage module contains two directives that help in showing messages:

ngMessages: Shows or hides messages out of a list of messages

ngMessage: Shows or hides a single message

The directives in ngMessages module support animations as well. I will cover that in a future post.

In case of displaying form validation messages, ngMessages is set to the $error property of the form object and every occurrence of ngMessage element is set to the condition for which the message is has to be displayed.

By default, ngMessages displays the first message out of the list even if more than one message is relevant. It can b overridden using multiple or ng-messages-multiple attribute on the ngMessages directive.

The above message list is generic to the form; the messages are not specific to any of the control in the form. To display messages specific to form, you can use the $error property on the form element.

About Me

I am a software developer working on and passionate about Microsoft Technologies and anything new in the Web world. Lately, spending a lot of time with JavaScript and finding it much deeper than what I knew for past few years. I enjoy writing code and writing about code. My contribution to community earned me a Microsoft MVP award (ASP.NET/IIS) and a DZone MVB award. When not in front of computers, like to spend time with melodious Hindi and Telugu tunes or watching Cricket