<!DOCTYPE html> <html> <head> <script src="angular.js"></script> <script src="script.js"></script> <style> label { display: inline-block; width: 120px; vertical-align: middle; } input { display: inline-block; vertical-align: middle; } { border: solid red 2px; } form { padding: 10px; } textarea { width: 250px; height: 160px; } </style> </head> <body ng-app="mainModule"> <div ng-controller="mainController"> <form name="personForm" novalidate> <label for="firstNameEdit">First name:</label> <input id="firstNameEdit" type="text" name="firstName" ng-model="person.firstName" required /><br /> <label for="lastNameEdit">Last name:</label> <input id="lastNameEdit" type="text" name="lastName" ng-model="person.lastName" required /><br /> <ng-include src="'addressForm.html'"></ng-include> </form> <br /> <strong><label for="userDebugText">Person:</label></strong><br /> <textarea id="userDebugText">{{person | json}}</textarea><br /> <br /> <strong>Form validity:</strong><br /> <ul> <li><strong>personForm.$valid =</strong> {{personForm.$valid}}</li> <li><strong>personForm.addressForm.$valid =</strong> {{personForm.addressForm.$valid}}</li> <li><strong>personForm.firstName.$valid =</strong> {{personForm.firstName.$valid}}</li> <li><strong>personForm.lastName.$valid =</strong> {{personForm.lastName.$valid}}</li> <li><strong>$valid =</strong> {{$valid}}</li> </ul> </div> </body> </html>
<ng-form name="addressForm"> <label for="addressEdit">Address:</label> <input id="addressEdit" type="text" name="address" ng-model="person.address" /><br /> <label for="zipEdit">ZIP code:</label> <input id="zipEdit" type="number" name="zip" ng-model="" required /><br /> <label for="cityEdit">City:</label> <input id="cityEdit" type="text" name="city" ng-model="" /><br /> <label for="stateProvinceEdit">State/Province:</label> <input id="stateProvinceEdit" type="text" name="stateProvince" ng-model="person.stateProvince" /><br /> <label for="countryEdit">Country:</label> <input id="countryEdit" type="text" name="country" ng-model="" /> </ng-form>
angular.module("mainModule", []) .controller("mainController", function ($scope) { $scope.person = {}; });



While working with forms, we might find useful to reuse common parts in different forms. For example, the fields to collect the address information of a person could be reused in many different cases. AngularJS allows us to define subforms that we can nest inside regular forms.

In the example you can see that we've defined a form inside our main index.html page and a subform inside addressForm.html. The subform is nested inside the main form with the ng-include directive. To define a subform we have to use the ng-form directive and assign it a name. All the elements inside the subform are grouped together: as you can see, if we want to access the validity state of the zip field inside the subform, we have to write$valid because the addressForm is part of personForm and all the fields inside the subform (like zip) are part of the addressForm object. The subform have it's own validity (addressForm.$valid and addressForm.$invalid) and modification states (addressForm.$pristine and addressForm.$dirty) that are automatically merged with the other elements of the containing form to have the global validity and modification states of the main form.

Both the containing form and the subform can work on the same model variable defined on the scope. In this case we see that the model variable person that we've defined in the script file is used by both the forms so it can be automatically updated like if it was inside a single form.

When you use the ng-include directive, remember to wrap the external file name in single quotes if it's a string constant, otherwise, if you don't include the quotes, your string in the src attribute will be interpreted as an expression that must evaluate to a URL.