Tutorial

AngularJS Form Validation with NgMessages

Draft updated on Invalid Date
author

Chris on Code

AngularJS Form Validation with NgMessages

This tutorial is out of date and no longer maintained.

Introduction

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.

Validation Messages without ngMessages

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.

A Quick Look at ngMessages

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.

Using ngMessages

The setup for ngMessages is very simple. We just need to load the module after Angular and then inject it into our application.

Load Dependencies and Inject

    <!-- 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']);

Show Messages

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>

A Sample App

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.

The HTML

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.

Our Angular App

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.

ngMessages for 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>

ngMessages for 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!

Reusable ngMessages with File

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.

Only Showing Messages After Blur

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.

Adding Bootstrap Error Classes

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 $touched and $invalid.

Conclusion

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.

Learn more about our products

About the authors
Default avatar
Chris on Code

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


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!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.