o7planning

AngularJS Validation Tutorial with Examples

  1. Overview
  2. ng-required
  3. ng-minlength, ng-maxlength
  4. ng-pattern
  5. ng-submitted
  6. ng-messages
  7. Custom Validation

1. Overview

AngularJS provides a list of Directives. It helps you validate the information entered in the fields of Form by an user.
ng-required
Sets required attribute on an input field.
ng-minlength
Sets minlength attribute on an input field.
ng-maxlength
Sets maxlength attribute on an input field. Setting the attribute to a negative or non-numeric value, It will allow users to enter content of any length.
ng-pattern
Setting a regular expression, the user entering the content must match to this expression.
$pristine
(Primitive state) returns true if the user has not interacted with control (not touched it or touched it but never changed it), vice versa, returns false.
$dirty
a negative state of $pristine, exactly,$dirty == !pristine. It returns true if the user has changed the values of the control at least one time.
$touched
Returns true if the user has ever touched this control and ever logged out at least one time. (focus is lost at least one time)
$untouched
a negative state of $touched, exactly, $untouched == !touched. It returns true if the user has never touched this control or already touched it but not ever logged out (focus has not ever lost)
$error
A $error object contains all validation attributes applied to a specific element.
$valid
Returns true if the content is valid.
$invalid
Returns true if the content is not valid.
$pristine
The control element has $pristine = true status (Pristine state). If an user has not ever touched it or has touched it but ever not changed it. On the contrary, $pristine= false.
$dirty
$dirty is the negative of $pristine, or exactly $dirty == !$pristine. The control element is $dirty = true if the user has changed it at least once. On the contrary, $dirty = false.
$touched & $untouched
A Control has the $untouched status if users have not ever touched it or touched it but not ever logged out from it (focus has never been lost).
On the contrary, the control has the $touched status if users have ever touched it and logged out at least one time (focus is lost at least one time).

2. ng-required

ng-required is an attribute that applies to an input field of a Form that requires the user to enter content for the field.
<input ng-model="something" ng-required="true" />

<input ng-model="something" ng-required="someLogicExpression" />
Below is a simple example using ng-required. A notice of error will display if the input field has no content.
ng-required-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation - ng-required</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="ng-required-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-required</h3>
         <p>Enter Your Name:</p>

         <form name="myForm">
            Full Name <br/>
            <input type="text"
               name="myFullName" ng-model="fullName" ng-required ="true" />
            <span ng-show="myForm.myFullName.$invalid" class="error-msg">
            You must enter your Name.
            </span>
         </form>
      </div>
   </body>
</html>
ng-required-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.fullName = "";

});
Example 2:
An example other than ng-required. A checkbox will decide whether an user has to enter data into a particular field or not.
ng-required-example2.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation - ng-required</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="ng-required-example2.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-required</h3>
         <p>Enter User Name:</p>
         <form name="myForm">
            <input type="checkbox" ng-model="autoName" /> Auto Name?
            <br/>
            User Name
            <br/>
            <input type="text"
               name="myUserName" ng-model="userName" ng-required ="!autoName" />
            <span ng-show="myForm.myUserName.$invalid" class="error-msg">
            Please Enter User Name.
            </span>
         </form>
      </div>
   </body>
</html>
ng-required-example2.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.autoName = false;
    $scope.userName = "";

});

3. ng-minlength, ng-maxlength

ng-minlength is an attribute applying to an input field of Form to specify the minimum number of characters which a user has to enter in the field. For example, ng-minlength = "3" means that the user has to enter at least 3 characters into this field while the ng-maxlength specifies the maximum number of characters that the user is allowed to enter in a field.
minmax-length-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="minmax-length-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-minlength, ng-maxlength</h3>
         <p>Enter Password:</p>

         <form name="myForm" action="" ng-submit="checkOnSubmit($event)">
            Password <br/>
            <input type="password"
               name="myPassword" ng-model="password"
               ng-minlength= "5" ng-maxlength= "10" ng-required="true"/>
               
            <span ng-show="myForm.myPassword.$invalid" class="error-msg">
                 Password must be minimum 5 and maximum 10 characters
            </span>
            <br/>
            <button type="submit" >Submit</button>
         </form>
      </div>
   </body>
</html>
minmax-length-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.password = "";

    // Show more error infos.
    function printErrorInfo() {
        console.log($scope.myForm.$error);
        if ($scope.myForm.$error.minlength) {
            console.log('$error.minlength? ' + $scope.myForm.$error.minlength[0].$invalid);
        }
        if ($scope.myForm.$error.maxlength) {
            console.log('$error.maxlength? ' + $scope.myForm.$error.maxlength[0].$invalid);
        }
    }

    $scope.checkOnSubmit = function(event) {
        if ($scope.myForm.$invalid) {
            alert("Something invalid!");

            printErrorInfo();

            // Cancel submit
            event.preventDefault();
            return false;
        }
        alert("All valid => Submit now!");
        return true;
    }

});

4. ng-pattern

ng-pattern defines a pattern to ensure that the content entered in the Form by the user has to be suitable for such pattern. The value of ng-pattern is a regular expression.
ng-pattern-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation ng-pattern</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="minmax-length-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-pattern</h3>
         <p>Enter Pin Code:</p>
         <form name="myForm" action="" ng-submit="checkOnSubmit($event)">
            Pin Code:<br/>
            <!-- Only Numbers Allowed, Maximum 5 Characters -->
            <input type="text" name="myPinCode" ng-model="pinCode" ng-pattern="/^[0-9]{1,5}$/" ng-required="true" />
            <span class="error-msg" ng-show="myForm.myPinCode.$error.required">Required!</span>
            <span class="error-msg" ng-show="myForm.myPinCode.$dirty && myForm.myPinCode.$error.pattern">
            Only Numbers Allowed, Maximum 5 Characters
            </span>
            <br/>
            <button type="submit" >Submit</button>
         </form>
      </div>
   </body>
</html>
ng-pattern-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) { 
    $scope.pinCode = "";
    // Show more error infos.
    function printErrorInfo() {
        console.log($scope.myForm.$error);
    }
    $scope.checkOnSubmit = function(event) {
        if ($scope.myForm.$invalid) {
            alert("Something invalid!");

            printErrorInfo();

            // Cancel submit
            event.preventDefault();
            return false;
        }
        alert("All valid => Submit now!");
        return true;
    }
});

5. ng-submitted

AngularJS 1.3 also introduces Form a new property that is $submitted to display whether the Form has ever been submitted or not.
<div ng-if="myForm.$submitted">
    <!-- show errors -->
</div>
ng-submitted-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation $sumitted</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <script src="$submitted-example.js"></script>
      <style>
         .error-msg {
         font-size: 90%;
         font-style: italic;
         color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>$sumitted</h3>
         <p><a href="?refresh">Reset</a></p>
         <p style="color:blue;">Click Submit button to test $sumitted</p>
         <h3 style= "color:red;">$submitted = {{myForm.$submitted}}</h3>
         <!--
            (IMPOTANT!!) To test with $submitted
            You need to remove the action attribute in the FORM.

            novalidate: Disable browser default validation.
            -->
         <form name="myForm" ng-submit="myForm.$valid && doSubmitForm($event)" novalidate>
            <input type="text" name="myField1" ng-model="field1" ng-required="true"/>
            <span ng-show="myForm.myField1.$invalid" class="error-msg">Required!!</span>
            <br/>
            <button type="submit">Submit</button>
            <h4 ng-show="myForm.$submitted && myForm.$invalid" class="error-msg">
               Something invalid, please check and re-submit
            </h4>
         </form>
      </div>
   </body>
</html>
ng-submitted-example.js
var app = angular.module("myApp", []);

app.controller("myCtrl", function($scope) {

    $scope.field1 = "";

    $scope.doSubmitForm = function(event) {
        alert("OK: " + $scope.myForm.$submitted);
        // Code to Submit form!
    }

});

6. ng-messages

Validating the Form always is a complex and difficult-to-understand duty in the AngularJS. Therefore, the AngularJS 1.3 introduces some several improvements, including two more directives: ngMessages & ngMessage.
If a control needs to validate in many aspects, you need to set up many notices of errors corresponding to each aspect. Basically, your code will be like below and it is concluded that it is quite long and unfriendly.
<div>
    <div ng-if="myForm.myFieldName.$error.required">Required Message</div>
    <div ng-if="myForm.myFieldName.$error.minlength">Min length Error Message</div>
    <div ng-if="myForm.myFieldName.$error.customValidator">Custom Error Message</div>
    <div ng-if="myForm.myFieldName.$error.asyncValidator">Custom Async Error Message</div>
    <div ng-if="myForm.myFieldName.$pending">Fetching Data...</div>
</div>

<!-- Or -->

<div>
    <div ng-show="myForm.myFieldName.$error.required">Required Message</div>
    <div ng-show="myForm.myFieldName.$error.minlength">Min length Error Message</div>
    <div ng-show="myForm.myFieldName.$error.customValidator">Custom Error Message</div>
    <div ng-show="myForm.myFieldName.$error.asyncValidator">Custom Async Error Message</div>
    <div ng-show="myForm.myFieldName.$pending">Fetching Data...</div>
</div>
The better solution is that you should use ng-messages & ng-message:
<div ng-messages="myForm.myFieldName.$error">
    <div ng-message="required">Required Message</div>
    <div ng-message="minlength">Min length Error Message</div>
    <div ng-message="customValidator">Custom Error Message</div>
    <div ng-message="asyncValidator">Custom Async Error Message</div>
    <div ng-message-default="asyncValidator">Some thing error</div>
</div>

<div ng-if="myForm.myFieldName.$pending">Fetching Data...</div>
General usage:
Usage
<!-- Using attribute directives -->
<!-- ng-messages-multiple: Optional attribute -->
<ANY ng-messages="expression" role="alert" [ng-messages-multiple]>
  <ANY ng-message="stringValue">...</ANY>
  <ANY ng-message="stringValue1, stringValue2, ...">...</ANY>
  <ANY ng-message-exp="expressionValue">...</ANY>
  <ANY ng-message-default>...</ANY>
</ANY>

<!-- Or by using element directives -->
<!-- multiple: Optional attribute -->
<ng-messages for="expression" role="alert" [multiple]>
  <ng-message when="stringValue">...</ng-message>
  <ng-message when="stringValue1, stringValue2, ...">...</ng-message>
  <ng-message when-exp="expressionValue">...</ng-message>
  <ng-message-default>...</ng-message-default>
</ng-messages>
Note: To use the ngMessages you need angular-messages.js library:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-messages.js"></script>

<!-- Example: -->

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular-messages.js"></script>
and import the "ngMessages" module to your Apps
// Import ngMessages module to your App.
var app = angular.module("myApp", ["ngMessages"] );
ng-messages-example.html
<!DOCTYPE html>
<html>
   <head>
      <title>AngularJS Validation</title>
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
      <!-- angular-messsages.js Library -->
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular-messages.js"></script>
      <script src="ng-messages-example.js"></script>
      <style>
         .error-msg {
          font-size: 90%;
          font-style: italic;
          color: red;
         }
      </style>
   </head>
   <body>
      <div ng-app="myApp" ng-controller="myCtrl">
         <h3>Validation Directive: ng-messages, ng-message</h3>
         <p>Enter Password:</p>
         <form name="myForm" action="" ng-submit="checkOnSubmit($event)">
            Password <br/>
            <input type="password"
               name="myPassword" ng-model="password"
               ng-minlength= "5" ng-maxlength= "10" ng-required="true"/>

            <div ng-messages="myForm.myPassword.$error" ng-messages-multiple class="error-msg">
               <div ng-message="required">Required!</div>
               <div ng-message="minlength">Min length 5 characters</div>
               <div ng-message="maxlength">Max length 10 characters</div>
               <div ng-message="customValidator">Custom Error Message</div>
               <div ng-message="asyncValidator">Custom Async Error Message</div>
            </div>

            <br/>
            <button type="submit" >Submit</button>
         </form>
      </div>
   </body>
</html>
ng-messages-example.js
// Import ngMessages module to your App.
var app = angular.module("myApp", ["ngMessages"] );

app.controller("myCtrl", function($scope) {

    $scope.password = "";

    $scope.checkOnSubmit = function(event) {
        if ($scope.myForm.$invalid) {
            alert("Something invalid!");
            // Cancel submit
            event.preventDefault();
            return false;
        }
        alert("All valid => Submit now!");
        return true;
    }

});

7. Custom Validation

  • Custom AngularJS Validation