@@ -95,6 +95,82 @@ describe('form', function() {
95
95
} ) ;
96
96
97
97
98
+ it ( 'should react to validation changes in manually added controls' , function ( ) {
99
+ doc = $compile (
100
+ '<form name="myForm">' +
101
+ '<input name="control" ng-maxlength="1" ng-model="value" store-model-ctrl/>' +
102
+ '</form>' ) ( scope ) ;
103
+
104
+ scope . $digest ( ) ;
105
+
106
+ var form = scope . myForm ;
107
+
108
+ var input = doc . find ( 'input' ) . eq ( 0 ) ;
109
+
110
+ // remove control and invalidate it
111
+ form . $removeControl ( control ) ;
112
+ expect ( form . control ) . toBeUndefined ( ) ;
113
+
114
+ changeInputValue ( input , 'abc' ) ;
115
+ expect ( control . $error . maxlength ) . toBe ( true ) ;
116
+ expect ( control . $dirty ) . toBe ( true ) ;
117
+ expect ( form . $error . maxlength ) . toBeFalsy ( ) ;
118
+ expect ( form . $dirty ) . toBe ( false ) ;
119
+
120
+ // re-add the control; its current validation state is not propagated
121
+ form . $addControl ( control ) ;
122
+ expect ( form . control ) . toBe ( control ) ;
123
+ expect ( form . $error . maxlength ) . toBeFalsy ( ) ;
124
+ expect ( form . $dirty ) . toBe ( false ) ;
125
+
126
+ // Only when the input changes again its validation state is propagated
127
+ changeInputValue ( input , 'abcd' ) ;
128
+ expect ( form . $error . maxlength [ 0 ] ) . toBe ( control ) ;
129
+ expect ( form . $dirty ) . toBe ( false ) ;
130
+ } ) ;
131
+
132
+
133
+ it ( 'should use the correct parent when renaming and removing dynamically added controls' , function ( ) {
134
+ scope . controlName = 'childControl' ;
135
+ scope . hasChildControl = true ;
136
+
137
+ doc = $compile (
138
+ '<form name="myForm">' +
139
+ '<div ng-if="hasChildControl">' +
140
+ '<input name="{{controlName}}" ng-maxlength="1" ng-model="value"/>' +
141
+ '</div>' +
142
+ '</form>' +
143
+ '<form name="otherForm"></form>' ) ( scope ) ;
144
+
145
+ scope . $digest ( ) ;
146
+
147
+ var form = scope . myForm ;
148
+ var otherForm = scope . otherForm ;
149
+ var childControl = form . childControl ;
150
+
151
+ // remove child form and add it to another form
152
+ form . $removeControl ( childControl ) ;
153
+ otherForm . $addControl ( childControl ) ;
154
+
155
+ expect ( form . childControl ) . toBeUndefined ( ) ;
156
+ expect ( otherForm . childControl ) . toBe ( childControl ) ;
157
+
158
+ // rename the childControl
159
+ scope . controlName = 'childControlMoved' ;
160
+ scope . $digest ( ) ;
161
+
162
+ expect ( form . childControlMoved ) . toBeUndefined ( ) ;
163
+ expect ( otherForm . childControl ) . toBeUndefined ( ) ;
164
+ expect ( otherForm . childControlMoved ) . toBe ( childControl ) ;
165
+
166
+ scope . hasChildControl = false ;
167
+ scope . $digest ( ) ;
168
+
169
+ expect ( form . childControlMoved ) . toBeUndefined ( ) ;
170
+ expect ( otherForm . childControlMoved ) . toBeUndefined ( ) ;
171
+ } ) ;
172
+
173
+
98
174
it ( 'should remove scope reference when form with no parent form is removed from the DOM' , function ( ) {
99
175
var formController ;
100
176
scope . ctrl = { } ;
@@ -614,6 +690,123 @@ describe('form', function() {
614
690
expect ( child . $error . required ) . toEqual ( [ inputB ] ) ;
615
691
} ) ;
616
692
693
+
694
+ it ( 'should ignore changes in manually removed child forms' , function ( ) {
695
+ doc = $compile (
696
+ '<form name="myForm">' +
697
+ '<ng-form name="childform">' +
698
+ '<input name="childformcontrol" ng-maxlength="1" ng-model="value"/>' +
699
+ '</ng-form>' +
700
+ '</form>' ) ( scope ) ;
701
+
702
+ var form = scope . myForm ;
703
+ var childformController = doc . find ( 'ng-form' ) . eq ( 0 ) . controller ( 'form' ) ;
704
+
705
+ var input = doc . find ( 'input' ) . eq ( 0 ) ;
706
+ var inputController = input . controller ( 'ngModel' ) ;
707
+
708
+ changeInputValue ( input , 'ab' ) ;
709
+ scope . $apply ( ) ;
710
+
711
+ expect ( form . $dirty ) . toBe ( true ) ;
712
+ expect ( form . $error . maxlength ) . toBeTruthy ( ) ;
713
+ expect ( form . $error . maxlength [ 0 ] . $name ) . toBe ( 'childform' ) ;
714
+
715
+ inputController . $setPristine ( ) ;
716
+ expect ( form . $dirty ) . toBe ( true ) ;
717
+
718
+ form . $setPristine ( ) ;
719
+
720
+ // remove child form
721
+ form . $removeControl ( childformController ) ;
722
+ expect ( form . childform ) . toBeUndefined ( ) ;
723
+ expect ( form . $error . maxlength ) . toBeFalsy ( ) ;
724
+
725
+ changeInputValue ( input , 'abc' ) ;
726
+ scope . $apply ( ) ;
727
+
728
+ expect ( form . $error . maxlength ) . toBeFalsy ( ) ;
729
+ expect ( form . $dirty ) . toBe ( false ) ;
730
+ } ) ;
731
+
732
+
733
+ it ( 'should react to changes in manually added child forms' , function ( ) {
734
+ doc = $compile (
735
+ '<form name="myForm">' +
736
+ '<ng-form name="childForm">' +
737
+ '<input name="childformcontrol" ng-maxlength="1" ng-model="value" />' +
738
+ '</ng-form>' +
739
+ '</form>' ) ( scope ) ;
740
+
741
+ var form = scope . myForm ;
742
+ var childFormController = doc . find ( 'ng-form' ) . eq ( 0 ) . controller ( 'form' ) ;
743
+
744
+ var input = doc . find ( 'input' ) . eq ( 0 ) ;
745
+
746
+ // remove child form so we can add it manually
747
+ form . $removeControl ( childFormController ) ;
748
+ changeInputValue ( input , 'ab' ) ;
749
+
750
+ expect ( form . childForm ) . toBeUndefined ( ) ;
751
+ expect ( form . $dirty ) . toBe ( false ) ;
752
+ expect ( form . $error . maxlength ) . toBeFalsy ( ) ;
753
+
754
+ // re-add the child form; its current validation state is not propagated
755
+ form . $addControl ( childFormController ) ;
756
+ expect ( form . childForm ) . toBe ( childFormController ) ;
757
+ expect ( form . $error . maxlength ) . toBeFalsy ( ) ;
758
+ expect ( form . $dirty ) . toBe ( false ) ;
759
+
760
+ // Only when the input inside the child form changes, the validation state is propagated
761
+ changeInputValue ( input , 'abc' ) ;
762
+ expect ( form . $error . maxlength [ 0 ] ) . toBe ( childFormController ) ;
763
+ expect ( form . $dirty ) . toBe ( false ) ;
764
+ } ) ;
765
+
766
+
767
+ it ( 'should use the correct parent when renaming and removing dynamically added forms' , function ( ) {
768
+ scope . formName = 'childForm' ;
769
+ scope . hasChildForm = true ;
770
+
771
+ doc = $compile (
772
+ '<form name="myForm">' +
773
+ '<div ng-if="hasChildForm">' +
774
+ '<ng-form name="{{formName}}">' +
775
+ '<input name="childformcontrol" ng-maxlength="1" ng-model="value"/>' +
776
+ '</ng-form>' +
777
+ '</div>' +
778
+ '</form>' +
779
+ '<form name="otherForm"></form>' ) ( scope ) ;
780
+
781
+ scope . $digest ( ) ;
782
+
783
+ var form = scope . myForm ;
784
+ var otherForm = scope . otherForm ;
785
+ var childForm = form . childForm ;
786
+
787
+ // remove child form and add it to another form
788
+ form . $removeControl ( childForm ) ;
789
+ otherForm . $addControl ( childForm ) ;
790
+
791
+ expect ( form . childForm ) . toBeUndefined ( ) ;
792
+ expect ( otherForm . childForm ) . toBe ( childForm ) ;
793
+
794
+ // rename the childForm
795
+ scope . formName = 'childFormMoved' ;
796
+ scope . $digest ( ) ;
797
+
798
+ expect ( form . childFormMoved ) . toBeUndefined ( ) ;
799
+ expect ( otherForm . childForm ) . toBeUndefined ( ) ;
800
+ expect ( otherForm . childFormMoved ) . toBe ( childForm ) ;
801
+
802
+ scope . hasChildForm = false ;
803
+ scope . $digest ( ) ;
804
+
805
+ expect ( form . childFormMoved ) . toBeUndefined ( ) ;
806
+ expect ( otherForm . childFormMoved ) . toBeUndefined ( ) ;
807
+ } ) ;
808
+
809
+
617
810
it ( 'should chain nested forms in repeater' , function ( ) {
618
811
doc = jqLite (
619
812
'<ng:form name=parent>' +
0 commit comments