So I'm using angular 11 and struggling to get the following behavior : A stepper, with two inputs in a single steps, that are a datepicker and a select (a dropdown menu). Then I want the stepControl to validate that both fields have been filled, and be able to retrieve their values.
In my example I have many steps, but here is the one that give me troubles.
HTML :
<mat-vertical-stepper>
<!-- First steps... -->
<mat-step state="date" [stepControl]="fourthFormGroup">
<form [formGroup]="fourthFormGroup">
<mat-form-field>
<ng-template matStepLabel>Placeholder Text Date</ng-template>
<input matInput [min]="minDate" [matDatepicker]="picker" [formControl]="date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<br/>
<mat-form-field>
<mat-label>Placeholder Text Hour</mat-label>
<mat-select [formControl]="hours" required>
<mat-option *ngFor="let j of hours" [value]="j[0]">
{{j[1]}}
</mat-option>
</mat-select>
</mat-form-field>
</form>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button (click)="searchNow()">Search</button>
</div>
</mat-step>
</mat-vertical-stepper>
TS declaration :
public fourthFormGroup: FormGroup;
TS in ngOnInit :
this.fourthFormGroup = this._formBuilder.group({
date: new FormControl(new Date()),
hours: new FormControl('', Validators.required)
});
Why it doesn't work :
I am unable to retrieve the values from this form. Also, validating the form with empty fields generate backend error but is not prevented by the frontend-component as you would expect it (to light up in the red and say the field is required).
Many thanks for your help ! Kev'.
The Problem you are facing is that you are mixing the directives. You are binding a [FormControl]
to undefined values e.g [formControl]='date'
will definitely not work.
Change [formControl]='date'
to formControlName='date'
and formControl="hours"
to formControlName="hours"
See this demo
NB
I believe a better approach would simply to have one formGroup
for all your inputs
myForm = this.formBuilder.group({
thirdFormControl: ['', [Validators.required]],
date: [new Date(), [Validators.required]],
hours: ["", [Validators.required]]
})
And amend your html
<form [formGroup]='myForm'>
<mat-vertical-stepper [linear]="true" #stepper>
<mat-step [stepControl]="step[0]" [optional]="true">
<ng-template matStepLabel>Placeholder title</ng-template>
<mat-form-field>
<mat-label>Placeholder label</mat-label>
<textarea
matInput
cdkTextareaAutosize
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="2"
cdkAutosizeMaxRows="10"
placeholder="Optionnel"
formControlName="thirdFormControl"
></textarea>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
<mat-step state="date" [stepControl]="step[1]">
<mat-form-field>
<ng-template matStepLabel>Placeholder label 0</ng-template>
<input
matInput
[min]="minDate"
[matDatepicker]="picker"
formControlName="date"
/>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
<br />
<mat-form-field>
<mat-label>Placeholder label 1</mat-label>
<mat-select formControlName="hours" required>
<mat-option *ngFor="let j of hours" [value]="j[0]">
{{j[1]}}
</mat-option>
</mat-select>
</mat-form-field>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button (click)="searchNow()">Search</button>
</div>
</mat-step>
</mat-vertical-stepper>
</form>
Now the form will be invalid if any of the inputs is not captured