aboutsummaryrefslogtreecommitdiffstats
path: root/src/widget/form.js
blob: 51864cf0037a4760f4fbcc6b48f47fb366639d2d (plain)
1
2
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
'use strict';

/**
 * @ngdoc widget
 * @name angular.widget.form
 *
 * @description
 * Angular widget that creates a form scope using the
 * {@link angular.module.ng.$formFactory $formFactory} API. The resulting form scope instance is
 * attached to the DOM element using the jQuery `.data()` method under the `$form` key.
 * See {@link guide/dev_guide.forms forms} on detailed discussion of forms and widgets.
 *
 *
 * # Alias: `ng:form`
 *
 * In angular forms can be nested. This means that the outer form is valid when all of the child
 * forms are valid as well. However browsers do not allow nesting of `<form>` elements, for this
 * reason angular provides `<ng:form>` alias which behaves identical to `<form>` but allows
 * element nesting.
 *
 *
 * @example
    <doc:example>
      <doc:source>
       <script>
         function Ctrl() {
           this.text = 'guest';
         }
       </script>
       <div ng:controller="Ctrl">
         <form name="myForm">
           text: <input type="text" name="input" ng:model="text" required>
           <span class="error" ng:show="myForm.text.$error.REQUIRED">Required!</span>
         </form>
         <tt>text = {{text}}</tt><br/>
         <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
         <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
         <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
         <tt>myForm.$error.REQUIRED = {{!!myForm.$error.REQUIRED}}</tt><br/>
       </div>
      </doc:source>
      <doc:scenario>
        it('should initialize to model', function() {
         expect(binding('text')).toEqual('guest');
         expect(binding('myForm.input.$valid')).toEqual('true');
        });

        it('should be invalid if empty', function() {
         input('text').enter('');
         expect(binding('text')).toEqual('');
         expect(binding('myForm.input.$valid')).toEqual('false');
        });
      </doc:scenario>
    </doc:example>
 */
angularWidget('form', function(form){
  this.descend(true);
  this.directives(true);
  return ['$formFactory', '$element', function($formFactory, formElement) {
    var name = formElement.attr('name'),
        parentForm = $formFactory.forElement(formElement),
        form = $formFactory(parentForm);
    formElement.data('$form', form);
    formElement.bind('submit', function(event){
      event.preventDefault();
    });
    if (name) {
      this[name] = form;
    }
    watch('valid');
    watch('invalid');
    function watch(name) {
      form.$watch('$' + name, function(scope, value) {
        formElement[value ? 'addClass' : 'removeClass']('ng-' + name);
      });
    }
  }];
});

angularWidget('ng:form', angularWidget('form'));