I'm trying to add form validations which don't invalidate the form. The validation should only appear as warnings.
E.g. an age validation. An age greater than 90 shows a warning and an age greater than 120 shows an error.
I've tried it with two FormGroups on a form and two [formControl]s on the input field. Only the first [formControl] is used.
Is it possible to use Angulars form validation for this kind of validation? Which approach is the way to go?
I have done it by creating custom validator, which always return null
. Also this validator creates additional property warnings
. Then just simple check this property from your view.
export interface AbstractControlWarn extends AbstractControl { warnings: any; }
export function tooBigAgeWarning(c: AbstractControlWarn) {
if (!c.value) { return null; }
let val = +c.value;
c.warnings = val > 90 && val <= 120 ? { tooBigAge: {val} } : null;
return null;
}
export function impossibleAgeValidator(c: AbstractControl) {
if (tooBigAgeWarning(c) !== null) { return null; }
let val = +c.value;
return val > 120 ? { impossibleAge: {val} } : null;
}
@Component({
selector: 'my-app',
template: `
<div [formGroup]="form">
Age: <input formControlName="age"/>
<div *ngIf="age.errors?.required" [hidden]="age.pristine">
Error! Age is required
</div>
<div *ngIf="age.errors?.impossibleAge" [hidden]="age.pristine">
Error! Age is greater then 120
</div>
<div *ngIf="age.warnings?.tooBigAge" [hidden]="age.pristine">
Warning! Age is greater then 90
</div>
<p><button type=button [disabled]="!form.valid">Send</button>
</div>
`,
})
export class App {
age: FormControl;
constructor(private _fb: FormBuilder) { }
ngOnInit() {
this.form = this._fb.group({
age: ['', [
Validators.required,
tooBigAgeWarning,
impossibleAgeValidator]]
})
this.age = this.form.get("age");
}
}
Example: https://plnkr.co/edit/me0pHePkcM5xPQ7nzJwZ?p=preview
The accepted answer from Sergey Voronezhskiy works perfect in development mode but if you try build in --prod mode you will get this error.
... Property 'warnings' does not exist on type 'FormControl'.
In order to fix this error I did adjustments to the original code (App class), basically to fix loosely typed variables. This is the new version:
export class FormControlWarn extends FormControl { warnings: any; }
export function tooBigAgeWarning(c: FormControlWarn ) {
if (!c.value) { return null; }
let val = +c.value;
c.warnings = val > 90 && val <= 120 ? { tooBigAge: {val} } : null;
return null;
}
export function impossibleAgeValidator(c: AbstractControl) {
if (tooBigAgeWarning(c) !== null) { return null; }
let val = +c.value;
return val > 120 ? { impossibleAge: {val} } : null;
}
@Component({
selector: 'my-app',
template: `
<div [formGroup]="form">
Age: <input formControlName="age"/>
<div *ngIf="age.errors?.required" [hidden]="age.pristine">
Error! Age is required
</div>
<div *ngIf="age.errors?.impossibleAge" [hidden]="age.pristine">
Error! Age is greater then 120
</div>
<div *ngIf="age.warnings?.tooBigAge" [hidden]="age.pristine">
Warning! Age is greater then 90
</div>
<p><button type=button [disabled]="!form.valid">Send</button>
</div>
`,
})
export class App {
get age(): FormControlWarn{
return <FormControlWarn>this.form.get("age");
}
constructor(private _fb: FormBuilder) { }
ngOnInit() {
this.form = this._fb.group({
age: new FormControlWarn('', [
Validators.required,
tooBigAgeWarning,
impossibleAgeValidator])
});
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With