How to create form with validation using ngMessages in AngularJS.

With the help of ngMessages (available from Angular 1.3), form validation is much easier to develop. Let’s see how we can do it.

See full demo on plunkr here


Create a basic form

<form name="form" novalidate ng-submit="submit()">
<div class="form-group">
<label>Email *</label>
<input name="email" ng-model="vm.data.email">
</div>
    <div class="form-gorup">
<label>Password</label>
<input name="password" ng-model="vm.data.password">
</div>
    <div class="form-group">
<label>Confirm password</label>
<input name="confirmPassword"
ng-model="vm.data.confirmPassword">
</div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>
  • Adding novalidate attribute to the form will disable HTML5 validation.
  • You need to specify name for the form and all the input elements (<form name=”form”>, <input name=”email”>, …). With this, a form object will be created, hold the state of our form and inputs. For example: form.$valid indicates that all input values of the form is valid or not, so is form.email.$valid; form.$submitted will be set to true when user clicks on submit button. We will find out more about this object in the next section.
If you want to investigate the form object, add this tag <pre ng-bind=”form|json></pre> to anywhere in your template.
  • Inside our controller, we must check for form validation before actually submit the data to server:
$scope.submit = function(){ 
if ($scope.form.$valid) {
// actually submit form data to server.
}
}

Add validators and ngMessages

If you want the email field is required and must match an email regex, using required and ngPattern like this

<div class="form-group">
<label>Email *</label>
<input name="email" ng-model="vm.data.email"
required ng-pattern="/^\S+@\S+$/">
<div ng-show="form.email.$touched || form.$submitted"
ng-messages="form.email.$error">
<p ng-message="required">Please enter your email</p>
<p ng-message="pattern">Please enter valid email</p>
</div>
</div>
  • As the ngShow declaration, the messages of ngMessages will only show when user has touched the input or form was submitted.
  • If user has touched the input or form was submitted, validation messages will be shown depend on the form.email.$error object
Add this tag <pre ng-bind=”form.email.$error|json”></pre> to anywhere in your template then type something to email input and see the change of the form.email.$error object.
We can declare many validators in one ngMessage separated by a comma (,).
  • Angular has many build-in validators like required, ngPattern, ngMinlength, ngMaxlength that you can use them right away or you can create your own custom validators.

Create custom validators.

Depend on the form’s business, you may need to create your own custom validator. Let see the demo, here confirm password must be the same as password.

So we will create ‘equalWith’ validator:

app.directive('equalWith', function() {
return {
require: 'ngModel',
scope: { equalWith: '&'},
link: function(scope, elem, attrs, ngModelCtrl) {
            ngModelCtrl.$validators.equalWith = 
function (modelValue){
return (modelValue === scope.equalWith())
}
            scope.$watch(scope.equalWith, function(value){
ctrl.$validate()
})
}
}
})

Then we use equalWith validator like this

<input class=”form-control” name=”confirmPassword” type=”password”
ng-model=”vm.data.confirmPassword”
equal-with=”vm.data.password”
required>
<div ng-show=”form.confirmPassword.$touched || form.$submitted”
ng-messages=”form.confirmPassword.$error”>
<p ng-message=”required”>Please enter confirm password</p>
<p ng-message=”equalWith”>Confirm password does not match</p>
</div>

Conclusion

Writing form validation is no longer a mess, as long as we understand the form object and use it right with ngMessages. The validators can be used among different projects. Our code now is much easier to read, to develop and also more reusable.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.