This tutorial is out of date and no longer maintained.
Angular has always strived to provide tools to make forms easier. Just using Angular to submit AJAX forms and using Angular’s built-in validation makes using forms that much easier.
There are even great 3rd party modules to help us work with forms like angular-formly
.
Since Angular 1.3, there is a new tool for creating and managing forms in AngularJS, ngMessages. This module specifically helps us deal with displaying error messages from form validation.
Let’s take a quick look at how forms look without using this module.
<form name="userForm">
<input
type="text"
name="username"
ng-model="user.username"
ng-minlength="3"
ng-maxlength="8"
required>
<!-- show an error if username is too short -->
<p ng-show="userForm.username.$error.minlength">Username is too short.</p>
<!-- show an error if username is too long -->
<p ng-show="userForm.username.$error.maxlength">Username is too long.</p>
<!-- show an error if this isn't filled in -->
<p ng-show="userForm.username.$error.required">Your username is required.</p>
</form>
We are explicitly showing each error message only if that error exists. This can get tedious when we have multiple errors that we want to show.
This is where ngMessages comes in. This module brings some sanity to validation messages.
Let’s take the above example and see how that would look in ngMessages.
<form name="userForm">
<input
type="text"
name="username"
ng-model="user.username"
ng-minlength="3"
ng-maxlength="8"
required>
<div ng-messages="userForm.name.$error">
<p ng-message="minlength">Your name is too short.</p>
<p ng-message="maxlength">Your name is too long.</p>
<p ng-message="required">Your name is required.</p>
</div>
</form>
Much simpler! ngMessages will handle showing and hiding specific messages based on the errors. ngMessages is basically looping through the userForm.name.$errors
object and displaying messages based on that.
The setup for ngMessages is very simple. We just need to load the module after Angular and then inject it into our application.
<!-- load angular -->
<script src="//code.angularjs.org/1.4.0/angular.js"></script>
<!-- load ngmessages -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-messages.js"></script>
<!-- load our custom app -->
<script src="app.js"></script>
Now we can inject it into our application in the app.js
file.
angular.module('app', ['ngMessages']);
Just use the ng-messages
directive and pass in the field you want and its $error
object.
This is the format:
<div ng-messages="<formName>.<inputName>.$error">
<p ng-message="<validationName>">Your message here.</p>
</div>
Let’s create a simple sample application to demonstrate ngMessages in practice. We’re working from a Plunkr. You can create a new one for yourself or just follow along in the code provided.
We’re going to be using some very simple HTML here. We just need a form after all.
Here’s our index.html
file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ngMessages Demo</title>
<!-- CSS -->
<!-- load bootstrap and add some custom css -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.4/cerulean/bootstrap.min.css">
<style>body { padding-top:50px; }</style>
<!-- JS -->
<script src="//code.angularjs.org/1.4.0/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-messages.js"></script>
<script src="app.js"></script>
</head>
<body class="container" ng-app="app" ng-controller="MainCtrl as main">
<!-- create our form -->
<form name="userForm" novalidate>
<!-- name field -->
<div class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control"
ng-model="main.name"
ng-minlength="5"
ng-maxlength="10"
required>
<!-- ngMessages goes here -->
</div>
<!-- email field -->
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control"
ng-model="main.email"
ng-minlength="5"
ng-maxlength="20"
required>
<!-- ngMessages goes here -->
</div>
<div class="form-group">
<button type="submit" class="btn btn-danger">Submit</button>
</div>
</form>
</body>
</html>
This will be the starting template for our app. We are using novalidate
on our form so that we disable the HTML5 validations. We have our own validations and they look much better.
We’ve started our HTML. Now we just need to create the Angular application that we already referenced in app.js
, ng-app
, and ng-controller
.
Create an app.js
file and use the following:
angular
.module('app', ['ngMessages'])
.controller('MainCtrl', MainCtrl);
function MainCtrl() {}
We don’t need to have anything in our controller right now, but this is where you would process your form.
name
The name
field only has three validations (minlength
, maxlength
, required
).
Here are the ng-messages for this input:
<div class="help-block" ng-messages="userForm.name.$error" ng-if="userForm.name.$touched">
<p ng-message="minlength">Your name is too short.</p>
<p ng-message="maxlength">Your name is too long.</p>
<p ng-message="required">Your name is required.</p>
</div>
email
For our email
input, let’s take a different approach. If our form has multiple fields, then it can be tedious to create multiple ng-messages
blocks. ngMessages gives us the ability to pull messages from an external file.
This means we can reuse the same messages for multiple fields!
Let’s create a new file called messages.html
. We can place all of our messages in this file and just call it with ng-messages-include
.
Here’s the messages.html
file:
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="required">This field is required</p>
<p ng-message="email">This needs to be a valid email</p>
Now we can use it for our email
input:
<div class="help-block" ng-messages="userForm.email.$error">
<div ng-messages-include="messages.html"></div>
</div>
This makes ngMessages very powerful and reusable.
Let’s say we wanted to only show error messages after a user has clicked out of the input that they are typing into. It isn’t very intuitive to show errors even before a user has used an input
.
Angular provides a simple way to do this. We just have to use ngShow and the $touched
validation feature Angular provides.
For example, we can only show errors for the name
input using the following:
<div class="help-block" ng-messages="userForm.name.$error" ng-show="userForm.name.$touched">
...
</div>
Now, these messages will only show after an input blur.
We also want to use the Bootstrap provided classes (.has-error
) to highlight the field as red if there is an error. We can use ngClass to add the error class if the field is $invalid
.
<div class="form-group" ng-class="{ 'has-error': userForm.name.$touched && userForm.name.$invalid }">
We are adding the .has-error
class if this field has been $touch
ed and $invalid
.
With this simple module, Angular form validation has gotten that much easier. Try it out in your own applications and let us know how you like it. Do you prefer ngMessages, a third-party software like angular-formly
, or doing validation from scratch?
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!