@@ -27,8 +27,8 @@ for other directives to augment its behavior.
27
27
E-mail: <input type="email" ng-model="user.email" /><br />
28
28
Gender: <input type="radio" ng-model="user.gender" value="male" />male
29
29
<input type="radio" ng-model="user.gender" value="female" />female<br />
30
- <button ng-click="reset()">RESET</button >
31
- <button ng-click="update(user)">SAVE</button >
30
+ <input type=" button" ng-click="reset()" value="Reset" / >
31
+ <input type="submit" ng-click="update(user)" value="Save" / >
32
32
</form>
33
33
<pre>form = {{user | json}}</pre>
34
34
<pre>master = {{master | json}}</pre>
@@ -77,29 +77,29 @@ To allow styling of form as well as controls, `ngModel` adds these CSS classes:
77
77
78
78
The following example uses the CSS to display validity of each form control.
79
79
In the example both `user.name` and `user.email` are required, but are rendered
80
- with red background only when they are dirty. This ensures that the user is not distracted
81
- with an error until after interacting with the control, and failing to satisfy its validity.
80
+ with red background only after the input is blurred (loses focus).
81
+ This ensures that the user is not distracted with an error until after interacting with the control,
82
+ and failing to satisfy its validity.
82
83
83
84
<example module="formExample">
84
85
<file name="index.html">
85
86
<div ng-controller="ExampleController">
86
87
<form novalidate class="css-form">
87
- Name:
88
- <input type="text" ng-model="user.name" required /><br />
88
+ Name: <input type="text" ng-model="user.name" required /><br />
89
89
E-mail: <input type="email" ng-model="user.email" required /><br />
90
90
Gender: <input type="radio" ng-model="user.gender" value="male" />male
91
91
<input type="radio" ng-model="user.gender" value="female" />female<br />
92
- <button ng-click="reset()">RESET</button >
93
- <button ng-click="update(user)">SAVE</button >
92
+ <input type=" button" ng-click="reset()" value="Reset" / >
93
+ <input type="submit" ng-click="update(user)" value="Save" / >
94
94
</form>
95
95
</div>
96
96
97
97
<style type="text/css">
98
- .css-form input.ng-invalid.ng-dirty {
98
+ .css-form input.ng-invalid.ng-touched {
99
99
background-color: #FA787E;
100
100
}
101
101
102
- .css-form input.ng-valid.ng-dirty {
102
+ .css-form input.ng-valid.ng-touched {
103
103
background-color: #78FA89;
104
104
}
105
105
</style>
@@ -140,34 +140,45 @@ the view using the standard binding primitives.
140
140
141
141
This allows us to extend the above example with these features:
142
142
143
- - RESET button is enabled only if form has some changes
144
- - SAVE button is enabled only if form has some changes and is valid
145
- - custom error messages for `user.email` and `user.agree`
143
+ - Custom error message displayed after the user interacted with a control (i.e. when `$touched` is set)
144
+ - Custom error message displayed upon submitting the form (`$submitted` is set), even if the user
145
+ didn't interact with a control
146
+
146
147
147
148
<example module="formExample">
148
149
<file name="index.html">
149
150
<div ng-controller="ExampleController">
150
151
<form name="form" class="css-form" novalidate>
151
152
Name:
152
- <input type="text" ng-model="user.name" name="uName" required /><br />
153
+ <input type="text" ng-model="user.name" name="uName" required="" />
154
+ <br />
155
+ <div ng-show="form.$submitted || form.uName.$touched">
156
+ <div ng-show="form.uName.$error.required">Tell us your name.</div>
157
+ </div>
158
+
153
159
E-mail:
154
- <input type="email" ng-model="user.email" name="uEmail" required/><br />
155
- <div ng-show="form.uEmail.$dirty && form.uEmail.$invalid">Invalid:
160
+ <input type="email" ng-model="user.email" name="uEmail" required="" />
161
+ <br />
162
+ <div ng-show="form.$submitted || form.uEmail.$touched">
156
163
<span ng-show="form.uEmail.$error.required">Tell us your email.</span>
157
164
<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
158
165
</div>
159
166
160
- Gender: <input type="radio" ng-model="user.gender" value="male" />male
161
- <input type="radio" ng-model="user.gender" value="female" />female<br />
162
-
163
- <input type="checkbox" ng-model="user.agree" name="userAgree" required />
164
- I agree: <input ng-show="user.agree" type="text" ng-model="user.agreeSign"
165
- required /><br />
166
- <div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>
167
+ Gender:
168
+ <input type="radio" ng-model="user.gender" value="male" />male
169
+ <input type="radio" ng-model="user.gender" value="female" />female
170
+ <br />
171
+ <input type="checkbox" ng-model="user.agree" name="userAgree" required="" />
172
+
173
+ I agree:
174
+ <input ng-show="user.agree" type="text" ng-model="user.agreeSign" required="" />
175
+ <br />
176
+ <div ng-show="form.$submitted || form.userAgree.$touched">
177
+ <div ng-show="!user.agree || !user.agreeSign">Please agree and sign.</div>
178
+ </div>
167
179
168
- <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
169
- <button ng-click="update(user)"
170
- ng-disabled="form.$invalid || isUnchanged(user)">SAVE</button>
180
+ <input type="button" ng-click="reset(form)" value="Reset" />
181
+ <input type="submit" ng-click="update(user)" value="Save" />
171
182
</form>
172
183
</div>
173
184
</file>
@@ -181,14 +192,14 @@ This allows us to extend the above example with these features:
181
192
$scope.master = angular.copy(user);
182
193
};
183
194
184
- $scope.reset = function() {
195
+ $scope.reset = function(form) {
196
+ if (form) {
197
+ form.$setPristine();
198
+ form.$setUntouched();
199
+ }
185
200
$scope.user = angular.copy($scope.master);
186
201
};
187
202
188
- $scope.isUnchanged = function(user) {
189
- return angular.equals(user, $scope.master);
190
- };
191
-
192
203
$scope.reset();
193
204
}]);
194
205
</file>
0 commit comments