0
# Template-Driven Forms
1
2
Angular directive support for using ngx-validators in template-driven forms with two-way data binding and declarative validation configuration.
3
4
## ValidatorsModule
5
6
Angular module that declares and exports all validator directives for use in template-driven forms.
7
8
```typescript { .api }
9
@NgModule({
10
declarations: [
11
// Password validation
12
PasswordValidatorDirective,
13
14
// Email validation
15
EmailValidatorDirective,
16
EmailSuggestValidatorDirective,
17
18
// Universal validation
19
IsInRangeValidatorDirective,
20
IsNumberValidatorDirective,
21
MaxValidatorDirective,
22
MinValidatorDirective,
23
WhiteSpaceValidatorDirective,
24
EmptyStringValidatorDirective,
25
TypeValidatorDirective,
26
MinDateValidatorDirective,
27
MaxDateValidatorDirective,
28
29
// Credit card validation
30
CreditCardValidatorDirective,
31
32
// Equal to validation
33
EqualToDirective
34
],
35
exports: [/* same as declarations */]
36
})
37
export class ValidatorsModule {}
38
```
39
40
**Usage:**
41
42
```typescript
43
import { ValidatorsModule } from "ngx-validators";
44
45
@NgModule({
46
imports: [
47
CommonModule,
48
FormsModule,
49
ValidatorsModule // Import to use validator directives
50
],
51
// ...
52
})
53
export class MyModule {}
54
```
55
56
## Capabilities
57
58
### Password Validation Directive
59
60
Comprehensive password validation with configurable character requirements.
61
62
```typescript { .api }
63
@Directive({
64
selector: "[password][formControlName],[password][formControl],[password][ngModel]"
65
})
66
export class PasswordValidatorDirective implements Validator, OnInit, OnChanges {
67
@Input() repeatCharacter: number = 4;
68
@Input() alphabeticalCharacter: number = 1;
69
@Input() digitCharacter: number = 1;
70
@Input() lowercaseCharacter: number = 1;
71
@Input() uppercaseCharacter: number = 1;
72
}
73
```
74
75
**Usage Example:**
76
77
```html
78
<input
79
type="password"
80
name="password"
81
[(ngModel)]="user.password"
82
#password="ngModel"
83
[password]="true"
84
[repeatCharacter]="3"
85
[alphabeticalCharacter]="2"
86
[digitCharacter]="1"
87
[lowercaseCharacter]="1"
88
[uppercaseCharacter]="1">
89
90
<div *ngIf="password.errors?.repeatCharacterRegexRule">
91
Cannot repeat characters more than {{password.errors.repeatCharacterRegexRule.repeatCount}} times.
92
</div>
93
<div *ngIf="password.errors?.digitCharacterRule">
94
Must contain at least {{password.errors.digitCharacterRule.required}} digit(s).
95
</div>
96
<div *ngIf="password.errors?.lowercaseCharacterRule">
97
Must contain at least {{password.errors.lowercaseCharacterRule.required}} lowercase letter(s).
98
</div>
99
```
100
101
### Email Validation Directives
102
103
#### EmailValidatorDirective
104
105
Basic email validation directive with configurable validation type.
106
107
```typescript { .api }
108
@Directive({
109
selector: "[email][formControlName],[email][formControl],[email][ngModel]"
110
})
111
export class EmailValidatorDirective implements Validator, OnInit, OnChanges {
112
@Input() email: "normal" | "simple" = "normal";
113
}
114
```
115
116
**Usage Example:**
117
118
```html
119
<input
120
type="email"
121
name="email"
122
[(ngModel)]="user.email"
123
#email="ngModel"
124
[email]="'normal'">
125
126
<div *ngIf="email.errors?.normalEmailRule">
127
Please enter a valid email address.
128
</div>
129
130
<!-- Simple email validation -->
131
<input
132
type="email"
133
name="simpleEmail"
134
[(ngModel)]="user.simpleEmail"
135
#simpleEmail="ngModel"
136
[email]="'simple'">
137
138
<div *ngIf="simpleEmail.errors?.simpleEmailRule">
139
Please enter a valid email address.
140
</div>
141
```
142
143
#### EmailSuggestValidatorDirective
144
145
Email validation with intelligent typo suggestions and configurable options.
146
147
```typescript { .api }
148
@Directive({
149
selector: "[emailSuggest][formControlName],[emailSuggest][formControl],[emailSuggest][ngModel]"
150
})
151
export class EmailSuggestValidatorDirective implements Validator, OnInit, OnChanges {
152
@Input() emailSuggest?: EmailOptions;
153
}
154
```
155
156
**Usage Example:**
157
158
```html
159
<input
160
type="email"
161
name="email"
162
[(ngModel)]="user.email"
163
#email="ngModel"
164
[emailSuggest]="customEmailOptions">
165
166
<div *ngIf="email.errors?.suggestion">
167
Did you mean: <strong>{{email.errors.suggestion.full}}</strong>?
168
</div>
169
170
<!-- With default options -->
171
<input
172
type="email"
173
name="defaultEmail"
174
[(ngModel)]="user.defaultEmail"
175
#defaultEmail="ngModel"
176
emailSuggest>
177
```
178
179
### Universal Validation Directives
180
181
#### WhiteSpaceValidatorDirective
182
183
Validates that input contains no whitespace characters.
184
185
```typescript { .api }
186
@Directive({
187
selector: "[noWhitespace][formControlName],[noWhitespace][formControl],[noWhitespace][ngModel]"
188
})
189
export class WhiteSpaceValidatorDirective implements Validator {}
190
```
191
192
**Usage Example:**
193
194
```html
195
<input
196
name="username"
197
[(ngModel)]="user.username"
198
#username="ngModel"
199
noWhitespace>
200
201
<div *ngIf="username.errors?.noWhitespaceRequired">
202
Username cannot contain spaces.
203
</div>
204
```
205
206
#### EmptyStringValidatorDirective
207
208
Validates that input is not empty after trimming whitespace.
209
210
```typescript { .api }
211
@Directive({
212
selector: "[noEmptyString][formControlName],[noEmptyString][formControl],[noEmptyString][ngModel]"
213
})
214
export class EmptyStringValidatorDirective implements Validator {}
215
```
216
217
**Usage Example:**
218
219
```html
220
<input
221
name="description"
222
[(ngModel)]="item.description"
223
#description="ngModel"
224
noEmptyString>
225
226
<div *ngIf="description.errors?.noEmptyString">
227
Description cannot be empty.
228
</div>
229
```
230
231
#### IsNumberValidatorDirective
232
233
Validates that input is a valid number.
234
235
```typescript { .api }
236
@Directive({
237
selector: "[isNumber][formControlName],[isNumber][formControl],[isNumber][ngModel]"
238
})
239
export class IsNumberValidatorDirective implements Validator {}
240
```
241
242
**Usage Example:**
243
244
```html
245
<input
246
name="age"
247
[(ngModel)]="user.age"
248
#age="ngModel"
249
isNumber>
250
251
<div *ngIf="age.errors?.numberRequired">
252
Please enter a valid number.
253
</div>
254
```
255
256
#### IsInRangeValidatorDirective
257
258
Validates that numeric input is within a specified range.
259
260
```typescript { .api }
261
@Directive({
262
selector: "[isInRange][formControlName],[isInRange][formControl],[isInRange][ngModel]"
263
})
264
export class IsInRangeValidatorDirective implements Validator, OnInit, OnChanges {
265
@Input() minValue: number = 0;
266
@Input() maxValue: number = 0;
267
}
268
```
269
270
**Usage Example:**
271
272
```html
273
<input
274
name="score"
275
[(ngModel)]="test.score"
276
#score="ngModel"
277
isInRange
278
[minValue]="0"
279
[maxValue]="100">
280
281
<div *ngIf="score.errors?.rangeValueToSmall">
282
Score must be at least {{score.errors.rangeValueToSmall.requiredMinValue}}.
283
</div>
284
<div *ngIf="score.errors?.rangeValueToBig">
285
Score cannot exceed {{score.errors.rangeValueToBig.requiredMaxValue}}.
286
</div>
287
```
288
289
#### MinValidatorDirective
290
291
Validates minimum numeric value.
292
293
```typescript { .api }
294
@Directive({
295
selector: "input[type=text][min][formControlName],input[type=text][min][formControl],input[type=text][min][ngModel]"
296
})
297
export class MinValidatorDirective implements Validator, OnInit, OnChanges {
298
@Input() min: number = 0;
299
}
300
```
301
302
**Usage Example:**
303
304
```html
305
<input
306
type="text"
307
name="price"
308
[(ngModel)]="product.price"
309
#price="ngModel"
310
[min]="0.01">
311
312
<div *ngIf="price.errors?.min">
313
Price must be at least ${{price.errors.min.required}}.
314
</div>
315
```
316
317
#### MaxValidatorDirective
318
319
Validates maximum numeric value.
320
321
```typescript { .api }
322
@Directive({
323
selector: "input[type=text][max][formControlName],input[type=text][max][formControl],input[type=text][max][ngModel]"
324
})
325
export class MaxValidatorDirective implements Validator, OnInit, OnChanges {
326
@Input() max: number = 0;
327
}
328
```
329
330
**Usage Example:**
331
332
```html
333
<input
334
type="text"
335
name="discount"
336
[(ngModel)]="sale.discount"
337
#discount="ngModel"
338
[max]="100">
339
340
<div *ngIf="discount.errors?.max">
341
Discount cannot exceed {{discount.errors.max.required}}%.
342
</div>
343
```
344
345
#### Date Validation Directives
346
347
##### MinDateValidatorDirective
348
349
Validates minimum date value.
350
351
```typescript { .api }
352
@Directive({
353
selector: "input[type=text][minDate][formControlName],input[type=text][minDate][formControl],input[type=text][minDate][ngModel]"
354
})
355
export class MinDateValidatorDirective implements Validator, OnInit, OnChanges {
356
@Input() minDate: string = "";
357
}
358
```
359
360
**Usage Example:**
361
362
```html
363
<input
364
type="text"
365
name="startDate"
366
[(ngModel)]="event.startDate"
367
#startDate="ngModel"
368
[minDate]="'2023-01-01'">
369
370
<div *ngIf="startDate.errors?.minDate">
371
Start date cannot be before {{startDate.errors.minDate.required | date}}.
372
</div>
373
```
374
375
##### MaxDateValidatorDirective
376
377
Validates maximum date value.
378
379
```typescript { .api }
380
@Directive({
381
selector: "input[type=text][maxDate][formControlName],input[type=text][maxDate][formControl],input[type=text][maxDate][ngModel]"
382
})
383
export class MaxDateValidatorDirective implements Validator, OnInit, OnChanges {
384
@Input() maxDate: string = "";
385
}
386
```
387
388
**Usage Example:**
389
390
```html
391
<input
392
type="text"
393
name="endDate"
394
[(ngModel)]="event.endDate"
395
#endDate="ngModel"
396
[maxDate]="'2024-12-31'">
397
398
<div *ngIf="endDate.errors?.maxDate">
399
End date cannot be after {{endDate.errors.maxDate.required | date}}.
400
</div>
401
```
402
403
#### TypeValidatorDirective
404
405
Validates data type of input value.
406
407
```typescript { .api }
408
@Directive({
409
selector: "input[requireType][formControlName]"
410
})
411
export class TypeValidatorDirective implements Validator, OnInit, OnChanges {
412
@Input() requiredType: "number" | "string" | "object" | "boolean" = "string";
413
}
414
```
415
416
**Usage Example:**
417
418
```html
419
<input
420
name="value"
421
formControlName="value"
422
[requiredType]="'string'"
423
requireType>
424
425
<div *ngIf="form.get('value')?.errors?.type">
426
Expected {{form.get('value')?.errors?.type.required}}
427
but got {{form.get('value')?.errors?.type.actual}}.
428
</div>
429
```
430
431
### Credit Card Validation Directive
432
433
Validates credit card format with configurable card type support.
434
435
```typescript { .api }
436
@Directive({
437
selector: "[creditCard][formControlName],[creditCard][formControl],[creditCard][ngModel]"
438
})
439
export class CreditCardValidatorDirective implements Validator, OnInit, OnChanges {
440
@Input() creditCard: string = "all";
441
}
442
```
443
444
**Usage Example:**
445
446
```html
447
<!-- Accept any credit card -->
448
<input
449
type="text"
450
name="cardNumber"
451
[(ngModel)]="payment.cardNumber"
452
#cardNumber="ngModel"
453
[creditCard]="'all'">
454
455
<div *ngIf="cardNumber.errors?.creditcard">
456
Please enter a valid credit card number.
457
</div>
458
459
<!-- Accept only Visa cards -->
460
<input
461
type="text"
462
name="visaCard"
463
[(ngModel)]="payment.visaCard"
464
#visaCard="ngModel"
465
[creditCard]="'visa'">
466
467
<div *ngIf="visaCard.errors?.visa">
468
Please enter a valid Visa card number.
469
</div>
470
471
<!-- Other card types: 'americanExpress', 'dinersclub', 'discover', 'jcb', 'maestro', 'mastercard' -->
472
```
473
474
### Equal To Validation Directive
475
476
Validates that two form controls have equal values.
477
478
```typescript { .api }
479
@Directive({
480
selector: "[equalTo][ngModel], [equalTo][formControlName], [equalTo][formControl]"
481
})
482
export class EqualToDirective implements Validator, OnDestroy, OnChanges {
483
@Input() equalTo: string | AbstractControl;
484
}
485
```
486
487
**Usage Example:**
488
489
```html
490
<form>
491
<input
492
type="password"
493
name="password"
494
[(ngModel)]="user.password"
495
#password="ngModel">
496
497
<input
498
type="password"
499
name="confirmPassword"
500
[(ngModel)]="user.confirmPassword"
501
#confirmPassword="ngModel"
502
[equalTo]="'password'">
503
504
<div *ngIf="confirmPassword.errors?.notEqualTo">
505
Passwords do not match.
506
</div>
507
</form>
508
```
509
510
## Complete Form Example
511
512
```html
513
<form #userForm="ngForm">
514
<!-- Email with suggestion -->
515
<div>
516
<label>Email:</label>
517
<input
518
type="email"
519
name="email"
520
[(ngModel)]="user.email"
521
#email="ngModel"
522
emailSuggest
523
required>
524
525
<div *ngIf="email.errors?.suggestion">
526
Did you mean: <strong>{{email.errors.suggestion.full}}</strong>?
527
</div>
528
</div>
529
530
<!-- Password with complexity rules -->
531
<div>
532
<label>Password:</label>
533
<input
534
type="password"
535
name="password"
536
[(ngModel)]="user.password"
537
#password="ngModel"
538
[password]="true"
539
[digitCharacter]="1"
540
[lowercaseCharacter]="1"
541
[uppercaseCharacter]="1"
542
required>
543
544
<div *ngIf="password.errors?.digitCharacterRule">
545
Must contain at least 1 digit.
546
</div>
547
<div *ngIf="password.errors?.lowercaseCharacterRule">
548
Must contain at least 1 lowercase letter.
549
</div>
550
</div>
551
552
<!-- Password confirmation -->
553
<div>
554
<label>Confirm Password:</label>
555
<input
556
type="password"
557
name="confirmPassword"
558
[(ngModel)]="user.confirmPassword"
559
#confirmPassword="ngModel"
560
[equalTo]="'password'"
561
required>
562
563
<div *ngIf="confirmPassword.errors?.notEqualTo">
564
Passwords do not match.
565
</div>
566
</div>
567
568
<!-- Age with range validation -->
569
<div>
570
<label>Age:</label>
571
<input
572
type="text"
573
name="age"
574
[(ngModel)]="user.age"
575
#age="ngModel"
576
isNumber
577
[min]="18"
578
[max]="120"
579
required>
580
581
<div *ngIf="age.errors?.min">
582
Must be at least 18 years old.
583
</div>
584
<div *ngIf="age.errors?.max">
585
Age cannot exceed 120.
586
</div>
587
</div>
588
589
<!-- Credit card -->
590
<div>
591
<label>Credit Card:</label>
592
<input
593
type="text"
594
name="cardNumber"
595
[(ngModel)]="user.cardNumber"
596
#cardNumber="ngModel"
597
[creditCard]="'all'">
598
599
<div *ngIf="cardNumber.errors?.creditcard">
600
Please enter a valid credit card number.
601
</div>
602
</div>
603
604
<button type="submit" [disabled]="!userForm.valid">
605
Submit
606
</button>
607
</form>
608
```
609
610
## Important Notes
611
612
1. **Directive Selectors**: Each directive has specific attribute selectors that must be used exactly as shown.
613
614
2. **Input Validation**: Many directives require specific input types (e.g., `type="text"` for min/max date validators).
615
616
3. **Error Objects**: Error objects vary by validator type. Refer to individual validator documentation for specific error structures.
617
618
4. **Form Module**: Import `FormsModule` and `ValidatorsModule` in your Angular module to use template-driven forms with these validators.
619
620
5. **TypeValidatorDirective**: Currently only supports `formControlName` selector, limiting its use to reactive forms embedded in templates.