@workInProgress @ngdoc overview @name Cookbook: Form @description A web application's main purpose is to present and gather data. For this reason angular strives to make both of these operations trivial. This example shows off how you can build a simple form to allow a user to enter data.





,

[ add ]
[ X ]

Debug View:
user={{user}}
it('should show debug', function(){ expect(binding('user')).toMatch(/John Smith/); }); it('should add contact', function(){ using('.example').element('a:contains(add)').click(); using('.example div:last').input('contact.value').enter('you@example.org'); expect(binding('user')).toMatch(/\(234\) 555\-1212/); expect(binding('user')).toMatch(/you@example.org/); }); it('should remove contact', function(){ using('.example').element('a:contains(X)').click(); expect(binding('user')).not().toMatch(/\(234\) 555\-1212/); }); it('should validate zip', function(){ expect(using('.example'). element(':input[ng\\:model="user.address.zip"]'). prop('className')).not().toMatch(/ng-invalid/); using('.example').input('user.address.zip').enter('abc'); expect(using('.example'). element(':input[ng\\:model="user.address.zip"]'). prop('className')).toMatch(/ng-invalid/); }); it('should validate state', function(){ expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className')) .not().toMatch(/ng-invalid/); using('.example').input('user.address.state').enter('XXX'); expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className')) .toMatch(/ng-invalid/); });
# Things to notice * The user data model is initialized {@link api/angular.directive.ng:controller controller} and is available in the {@link api/angular.scope scope} with the initial data. * For debugging purposes we have included a debug view of the model to better understand what is going on. * The {@link api/angular.widget.HTML input widgets} simply refer to the model and are auto bound. * The inputs {@link guide/dev_guide.forms validate}. (Try leaving them blank or entering non digits in the zip field) * In your application you can simply read from or write to the model and the form will be updated. * By clicking the 'add' link you are adding new items into the `user.contacts` array which are then reflected in the view.