/
template-driven.component.html
319 lines (289 loc) · 20.4 KB
/
template-driven.component.html
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
<div class="row">
<div class="col-md-12">
<p class="myHeader">
Forms in Angular (1) Template Driven <span mdTooltip="View Source">
<a href="https://github.com/rahulrsingh09/AngularConcepts/tree/master/src/app/template-driven">
<img src="code.png" alt="Image">
</a>
</span>
</p>
</div>
</div>
<hr>
<div class="row">
<div class="col-md-12">
<p>Angular JS tackled forms via the famous ng-model directive.<br>
The instantaneous two-way data binding of ng-model in Angular 1 is really a life-saver as it allows to transparently keep in sync a form with a view model.
Forms built with this directive can only be tested in an end to end test because this requires the presence of a DOM, but still this mechanism is very useful and simple to understand.<br>
Angular 2 provides a similar mechanism also called ng-model, that allow us to build what is now called Template-Driven forms.<br>For more indepth study please visit these links .<span mdTooltip="Angular IO">
<a href="https://angular.io/guide/forms">
<img src="code.png" alt="Image">
</a>
</span> <br> <strong>Now Let's get our hand's dirty</strong> You need to Import the <strong>Forms Module</strong> in NgModule to kick start Template Driven Forms.</p>
</div>
</div>
<div class="row">
<div class="col-md-9">
<br>
<form #f="ngForm" [ngFormOptions]="{updateOn: 'blur'}" novalidate>
<div class="row">
<div class="col-md-8">
<div class="row" ngModelGroup = "name">
<div class="col-md-6">
<mat-form-field>
<input matInput type="text"
placeholder="First Name"
name = "firstName"
[(ngModel)] = "user.name.firstName"
#firstName = "ngModel"
minlength="4"
required
nameRahul>
</mat-form-field>
</div>
<div class="col-md-6">
<mat-form-field>
<input matInput type="text"
placeholder="Last Name"
name = "lastName"
[(ngModel)] = "user.name.lastName"
#lastName = "ngModel"
>
</mat-form-field>
</div>
</div>
</div>
<div class="col-md-4">
<mat-form-field>
<input matInput type="number" name="age" [(ngModel)]="user.age" #age = "ngModel" placeholder="Age" required asyncValidator >
</mat-form-field>
</div>
</div>
<br>
<div class="row">
<div class="col-md-8" *ngIf="formErrors.name">
<div *ngFor="let data of formErrors.name">
<small>{{data}}</small>
</div>
</div>
<div class="col-md-4" *ngIf="formErrors.age | json">
<div *ngFor="let data of formErrors.age">
<small>{{data}}</small>
</div>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<mat-form-field>
<input matInput type="text"
placeholder="email"
name = "email"
[(ngModel)] = "user.email"
#email = "ngModel"
>
</mat-form-field>
</div>
</div>
<br>
<div class="row">
<div class="col-md-4">
<mat-select placeholder="Role" name="role" [(ngModel)]="user.role">
<mat-option *ngFor="let role of roles" [value]="role.value">
{{role.display}}
</mat-option>
</mat-select>
</div>
<div class="col-md-4">
<mat-select placeholder="Theme" name="theme" [(ngModel)]="user.theme">
<mat-option *ngFor="let theme of themes" [value] = "theme">
{{theme.display}}
</mat-option>
</mat-select>
</div>
<div class="col-md-4">
<mat-select multiple placeholder="Topics" name="topics" [(ngModel)]="user.topics">
<mat-option *ngFor="let topic of topics" [value]="topic.value">
{{topic.display}}
</mat-option>
</mat-select><!-- Multiple select is not active in multiple select -->
</div>
</div>
<br>
<div class="row">
<div class="col-md-3">
<mat-checkbox name="isActive" [(ngModel)]="user.isActive" >Is Active!</mat-checkbox>
</div>
<div class="col-md-3">
<input type="hidden" name="toggle" [(ngModel)]="user.toggle">
<mat-checkbox [checked]="user.toggle === toggles[0].value"
(change)="$event.checked?(user.toggle = toggles[0].value): (user.toggle = toggles[1].value)">
{{toggles[0].display}}</mat-checkbox>
</div>
</div>
<br>
<div class="row">
<div class="col-md-3">
<button md-raised-button color = "primary" type="submit" (click)="save(f.valid,f.value)" [disabled] = !f.valid >Submit</button>
</div>
</div>
<!--
<md-radio-group [(ngModel)]="user.gender">
<mat-radio-button ngDefaultControl *ngFor="let gender of genders" [checked]="gender.value == user.gender"
name="gender" [value]="gender.value"> {{gender.display}}
</mat-radio-button>
</md-radio-group>
<div>
<label>Gender</label>
<div *ngFor="let gender of genders">
<label>
<input type="radio" name="gender" [(ngModel)]="user.gender"
[value]="gender.value">
{{gender.display}}
</label>
</div>
</div>
<div>
<input type="hidden" name="toggle" [(ngModel)]="user.toggle">
<div>
<label>
<input type="checkbox"
[checked]="user.toggle === toggles[0].value"
(change)="$event.target.checked?(user.toggle = toggles[0].value): (user.toggle = toggles[1].value)">
{{toggles[0].display}}
</label>
</div>
</div>
-->
</form>
</div>
<div class="col-md-3">
<pre> {{f.value | json}} </pre>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<p><strong>So Now what is this Form whats is Happening</strong><br>
<br> Its is a Form which highlights all the key features of an Template Driven Forms Key features are - Easy to use,
Suitable for simple scenarios and fails for complex scenarios,
Similar to angular js
Two way data binding(using [(NgModel)] syntax)
Minimal component code
Automatic track of the form and its data - handled by Angular. <br>
All the magic happens in the template in Template driven forms as the name suggests .
</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<p><strong>A Small portion of the Template used for the Above Form</strong></p>
<div style="background: #ffffff; overflow:auto;width:auto;"><pre style="margin: 0; line-height: 125%"><span style="color: #007700"><form</span> <span style="color: #FF0000; background-color: #FFAAAA">#</span><span style="color: #0000CC">f=</span><span style="background-color: #fff0f0">"ngForm"</span> <span style="color: #0000CC"> <span style="color: #FF0000; background-color: #FFAAAA">[</span><span style="color: #0000CC">ngFormOptions]="{updateOn: 'blur'}"</span><span style="color: #FF0000; background-color: #FFAAAA"></span> novalidate</span><span style="color: #007700">></span> // new feature in Angular v5.0.0
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"row"</span><span style="color: #007700">></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"col-md-8"</span><span style="color: #007700">></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"row"</span> <span style="color: #0000CC">ngModelGroup =</span><span style="color: #FF0000; background-color: #FFAAAA"> </span><span style="background-color: #fff0f0">"name"</span><span style="color: #007700">></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"col-md-6"</span><span style="color: #007700">></span>
<span style="color: #007700"><md</span><span style="color: #0000CC">-input-container</span><span style="color: #007700">></span>
<span style="color: #007700"><input</span> <span style="color: #0000CC">matInput</span> <span style="color: #0000CC">type=</span><span style="background-color: #fff0f0">"text"</span>
<span style="color: #0000CC">placeholder=</span><span style="background-color: #fff0f0">"First Name"</span>
<span style="color: #0000CC">name =</span><span style="color: #FF0000; background-color: #FFAAAA"> </span><span style="background-color: #fff0f0">"firstName"</span>
<span style="color: #FF0000; background-color: #FFAAAA">[(</span><span style="color: #0000CC">ngModel</span><span style="color: #FF0000; background-color: #FFAAAA">)]</span> <span style="color: #FF0000; background-color: #FFAAAA">=</span> <span style="color: #FF0000; background-color: #FFAAAA">"</span><span style="color: #0000CC">user</span><span style="color: #FF0000; background-color: #FFAAAA">.</span><span style="color: #0000CC">name</span><span style="color: #FF0000; background-color: #FFAAAA">.</span><span style="color: #0000CC">firstName</span><span style="color: #FF0000; background-color: #FFAAAA">"</span>
<span style="color: #FF0000; background-color: #FFAAAA">#</span><span style="color: #0000CC">firstName =</span><span style="color: #FF0000; background-color: #FFAAAA"> </span><span style="background-color: #fff0f0">"ngModel"</span>
<span style="color: #0000CC">minlength=</span><span style="background-color: #fff0f0">"4"</span>
<span style="color: #0000CC">required</span>
<span style="color: #0000CC">nameRahul</span><span style="color: #007700">></span>
<span style="color: #FF0000; background-color: #FFAAAA"><</span>/mat-form-field>
<span style="color: #007700"></div></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"col-md-6"</span><span style="color: #007700">></span>
<span style="color: #007700"><md</span><span style="color: #0000CC">-input-container</span><span style="color: #007700">></span>
<span style="color: #007700"><input</span> <span style="color: #0000CC">matInput</span> <span style="color: #0000CC">type=</span><span style="background-color: #fff0f0">"text"</span>
<span style="color: #0000CC">placeholder=</span><span style="background-color: #fff0f0">"Last Name"</span>
<span style="color: #0000CC">name =</span><span style="color: #FF0000; background-color: #FFAAAA"> </span><span style="background-color: #fff0f0">"lastName"</span>
<span style="color: #FF0000; background-color: #FFAAAA">[(</span><span style="color: #0000CC">ngModel</span><span style="color: #FF0000; background-color: #FFAAAA">)]</span> <span style="color: #FF0000; background-color: #FFAAAA">=</span> <span style="color: #FF0000; background-color: #FFAAAA">"</span><span style="color: #0000CC">user</span><span style="color: #FF0000; background-color: #FFAAAA">.</span><span style="color: #0000CC">name</span><span style="color: #FF0000; background-color: #FFAAAA">.</span><span style="color: #0000CC">lastName</span><span style="color: #FF0000; background-color: #FFAAAA">"</span>
<span style="color: #FF0000; background-color: #FFAAAA">#</span><span style="color: #0000CC">lastName =</span><span style="color: #FF0000; background-color: #FFAAAA"> </span><span style="background-color: #fff0f0">"ngModel"</span>
<span style="color: #007700">></span>
<span style="color: #FF0000; background-color: #FFAAAA"><</span>/mat-form-field>
<span style="color: #007700"></div></span>
<span style="color: #007700"></div></span>
<span style="color: #007700"></div></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"col-md-4"</span><span style="color: #007700">></span>
<span style="color: #007700"><md</span><span style="color: #0000CC">-input-container</span><span style="color: #007700">></span>
<span style="color: #007700"><input</span> <span style="color: #0000CC">matInput</span> <span style="color: #0000CC">type=</span><span style="background-color: #fff0f0">"number"</span> <span style="color: #0000CC">name=</span><span style="background-color: #fff0f0">"age"</span> <span style="color: #FF0000; background-color: #FFAAAA">[(</span><span style="color: #0000CC">ngModel</span><span style="color: #FF0000; background-color: #FFAAAA">)]="</span><span style="color: #0000CC">user</span><span style="color: #FF0000; background-color: #FFAAAA">.</span><span style="color: #0000CC">age</span><span style="color: #FF0000; background-color: #FFAAAA">"</span> <span style="color: #0000CC">placeholder=</span><span style="background-color: #fff0f0">"Age"</span> <span style="color: #0000CC">required</span> <span style="color: #0000CC">asyncValidator</span><span style="color: #007700">></span>
<span style="color: #FF0000; background-color: #FFAAAA"><</span>/mat-form-field>
<span style="color: #007700"></div></span>
<span style="color: #007700"></div></span>
<span style="color: #007700"><br></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"row"</span><span style="color: #007700">></span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"col-md-6"</span> <span style="color: #FF0000; background-color: #FFAAAA">*</span><span style="color: #0000CC">ngIf=</span><span style="background-color: #fff0f0">"formErrors.name"</span><span style="color: #007700">></span>
<span style="color: #007700"><div</span> <span style="color: #FF0000; background-color: #FFAAAA">*</span><span style="color: #0000CC">ngFor=</span><span style="background-color: #fff0f0">"let data of formErrors.name"</span><span style="color: #007700">></span>
<span style="color: #007700"><small></span><code>[use Interpolation]data</code><span style="color: #007700"></small></span>
<span style="color: #007700"></div></span>
<span style="color: #007700"></div>lidat</span>
<span style="color: #007700"><div</span> <span style="color: #0000CC">class=</span><span style="background-color: #fff0f0">"col-md-6"</span> <span style="color: #FF0000; background-color: #FFAAAA">*</span><span style="color: #0000CC">ngIf=</span><span style="background-color: #fff0f0">"formErrors.age | json"</span><span style="color: #007700">></span>
<span style="color: #007700"><div</span> <span style="color: #FF0000; background-color: #FFAAAA">*</span><span style="color: #0000CC">ngFor=</span><span style="background-color: #fff0f0">"let data of formErrors.age"</span><span style="color: #007700">></span>
<span style="color: #007700"><small></span><code>[use Interpolation]data</code><span style="color: #007700"></small></span>
<span style="color: #007700"></div></span>
<span style="color: #007700"></div></span>
<span style="color: #007700"></div></span>
</pre></div>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<p>I have used a Different Method to Validate my forms here i am attaching directives to the template which makes these Validators Reusable.
<br> On such Validator where i check if name is Rahul.</p>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<div style="background: #ffffff; overflow:auto;width:auto;"><pre style="margin: 0; line-height: 125%"><span style="color: #008800; font-weight: bold">import</span> {AbstractControl, ValidatorFn, Validator, FormControl, NG_VALIDATORS} from <span style="background-color: #fff0f0">"@angular/forms"</span>;
<span style="color: #008800; font-weight: bold">import</span> {Directive} from <span style="background-color: #fff0f0">'@angular/core'</span>;
<span style="color: #008800; font-weight: bold">function</span> validateName()<span style="color: #333333">:</span> ValidatorFn {
<span style="color: #008800; font-weight: bold">return</span> (c : <span style="color: #333399; font-weight: bold">AbstractControl</span>) <span style="color: #333333">=></span> {
<span style="color: #008800; font-weight: bold">let</span> isValid <span style="color: #333333">=</span> c.value <span style="color: #333333">===</span> <span style="background-color: #fff0f0">'Rahul'</span>;
<span style="color: #008800; font-weight: bold">if</span>(isValid){
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">null</span>;
}<span style="color: #008800; font-weight: bold">else</span>{
<span style="color: #008800; font-weight: bold">return</span> {
nameRahul<span style="color: #333333">:</span> {
valid: <span style="color: #333399; font-weight: bold">false</span>
}
};
}
}
}
<span style="color: #FF0000; background-color: #FFAAAA">@</span>Directive({
selector<span style="color: #333333">:</span> <span style="background-color: #fff0f0">'[nameRahul][ngModel]'</span>,
providers<span style="color: #333333">:</span> [{
provide: <span style="color: #333399; font-weight: bold">NG_VALIDATORS</span>, useExisting: <span style="color: #333399; font-weight: bold">NameValidatorDirective</span>, multi: <span style="color: #333399; font-weight: bold">true</span>
}]
})
<span style="color: #008800; font-weight: bold">export</span> <span style="color: #008800; font-weight: bold">class</span> NameValidatorDirective <span style="color: #008800; font-weight: bold">implements</span> Validator{
validator: <span style="color: #333399; font-weight: bold">ValidatorFn</span>;
<span style="color: #008800; font-weight: bold">constructor</span>() {
<span style="color: #008800; font-weight: bold">this</span>.validator <span style="color: #333333">=</span> validateName();
}
validate(c: <span style="color: #333399; font-weight: bold">FormControl</span>) {
<span style="color: #008800; font-weight: bold">return</span> <span style="color: #008800; font-weight: bold">this</span>.validator(c);
}
}
</pre></div>
</div>
</div>
<br>
<div class="row">
<div class="col-md-12">
<p><strong>Why are we using NG_VALIDATORS can't we use a normal function ?</strong><br>
Yes we can but to make it resuable we are doing this and NG_VALIDATORS is Providers for validators to be used for FormControls in a form.
<br> We use <code>multi: true</code> to add our own validator to NG_VALIDATORS . <br><br>
Now this is not the whole picture I wanted to highlight the main components of a Template Driven forms but there is more to than what on this
page. There is <strong>Async Validators</strong> , how to show validation messages in a sophisticated manner, use of ngModelGroup. I am posting this Link -> <span mdTooltip="View Source">
<a href="https://github.com/rahulrsingh09/AngularConcepts/tree/master/src/app/template-driven">
<img src="code.png" alt="Image">
</a>
</span> . It is the Repo Folder link for this whole page, you can get to see how I created Template driven forms as well as all the Css,Html and Angular.
</p>
</div>
</div>