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-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();
}
}