AngularJS Form Validation with Bootstrap

29 dec. 2023
Intermediate
65,6K Views
12 min read     Source Code

AngularJS form validation enables you to develop a modern HTML5 form that is interactive and responsive. AngularJS provides you built-in validation directives to to validate form client side. This makes your life pretty easy to handle client-side form validations without adding a lot of extra effort. AngularJS form validation are based on the HTML5 form validators. For in-depth insights and practical guidance on utilizing AngularJS for form validation and leveraging its validation directives, consider exploring Angular Online Training

AngularJS directives for form validation

Here is a list of angularjs directive which can be apply on a input field to validate it's value.

<input type="text"
 ng-model="{ string }"
 [name="{ string }"]
 [ng-required="{ boolean }"]
 [ng-minlength="{ number }"]
 [ng-maxlength="{ number }"]
 [ng-pattern="{ string }"]
 [ng-change="{ string }"]>
</input>

The main advantage of using AngularJS form validation instead of HTML5 attributes based validation, is that AngularJS way allows to mantain the two way data binding between model and view.

Custom Validation

AngularJS allows you to crate your own custom validation directives. For example, you want to compare password and confirm password fields. To do this, you have to make a custom directive that will fire whenever the password or confirmpassword changes.

<script>
//defining module
var myapp = angular.module('myapp', []);

//creating custom directive
myapp.directive('ngCompare', function () {
 return {
 require: 'ngModel',
 link: function (scope, currentEl, attrs, ctrl) {
 var comparefield = document.getElementsByName(attrs.ngCompare)[0]; //getting first element
 compareEl = angular.element(comparefield);

 //current field key up
 currentEl.on('keyup', function () {
 if (compareEl.val() != "") {
 var isMatch = currentEl.val() === compareEl.val();
 ctrl.$setValidity('compare', isMatch);
 scope.$digest();
 }
 });

 //Element to compare field key up
 compareEl.on('keyup', function () {
 if (currentEl.val() != "") {
 var isMatch = currentEl.val() === compareEl.val();
 ctrl.$setValidity('compare', isMatch);
 scope.$digest();
 }
 });
 }
 }
});
</script>

Angular Form Properties

Angular provides properties on form which help you to get information about a form or it's inputs and to validate them.

  1. $valid

    It is a boolean property that tells whether the form or it's inputs are valid or not. If all containing form and controls are valid, then it will be true, otherwise it will be false.

    Syntax

    formName.$valid
    formName.inputFieldName.$valid
    
  2. $invalid

    It is a boolean property that tells whether the form or it's inputs are invalid or not. If at least one containing form and control is invalid then it will be true, otherwise it will be false.

    Syntax

    formName.$invalid
    formName.inputFieldName.$invalid
    
  3. $pristine

    It is a boolean property that tells whether the form or it's inputs are unmodified by the user or not. If the form or it's inputs are unmodified by the user, then it will be true, otherwise it will be false.

    Syntax

    formName.inputFieldName.$pristine
    
  4. $dirty

    It is a boolean property that is actually just reverse of pristine i.e. it tells whether the form or it's inputs are modified by the user or not. If the form or it's inputs are modified by the user, then it will be true, otherwise it will be false.

    Syntax

    formName.$dirty
    formName.inputFieldName.$dirty
    
  5. $error

    This is an object hash which contains references to all invalid controls or forms. It has all errors as keys: where keys are validation tokens (such as required, url or email) and values are arrays of controls or forms that are invalid with given error. For a control, If a validation fails then it will be true, otherwise it will be false.

    Syntax

    formName.$error
    formName.inputFieldName.$error
    

Angular Form Methods

Angular provides some methods to change a form state. These are available only for the form, not for individual controls.

  1. $addControl()

    This method registers a control with the form.

    Syntax

    formName.$addControl()
    
  2. $removeControl()

    This method remove a control from the form.

    Syntax

    formName.$removeControl()
    
  3. $setDirty()

    This method set the form to Dirty state.

    Syntax

    formName.$setDirty()
    
  4. $setPristine()

    This method set the form to its pristine state.

    Syntax

    formName.$setPristine()
    
  5. $setValidity()

    This method set the validity of a form control.

    Syntax

    formName.$setValidity()
    

Controlling Display of Error Messages

By default, angularjs validation error messages are shown as soon as the page is loaded. This doesn't seems pretty at all. The error messages will be shown, when you will click on submit button or when are interacting with the input. You can achieve this by checking button submit state or by checking form input field $dirty property. So you have to write the code as shown below:

<script >
//Other code has been removed for clarity
// function to submit the form after all validation has occurred 
 $scope.submitForm = function () {
 
 // Set the 'submitted' flag to true
 $scope.submitted = true;
 //To DO
 };
});
</script >

 <!-- Control display of error messages for NAME input -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.name.$invalid && (userForm.name.$dirty || submitted)}">
 <label>Name</label>
 <input type="text" name="name" class="form-control" ng-model="user.name" placeholder="Your Name" ng-required="true">
 <p ng-show="userForm.name.$invalid && (userForm.name.$dirty || submitted)" class="help-block">You name is required.</p>
 </div>

A simple registration form using Angularjs

index.html

<!DOCTYPE html>
<html>
<head>
 <title>AngularJS & Bootstrap Form Validation</title>
 <link href="css/bootstrap.css" rel="stylesheet" />
 <link href="css/bootstrap-theme.css" rel="stylesheet" />
 <script src="lib/angular.js"></script>
<script >
//defining module
var myapp = angular.module('myapp', []);

//creating custom directive
myapp.directive('ngCompare', function () {
 return {
 require: 'ngModel',
 link: function (scope, currentEl, attrs, ctrl) {
 var comparefield = document.getElementsByName(attrs.ngCompare)[0]; //getting first element
 compareEl = angular.element(comparefield);

 //current field key up
 currentEl.on('keyup', function () {
 if (compareEl.val() != "") {
 var isMatch = currentEl.val() === compareEl.val();
 ctrl.$setValidity('compare', isMatch);
 scope.$digest();
 }
 });

 //Element to compare field key up
 compareEl.on('keyup', function () {
 if (currentEl.val() != "") {
 var isMatch = currentEl.val() === compareEl.val();
 ctrl.$setValidity('compare', isMatch);
 scope.$digest();
 }
 });
 }
 }
});

// create angular controller
myapp.controller('mainController', function ($scope) {

 $scope.countryList = [
 { CountryId: 1, Name: 'India' },
 { CountryId: 2, Name: 'USA' }
 ];

 $scope.cityList = [];

 $scope.$watch('user.country', function (newVal,oldVal) {

 if (newVal == 1)
 $scope.cityList = [
 { CountryId: 1, CityId: 1, Name: 'Noida' },
 { CountryId: 1, CityId: 2, Name: 'Delhi' }];
 else if (newVal == 2)
 $scope.cityList = [
 { CountryId: 2, CityId: 3, Name: 'Texas' },
 { CountryId: 2, CityId: 4, Name: 'NewYork' }];
 else
 $scope.cityList = [];
 });

 // function to submit the form after all validation has occurred 
 $scope.submitForm = function () {

 // Set the 'submitted' flag to true
 $scope.submitted = true;

 if ($scope.userForm.$valid) {
 alert("Form is valid!");
 }
 else {
 alert("Please correct errors!");
 }
 };
});

</script>
</head>
<body ng-app="myapp" ng-controller="mainController">
 <div class="container">
 <div class="col-sm-8 col-sm-offset-2">

 <!-- PAGE HEADER -->
 <div class="page-header"><h1>AngularJS Form Validation</h1></div>

 <!-- FORM : YOU CAN DISABLE, HTML5 VALIDATION BY USING "novalidate" ATTRIBUTE-->
 <form name="userForm" ng-submit="submitForm()" novalidate>

 <!-- NAME -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.name.$invalid && (userForm.name.$dirty || submitted)}">
 <label>Name</label>
 <input type="text" name="name" class="form-control" ng-model="user.name" placeholder="Your Name" ng-required="true">
 <p ng-show="userForm.name.$error.required && (userForm.name.$dirty || submitted)" class="help-block">You name is required.</p>
 </div>

 <!-- USERNAME -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.username.$invalid && (userForm.username.$dirty || submitted)}">
 <label>Username</label>
 <input type="text" name="username" class="form-control" ng-model="user.username" placeholder="Your Username" ng-minlength="3" ng-maxlength="8" ng-required="true">
 <p ng-show="userForm.username.$error.required && (userForm.username.$dirty || submitted)" class="help-block">You username is required.</p>
 <p ng-show="userForm.username.$error.minlength && (userForm.username.$dirty || submitted)" class="help-block">Username is too short.</p>
 <p ng-show="userForm.username.$error.maxlength && (userForm.username.$dirty || submitted)" class="help-block">Username is too long.</p>
 </div>

 <!-- PASSWORD -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.password.$invalid && (userForm.password.$dirty || submitted)}">
 <label>Password</label>
 <input type="Password" name="password" class="form-control" ng-model="user.password" placeholder="Your Password" ng-required="true">
 <p ng-show="userForm.password.$error.required && (userForm.password.$dirty || submitted)" class="help-block">Your password is required.</p>
 </div>

 <!-- CONFIRM PASSWORD -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.confirmPassword.$invalid && (userForm.confirmPassword.$dirty || submitted)}">
 <label>Confirm Password</label>
 <input type="Password" name="confirmPassword" class="form-control" ng-model="user.confirmPassword" placeholder="Confirm Your Password" ng-compare="password" ng-required="true">
 <p ng-show="userForm.confirmPassword.$error.required && (userForm.confirmPassword.$dirty || submitted)" class="help-block">Your confirm password is required.</p>
 <p ng-show="userForm.confirmPassword.$error.compare && (userForm.confirmPassword.$dirty || submitted)" class="help-block">Confirm password doesnot match.</p>
 </div>

 <!-- EMAIL -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.email.$invalid && (userForm.email.$dirty || submitted)}">
 <label>Email</label>
 <input type="email" name="email" class="form-control" ng-model="user.email" placeholder="Your Email Address" ng-required="true">
 <p ng-show="userForm.email.$error.required && (userForm.email.$dirty || submitted)" class="help-block">Email is required.</p>
 <p ng-show="userForm.email.$error.email && (userForm.email.$dirty || submitted)" class="help-block">Enter a valid email.</p>
 </div>

 <!-- CONTACTNO -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.contactno.$invalid && (userForm.contactno.$dirty || submitted) }">
 <label>ContactNo</label>
 <input type="text" name="contactno" class="form-control" ng-model="user.contactno" placeholder="Your Contact No" ng-pattern="/^[789]\d{9}$/" maxlength="10">
 <p ng-show="userForm.contactno.$error.pattern && (userForm.contactno.$dirty || submitted)" class="help-block">Enter a valid contactno.</p>
 </div>

 <!-- COUNTRY -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.country.$invalid && (userForm.country.$dirty || submitted)}">
 <label>Country</label>
 <select name="country" class="form-control"
 ng-model="user.country"
 ng-options="country.CountryId as country.Name for country in countryList"
 ng-required="true">
 <option value=''>Select</option>
 </select>
 <p ng-show="userForm.country.$error.required && (userForm.country.$dirty || submitted)" class="help-block">Select country.</p>
 </div>

 <!-- CITY -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.city.$invalid && (userForm.city.$dirty || submitted)}">
 <label>City</label>
 <select name="city" class="form-control"
 ng-model="user.city"
 ng-options="city.CityId as city.Name for city in cityList"
 ng-required="true">
 <option value=''>Select</option>
 </select>
 <p ng-show="userForm.city.$error.required && (userForm.city.$dirty || submitted)" class="help-block">Select city.</p>
 </div>

 <!-- TERMS & CONDITIONS -->
 <div class="form-group" ng-class="{ 'has-error' : userForm.terms.$invalid && (userForm.terms.$dirty || submitted)}">
 <label>Accept Terms & Conditions</label>
 <input type="checkbox" value="" name="terms" ng-model="user.terms" ng-required="true" />
 <p ng-show="userForm.terms.$error.required && (userForm.terms.$dirty || submitted)" class="help-block">Accept terms & conditions.</p>
 </div>

 <!-- ng-disabled FOR ENABLING AND DISABLING SUBMIT BUTTON -->
 <!--<button type="submit" class="btn btn-primary" ng-disabled="userForm.$invalid">Register</button>-->
 <button type="submit" class="btn btn-primary">Register</button>
 </form>
 </div>
 </div>
 <br />
</body>
</html>

How it works..

What do you think?

I hope this article will help you to understand AngularJS form validation. I would like to have feedback from my blog readers. Your valuable feedback, question, or comments about this article are always welcome. Consider delving into Angular JS training for comprehensive insights into form validation and other AngularJS features. Your feedback on the training content would be greatly appreciated!

Share Article
About Author
Shailendra Chauhan (Microsoft MVP, Founder & CEO at Scholarhat by DotNetTricks)

Shailendra Chauhan is the Founder and CEO at ScholarHat by DotNetTricks which is a brand when it comes to e-Learning. He provides training and consultation over an array of technologies like Cloud, .NET, Angular, React, Node, Microservices, Containers and Mobile Apps development. He has been awarded Microsoft MVP 8th time in a row (2016-2023). He has changed many lives with his writings and unique training programs. He has a number of most sought-after books to his name which has helped job aspirants in cracking tough interviews with ease.
Learn to Crack Your Technical Interview

Accept cookies & close this