The directives and controllers that AngularJS automatically associates with <form> and <input> elements offer quite a bit of functionality that is not apparent until you dig into the source code and experiment.
For example, in this plunkr I’ve created a simple HTML form with two inputs.
<div ng-controller="registerController"> <form name="registerForm" ng-submit="register()"> <input name="username" type="text" placeholder="Username" ng-model="username" required ng-minlength="3" /> <input name="password" type="password" placeholder="Password" ng-model="password" required /> <input type="submit" ng-disabled="registerForm.$invalid"/> <div>{{message}}</div> <pre>{{ registerForm | alljson }}</pre> </form> </div>
Notice the form has a name. Giving a form a name means Angular will automatically associate the form with registerController’s $scope object. The associated property will have the same name as the form (registerForm) and contain information about input values, clean and dirty flags, as well as valid and invalid flags.
The plunkr will dump out the data available about the form using an alljson filter, defined below. I’m using a custom filter because the built-in Angular json purposefully ignores object attributes that start with $ (like $invalid).
app.filter("alljson", function() { return function(o) { return JSON.stringify(o, null, 4); }; });
The output will look like the following (some information omitted for brevity).
{ "$name": "registerForm", "$dirty": true, "$pristine": false, "$valid": true, "$invalid": false, "username": { "$viewValue": "sallen", "$modelValue": "sallen", "$pristine": false, "$dirty": true, "$valid": true, "$invalid": false, "$name": "username", "$error": { "required": false, "minlength": false } }, "password": { "$viewValue": "123", "$modelValue": "123", "$pristine": false, "$dirty": true, "$valid": true, "$invalid": false, "$name": "password", "$error": { "required": false } } }
In addition to managing properties, Angular manipulates CSS classes in the DOM and provides extensibility points with model formatters and parsers, We’ll look at these features in a future post.