Reputation: 445
I’m working on an app that uses an angular material datepicker.
This datepicker returns a date object in ISO 8601 format I want to get the format yyyy-MM-dd in string. For this, I created the following code:
HTML:
<mat-form-field class="example-full-width" appearance="fill">
<mat-label>{{ 'commons.consultations.dateTo' | translate }}</mat-label>
<input matInput [matDatepicker]="pickerTo" formControlName="dateTo" />
<mat-datepicker-toggle
matSuffix
[for]="pickerTo"
></mat-datepicker-toggle>
<mat-datepicker
(closed)="convertDateTo_YYYY_MM_DD_Format()"
#pickerTo
></mat-datepicker>
</mat-form-field>
ts file:
public convertDateTo_YYYY_MM_DD_Format() {
this.form
.get('dateTo')
?.setValue(
this.datePipe.transform(this.form.get('dateTo')?.value, 'yyyy-MM-dd')
);
}
module.ts (format fr-FR)
providers: [{ provide: MAT_DATE_LOCALE, useValue: 'fr-FR' }, DatePipe]
In my code, I have a custom validator that checks that the date is in the format yyyy-MM-dd:
export function dateValidator(
dateTo: string,
): ValidatorFn {
return (form: AbstractControl): ValidationErrors | null => {
let dateTo = form.get(dateTo );
const regEx = /^[12]\d{3}-\d{2}-\d{2}$/;
//...............
if (dateTo.value?.match(regEx)) {
// do some stuff.....................
}
The problem with this code is that the validator is triggered even before the function call that depends on the event datepicker (closed).
(closed)=convertDateTo_YYYY_MM_DD_Format()
My question is: is there a way for the datepicker itself to convert the date to the desired format (yyyy-MM-dd) without going through the closed event before the validator is triggered?
Thanks for your help
Upvotes: 0
Views: 262
Reputation: 1014
There is a way to get the desired date format directly from the datepicker without relying on the closed event. You can use the MatDatepickerInputEvent that is emitted when the user selects a date, and then convert the selected date to the desired format using the DatePipe. Here's an example:
HTML
<mat-form-field class="example-full-width" appearance="fill">
<mat-label>{{ 'commons.consultations.dateTo' | translate }}</mat-label>
<input matInput [matDatepicker]="pickerTo" formControlName="dateTo" (dateChange)="onDateChange($event)" />
<mat-datepicker-toggle matSuffix [for]="pickerTo"></mat-datepicker-toggle>
<mat-datepicker #pickerTo></mat-datepicker>
</mat-form-field>
TS file
import { DatePipe } from '@angular/common';
constructor(private datePipe: DatePipe) {}
public onDateChange(event: MatDatepickerInputEvent<Date>) {
const formattedDate = this.datePipe.transform(event.value, 'yyyy-MM-dd');
this.form.get('dateTo')?.setValue(formattedDate);
}
Updated Code using subscribe method
HTML
<mat-form-field class="example-full-width" appearance="fill">
<mat-label>{{ 'commons.consultations.dateTo' | translate }}</mat-label>
<input matInput [matDatepicker]="pickerTo" formControlName="dateTo" />
<mat-datepicker-toggle matSuffix [for]="pickerTo"></mat-datepicker-toggle>
<mat-datepicker #pickerTo></mat-datepicker>
</mat-form-field>
TS
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { DatePipe } from '@angular/common';
import { Subscription } from 'rxjs';
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
})
export class ExampleComponent implements OnInit {
form: FormGroup;
dateToSubscription: Subscription;
constructor(
private fb: FormBuilder,
private datePipe: DatePipe
) {}
ngOnInit() {
this.form = this.fb.group({
dateTo: ['', Validators.required],
});
// Subscribe to the valueChanges of dateTo form control
this.dateToSubscription = this.form
.get('dateTo')
.valueChanges.subscribe((dateTo: Date) => {
// If the date is valid, format it and update the form control value
if (dateTo instanceof Date && !isNaN(dateTo.getTime())) {
const formattedDate = this.datePipe.transform(dateTo, 'yyyy-MM-dd');
this.form.get('dateTo').setValue(formattedDate);
}
});
}
ngOnDestroy() {
this.dateToSubscription.unsubscribe();
}
}
Upvotes: 0