Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 Reactive Forms trigger validation on submit

is there a way that all validators of a reactive forms can be triggered upon submit and not only by the "dirty" and "touch" events?

The reason for this is we have a very large forms which doesn't indicate if a field is required or not, and user might miss some of the required control, so upon submit, it is expected that all of the invalid fields which are missed by the end user will be shown.

I have tried marking the form as "touched" by using the

FormGroup.markAsTouched(true); 

it worked, and so I also tried marking it as "dirty"

FormGroup.markAsDirty(true); 

but the css of the class is still "ng-pristine",

Is there a way to trigger it manually from the component, I tried googling it to no avail, thanks you in advance!

UPDATE

I already got it working by iterating the FormGroup.controls and marking it as "dirty", but is there a "standard" way to do this.

like image 535
arvstracthoughts Avatar asked Oct 06 '16 10:10

arvstracthoughts


2 Answers

This can be achieved with the sample presented here, where you can make use of NgForm directive:

<form [formGroup]="heroForm" #formDir="ngForm"> 

and then in your validation messages just check if the form is submitted:

<small *ngIf="heroForm.hasError('required', 'formCtrlName') && formDir.submitted">   Required! </small> 

EDIT: Now is also { updateOn: 'submit'} is provided, but that works only if you do not have required on the form, as required is displayed initially anyway. You can suppress that with checking if field has been touched though.

// fb is 'FormBuilder' this.heroForm = this.fb.group({  // ... }, { updateOn: 'submit'}) 
like image 122
AT82 Avatar answered Sep 19 '22 21:09

AT82


Coming back after some months, I share here the improved version based on all the comments, just for the record:

markAsTouched(group: FormGroup | FormArray) {   group.markAsTouched({ onlySelf: true });    Object.keys(group.controls).map((field) => {     const control = group.get(field);     if (control instanceof FormControl) {       control.markAsTouched({ onlySelf: true });     } else if (control instanceof FormGroup) {       this.markAsTouched(control);     }   }); } 

Hope it will be useful!

UPDATE: Angular 8 introduced FormGroup.markAllAsTouched() and it does this! :D

like image 24
Mateo Tibaquira Avatar answered Sep 20 '22 21:09

Mateo Tibaquira