@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.input input widgets} simply refer to the model and are data-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. ef='#n3'>3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
"""
Descriptive HTTP status codes, for code readability.

See RFC 2616 - Sec 10: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Also see django.core.handlers.wsgi.STATUS_CODE_TEXT
"""

# Verbose format
HTTP_100_CONTINUE = 100
HTTP_101_SWITCHING_PROTOCOLS = 101
HTTP_200_OK = 200
HTTP_201_CREATED = 201
HTTP_202_ACCEPTED = 202
HTTP_203_NON_AUTHORITATIVE_INFORMATION = 203
HTTP_204_NO_CONTENT = 204
HTTP_205_RESET_CONTENT = 205
HTTP_206_PARTIAL_CONTENT = 206
HTTP_300_MULTIPLE_CHOICES = 300
HTTP_301_MOVED_PERMANENTLY = 301
HTTP_302_FOUND = 302
HTTP_303_SEE_OTHER = 303
HTTP_304_NOT_MODIFIED = 304
HTTP_305_USE_PROXY = 305
HTTP_306_RESERVED = 306
HTTP_307_TEMPORARY_REDIRECT = 307
HTTP_400_BAD_REQUEST = 400
HTTP_401_UNAUTHORIZED = 401
HTTP_402_PAYMENT_REQUIRED = 402
HTTP_403_FORBIDDEN = 403
HTTP_404_NOT_FOUND = 404
HTTP_405_METHOD_NOT_ALLOWED = 405
HTTP_406_NOT_ACCEPTABLE = 406
HTTP_407_PROXY_AUTHENTICATION_REQUIRED = 407
HTTP_408_REQUEST_TIMEOUT = 408
HTTP_409_CONFLICT = 409
HTTP_410_GONE = 410
HTTP_411_LENGTH_REQUIRED = 411
HTTP_412_PRECONDITION_FAILED = 412
HTTP_413_REQUEST_ENTITY_TOO_LARGE = 413
HTTP_414_REQUEST_URI_TOO_LONG = 414
HTTP_415_UNSUPPORTED_MEDIA_TYPE = 415
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE = 416
HTTP_417_EXPECTATION_FAILED = 417
HTTP_500_INTERNAL_SERVER_ERROR = 500
HTTP_501_NOT_IMPLEMENTED = 501
HTTP_502_BAD_GATEWAY = 502
HTTP_503_SERVICE_UNAVAILABLE = 503
HTTP_504_GATEWAY_TIMEOUT = 504
HTTP_505_HTTP_VERSION_NOT_SUPPORTED = 505

# Short format
CONTINUE = 100
SWITCHING_PROTOCOLS = 101
OK = 200
CREATED = 201
ACCEPTED = 202
NON_AUTHORITATIVE_INFORMATION = 203
NO_CONTENT = 204
RESET_CONTENT = 205
PARTIAL_CONTENT = 206
MULTIPLE_CHOICES = 300
MOVED_PERMANENTLY = 301
FOUND = 302
SEE_OTHER = 303
NOT_MODIFIED = 304
USE_PROXY = 305
RESERVED = 306
TEMPORARY_REDIRECT = 307
BAD_REQUEST = 400
UNAUTHORIZED = 401
PAYMENT_REQUIRED = 402
FORBIDDEN = 403
NOT_FOUND = 404
METHOD_NOT_ALLOWED = 405
NOT_ACCEPTABLE = 406
PROXY_AUTHENTICATION_REQUIRED = 407
REQUEST_TIMEOUT = 408
CONFLICT = 409
GONE = 410
LENGTH_REQUIRED = 411
PRECONDITION_FAILED = 412
REQUEST_ENTITY_TOO_LARGE = 413
REQUEST_URI_TOO_LONG = 414
UNSUPPORTED_MEDIA_TYPE = 415
REQUESTED_RANGE_NOT_SATISFIABLE = 416
EXPECTATION_FAILED = 417
INTERNAL_SERVER_ERROR = 500
NOT_IMPLEMENTED = 501
BAD_GATEWAY = 502
SERVICE_UNAVAILABLE = 503
GATEWAY_TIMEOUT = 504
HTTP_VERSION_NOT_SUPPORTED = 505