Form Validation in Angular

Posted on - Last Modified on

These days, you'll see a lot of Web applications that include some kind of form, ranging from forms for registering and logging in, for subscribing to a mailing list, or simply offering a contact form that allows users to send a message to the website owner. Data validation is an important process because it can (most of the time) ensure that the data that you store or apply business logic to is correct.

Validation should always be done on the server side, but it shouldn't be limited to doing it there. Having client side validation in place also helps to reduce the roundtrips between the user's machine and the server. Reducing the load on the server also offers a better user experience because the user receives immediate feedback about the data entered without having to wait for the server's response.

Angular.js is one of the most popular client side SPA frameworks, and one that features great support for validation. Angular offers many built-in validators, plus you can define your own validation logic through directives. This article only covers some of the things that Angular.js validation is capable of, so please consult the documentation for more detailed scenarios. I assume you do have some basic knowledge of Angular.js so I don't need to cover basics like creating controllers or directives. For more information on these topics, you can check the Developing SPAs using Angular.js and Building Custom Angular.js Directives.

Here is the HTML from:

<body ng-controller="FormCtrl">
	
<form novalidate >
	<label for="manufacturer">Manufacturer:</label>
	<input id="manufacturer" type="text" ng-model="car.manufacturer" name="manufacturer" required />
	<br/>
	
	<label for="type">Car Type:</label>
	<input id="type" type="text" ng-model="car.type" name="type" required />
	<br/>

	<label for="model">Model:</label>
	<input id="model" type="text" ng-model="car.model" name="model" ng-model-options="{ updateOn: 'blur' }" required />
	<br/>

	<label for="manufactureYear">Manufacturer Year:</label>
	<input id="manufactureYear" type="number" ng-model="car.manufacturerYear" name="manufacturerYear" min="1900" max="2015" required year />
	<br/>

	<input type="submit" ng-click="car.print()" value="Print"/>
</form>
<br/>
Manufacturer - {{car.manufacturer}}
<br/>
Type - {{car.type}}
<br/>
Model - {{car.model}}

</body>

The novalidate attribute instructs the browser not to validate the form before submission. Using this attribute helps avoid instances of having browser and Angular.js validation at the same time. Here's an example: a form that has four fields – manufacturer, model, type and manufacturer year. All of the fields are assigned to the car object within the Angular scope, and all the four fields are required.

The model field is special, since this has set the ng-model-options attribute. The updateOn property can be used to set when the Angular validation should be executed. The value 'blur' will tell Angular to validate the input's value when that has lost the focus.

The manufacturer year is more special, since this has min and max attributes. For these, Angular provides built-in validation. The year attribute is a custom Angular.js directive used for validating the data entered by the user.

The Angular.js code:

var module = angular.module('formValidation',[]);
module.controller('FormCtrl', function($scope){
	$scope.car = {
		manufacturer: "BMW",
		type:"cabrio",
		model:"z4",
		manufacturerYear : 1986,
		print : function()  {
			console.log(this.manufacturer);
			console.log(this.type);
			console.log(this.model);
			console.log(this.manufacturerYear);
		}
	}
}).directive('year', function(){
	return {
		require: 'ngModel',
		link: function(scope, elm, attr, ctrl) {
			ctrl.$validators.year = function(modelValue, viewValue) {
				if(ctrl.$isEmpty(modelValue)) {
					return true; // I am accepting empty value as correct year
				}

				var currentYear = (new Date()).getFullYear();
				if(modelValue > currentYear || modelValue < 1900) {
					console.log(modelValue + ' is NOT valid.');
					return false;
				}

				console.log(modelValue + ' is valid.');
				return true;
			}
		}
	};
});

The custom validation in Angular.js should be assigned to the $validators object on the controller. There is another object, called $asyncValidators, that makes it possible to validate the date through HTTP requests.

The validator function receives two values, the modelValue and the viewValue. In this scenario, I only validated the modelValue so it's limited to a year between 1900 and the present. I also consider correct value if the model does not have any data.

When rendered, the form won't look good because it doesn't have any styling, but if you look at the validation logic and console logs, you'll see how everything works:

angular validation

Posted 19 May, 2015

Greg Bogdan

Software Engineer, Blogger, Tech Enthusiast

I am a Software Engineer with over 7 years of experience in different domains(ERP, Financial Products and Alerting Systems). My main expertise is .NET, Java, Python and JavaScript. I like technical writing and have good experience in creating tutorials and how to technical articles. I am passionate about technology and I love what I do and I always intend to 100% fulfill the project which I am ...

Next Article

Three Deadly Freelancing Misconceptions for Starters