Reputation: 1100
I'm developing an application with angular 8 in which I have an input that contains only year number. I have used mat-datepicker and want only to choose year.
<mat-form-field class="input-control">
<input matInput placeholder="{{'enter'|translate}}.." [formControl]="form.controls.openedAt"
[matDatepicker]="date" readonly>
<mat-datepicker-toggle matSuffix [for]="date"></mat-datepicker-toggle>
<mat-datepicker #date startView="multi-year"></mat-datepicker>
</mat-form-field>
this code shows year view first, but when I choose the year, the month view will be opened, then days view.
So how can I select only year, or show only year view on mat-datepicker?
Upvotes: 17
Views: 42864
Reputation: 204
Simple and native solution (without moment):
HTML:
<mat-form-field appearance="outline">
<mat-label>Year</mat-label>
<input
matInput
placeholder="YYYY"
[matDatepicker]="datePicker"
formControlName="date"
(focus)="datePicker?.open()"
/>
<mat-datepicker-toggle matSuffix [for]="datePicker"></mat-datepicker-toggle>
<mat-datepicker
#datePicker
color="primary"
startView="multi-year"
(yearSelected)="onYearSelected($event, datePicker)"
[startAt]="minDate"
></mat-datepicker>
<mat-error></mat-error>
</mat-form-field>
Typescript:
import { Component } from '@angular/core';
import { DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter } from '@angular/material/core';
class CustomDateAdapter extends NativeDateAdapter {
format(date: Date): string {
return `${date.getFullYear()}`;
}
}
@Component({
selector: 'app-component',
templateUrl: './component.html',
styleUrls: ['./component.scss'],
providers: [
{ provide: DateAdapter, useClass: CustomDateAdapter },
{
provide: MAT_DATE_FORMATS,
useValue: {
parse: { dateInput: 'YYYY' },
display: { dateInput: 'YYYY', monthYearLabel: 'YYYY', dateA11yLabel: 'LL', monthYearA11yLabel: 'YYYY' },
},
},
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
....
public onYearSelected(date: Date, datepicker: MatDatepicker<Date>) {
const normalizedYear = date.getFullYear();
form.controls.date.setValue(new Date(normalizedYear, 12, 0));
datepicker.close();
}
}
Upvotes: 1
Reputation: 111
I did like this (Angular 14 supported):
component.html :
<mat-form-field appearance="outline">
<mat-label>Ano</mat-label>
<input [(ngModel)]="selectYear" [formControl]="dateForm" matInput [matDatepicker]="picker" />
<mat-datepicker-toggle matSuffix [for]="picker" ></mat- datepicker-toggle>
<mat-datepicker #picker startView="multi-year" (yearSelected)="chosenYearHandler($event, picker)">
</mat-datepicker>
</mat-form-field>
component.ts :
export const MY_FORMATS = {
parse: {
dateInput: 'YYYY',
},
display: {
dateInput: 'YYYY',
monthYearLabel: 'YYYY',
monthYearA11yLabel: 'YYYY',
},
};
@Component({
providers: [
{
provide: DateAdapter,
useClass: MomentDateAdapter,
deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
},
{
provide: MAT_DATE_FORMATS, useValue: MY_FORMATS
},
]
})
export class MainFormComponent implements OnInit {
@ViewChild('picker', { static: false })
private picker!: MatDatepicker<Date>;
chosenYearHandler(ev, input){
let { _d } = ev;
this.selectYear = _d;
this.picker.close()
}
}
Its works well and very simple!!!
Upvotes: 11
Reputation: 2078
This feature is not fully implemented yet. You can see that here:
https://github.com/angular/components/issues/4853
For now you can try this:
https://stackblitz.com/edit/angular-mulitdate-picker-demo
Upvotes: 14