How to select only year on mat-datepicker
Asked Answered
G

3

16

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?

Grad answered 3/2, 2020 at 10:36 Comment(0)
W
14

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

Waterborne answered 3/2, 2020 at 11:36 Comment(1)
material.angular.io/components/datepicker/…Discarnate
A
11

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!!!

Aeneas answered 6/7, 2021 at 13:56 Comment(1)
Your solution was pretty awesome! but I found that "input._destroyPopup()" did not work so i had to use @ViewChild to access the datepicker and close it using the "close" function. my code: @ViewChild('picker', {static: false}) private picker: MatDatepicker<Date>; and the chosenYearHandler method was changed to this: chosenYearHandler(ev, input){ let { _d } = ev; this.selectYear = _d; this.picker.close(); }Collusion
F
0

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();
  }
}
Frill answered 17/5, 2023 at 4:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.