AngularJS Forms and Validation
Learn how to bind form inputs with ng-model and use AngularJS's automatic validation state classes to give users real-time feedback.
Two-Way Binding with ng-model
The ng-model directive binds a form control's value to a property on the scope. Typing into the input updates the property immediately, and changing the property from code updates the input just as immediately - this is AngularJS's classic two-way data binding applied to forms.
Example
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-app="formApp" ng-controller="ProfileController as vm">
<label>Display name:
<input type="text" ng-model="vm.name" placeholder="Enter your name">
</label>
<p>Hello, {{ vm.name || 'stranger' }}!</p>
</div>
<script>
angular.module('formApp', [])
.controller('ProfileController', function() {
var vm = this;
vm.name = '';
});
</script>
</body>
</html>Automatic Validation CSS Classes
Every ng-model bound field is automatically tracked by AngularJS's form controller. As the user interacts with it, AngularJS toggles a set of CSS classes on the element so you can style valid, invalid, touched, and untouched states without writing any JavaScript.
Example
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-app="formApp" ng-controller="SignupController as vm">
<form name="signupForm" novalidate ng-submit="vm.submit()">
<input type="text" name="username" ng-model="vm.username" required>
<span class="error" ng-show="signupForm.username.$invalid && signupForm.username.$dirty">
Username is required.
</span>
<button type="submit" ng-disabled="signupForm.$invalid">Sign Up</button>
</form>
<style>
input.ng-invalid.ng-dirty { border: 2px solid #d9534f; }
input.ng-valid.ng-dirty { border: 2px solid #5cb85c; }
</style>
</div>
<script>
angular.module('formApp', [])
.controller('SignupController', function() {
var vm = this;
vm.submit = function() {};
});
</script>
</body>
</html>- required - value must not be empty
- ng-minlength / ng-maxlength - enforce minimum and maximum string length
- type="email" - built-in email format validation
- type="number" - restricts input and parses the value to a number
- pattern - validates the value against a custom regular expression
Because the form and each input were given a name attribute, AngularJS registers them on the scope as nested objects: signupForm.username. That gives you direct access to per-field state such as $invalid, $dirty, and a detailed $error map keyed by which validation rule failed.
Example
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-app="formApp" ng-controller="ContactController as vm">
<form name="contactForm" novalidate>
<input type="email" name="email" ng-model="vm.email" required>
<div ng-show="contactForm.email.$dirty && contactForm.email.$invalid">
<span ng-show="contactForm.email.$error.required">Email is required.</span>
<span ng-show="contactForm.email.$error.email">Please enter a valid email.</span>
</div>
</form>
</div>
<script>
angular.module('formApp', [])
.controller('ContactController', function() {
var vm = this;
vm.email = '';
});
</script>
</body>
</html>Exercise: AngularJS Forms
What does ng-model do on a form input?