Open j-martinez-dev opened 3 years ago
Definitely an issue, but I suspect that it'll be difficult to resolve without regressing on other issues like https://github.com/angular/components/issues/20213.
This directive could serve as a hot fix until this is fixed in the date range picker component itself:
@Directive({
selector: 'mat-date-range-input'
})
export class UpdateDateRangeValueAndValidityFixerDirective
implements AfterContentInit, OnDestroy {
private readonly destroyed$ = new Subject<void>();
constructor(private readonly formGroupName: FormGroupName) {}
ngAfterContentInit(): void {
const startFormControl = this.formGroupName.control.get('start'); //unfortunatelly this would work only if the form controls are named 'start' or 'end', feel free to use your names. I've used the ones from the showcase that is in the official docs https://material.angular.io/components/datepicker/examples
const endFormControl = this.formGroupName.control.get('end');
startFormControl.valueChanges
.pipe(distinctUntilChanged(), takeUntil(this.destroyed$))
.subscribe(() => endFormControl.updateValueAndValidity());
endFormControl.valueChanges
.pipe(distinctUntilChanged(), takeUntil(this.destroyed$))
.subscribe(() => startFormControl.updateValueAndValidity());
}
ngOnDestroy(): void {
this.destroyed$.next();
}
}
Found this issue today. Happening as of Angular 12.1.1
I'm also facing the same issue using the following versions
"@angular/common": "12.1.3",
"@angular/material": "12.1.3",
Are there any plans for this issue to be fixed?
@marek-aguita , great solution. I improve a little your directive to not depends on form control names.
@Directive({
selector: 'mat-date-range-input'
})
export class UpdateDateRangeValueAndValidityFixerDirective
implements AfterContentInit, OnDestroy {
+ @ContentChild(MatStartDate, { read: FormControlName }) startDateControlName: FormControlName;
+ @ContentChild(MatEndDate, { read: FormControlName }) endDateControlName: FormControlName;
+
private readonly destroyed$ = new Subject<void>();
- constructor(private readonly formGroupName: FormGroupName) {}
-
ngAfterContentInit(): void {
- const startFormControl = this.formGroupName.control.get('start'); //unfortunatelly this would work only if the form controls are named 'start' or 'end', feel free to use your names. I've used the ones from the showcase that is in the official docs https://material.angular.io/components/datepicker/examples
- const endFormControl = this.formGroupName.control.get('end');
-
- startFormControl.valueChanges
+ this.startDateControlName.valueChanges
.pipe(distinctUntilChanged(), takeUntil(this.destroyed$))
- .subscribe(() => endFormControl.updateValueAndValidity());
+ .subscribe(() => setTimeout(() => this.endDateControlName.control.updateValueAndValidity()));
- endFormControl.valueChanges
+ this.endDateControlName.valueChanges
.pipe(distinctUntilChanged(), takeUntil(this.destroyed$))
- .subscribe(() => startFormControl.updateValueAndValidity());
+ .subscribe(() => setTimeout(() => this.startDateControlName.control.updateValueAndValidity()));
}
ngOnDestroy(): void {
this.destroyed$.next();
}
}
UPD 2023-04-03: Add setTimeout()
Reproduction
Use StackBlitz to reproduce your issue: https://stackblitz.com/edit/angular-uotl3m-yzo7qt
Steps to reproduce:
Modify the end date using the input with a date after the start date
Expected Behavior
The FormGroup is valid and not error message is show.
Actual Behavior
What behavior did you actually see?
The error message "Invalid start date" is show.
If you change the version of material from "^11.0.0" to "11.0.0" there is no problemr
Environment