Issue
I have a component called program-stepper that has 2 child component called create-workout and create-program as the code shows below: the problem that the forms fields in the child components turns red when I navigate between the 2 components and did not touch any field yet, example on stackblitz
<mat-horizontal-stepper [linear]="true">
<ng-container *ngIf="!isLoading">
<mat-step>
<ng-template matStepLabel>Create Program</ng-template>
<app-create-program [program]="program" [editMode]="editMode" [programId]="programId" ></app-create-program>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
<mat-step>
<ng-template matStepLabel>Create Workout</ng-template>
<app-create-workout [editMode]="editMode" [programId]="programId" [trainingDays]="trainingDays"></app-create-workout>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button [disabled]="!areAllFormsValid()" (click)="onDoneClick()" *ngIf="!editMode">Done</button>
</div>
</mat-step>
</ng-container>
this is code of create-program component:
export class CreateProgramComponent implements OnInit {
validationMessages: { [key: string]: { [key: string]: string } };
programForm: FormGroup;
@Input() athleteId: string;
@Input() editMode: boolean;
@Input() programId: string;
@Input() program: ProgramDisplay;
constructor(
public dialogRef: MatDialogRef<CreateProgramComponent>,
private fb: FormBuilder,
private programService: ProgramService,
private toastr: ToastrService,
private utilityService: UtilityService,
private datePipe: DatePipe
) {
this.validationMessages = {
title: {
required: 'Title is required',
},
start_date: {
required: 'Start date is required',
},
end_date: {
required: 'End date is required',
}
};
}
ngOnInit(): void {
this.createForm();
if(this.editMode){
this.loadDataForEditMode();
}
}
createForm(){
this.programForm = this.fb.group({
title: [null, [Validators.required]],
start_date: [null, [Validators.required]],
end_date: [null, [Validators.required]],
});
}
isFieldValid(field: string): boolean | undefined {
const control = this.programForm.get(field);
return control?.touched && !control.valid && control.dirty;
}
I want to prevent the fields from turning red when the user did not touch them yet and when navigating from one component to another, note that the form validation works correctly when i don't navigate . how to achieve this behaviour, thank you!
Solution
Sorry for the late reply, I got it working using the input property errorStateMatcher
of angular material, where you set the condition on which the errors need to be shown, please find below a working example where your requirement seems to work fine!
html adding the matcher
...
<form [formGroup]="programForm">
<mat-form-field appearance="fill">
<mat-label>Title</mat-label>
<input
matInput
formControlName="title"
placeholder="Program Title"
[errorStateMatcher]="matcher"
/>
<!-- <mat-error *ngIf="isFieldValid('title')">
{{ validationMessages['title']['required'] }}
</mat-error> -->
</mat-form-field>
...
and in the TS it will be
export class MyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(
control: FormControl | null,
form: FormGroupDirective | null
): boolean {
const isSubmitted = form && form.submitted;
return !!(
control &&
control.invalid &&
(control.dirty || control.touched || isSubmitted)
);
}
}
...
export class CreateProgramComponent implements OnInit {
matcher = new MyErrorStateMatcher();
Answered By - Naren Murali
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.