ZecKa
ZecKa

Reputation: 2934

mat-calendar : Display only month and year

How to control only date and year from component (without date picker) ?

I find a way to format date with moment following this discussion: Angular Material Datepicker - Month & Year ONLY . But I don't find a way to disable day selection.

I also try to switch current view to "multi-year" on monthSelected but the transition is flicky since monthSelected is trigger after calendar switch to "month" view.

Maybe there is another way to prevent mat-calendar to switch to month view ?

What I already do :

Stackblitz: https://stackblitz.com/edit/angular-rxexdn-kegubh

Typescript Component

import * as _moment from 'moment';
import { default as _rollupMoment, Moment } from 'moment';

const moment = _rollupMoment || _moment;

export const MY_FORMATS = {
  parse: {
    dateInput: 'MM/YYYY',
  },
  display: {
    dateInput: 'MM/YYYY',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM YYYY',
  },
};

@Component({
  selector: 'datepicker-inline-calendar-example',
  templateUrl: 'datepicker-inline-calendar-example.html',
  styleUrls: ['datepicker-inline-calendar-example.css'],
  providers: [

    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS],
    },

    { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS },
  ],
})
export class DatepickerInlineCalendarExample {
  date = new FormControl(moment());

  chosenYearHandler(normalizedYear: Moment) {
    const ctrlValue = this.date.value;
    ctrlValue.year(normalizedYear.year());
    this.date.setValue(ctrlValue);
  }

  chosenMonthHandler(normalizedMonth: Moment) {
    const ctrlValue = this.date.value;
    ctrlValue.month(normalizedMonth.month());
    this.date.setValue(ctrlValue);
  }
}

Template component

<mat-calendar
    [selected]="date"
    startView="multi-year"
    (yearSelected)="chosenYearHandler($event)"
    (monthSelected)="chosenMonthHandler($event)"
  ></mat-calendar>
  <p>date: {{date.value.format("MM/YYYY")}}</p>

Upvotes: 3

Views: 10152

Answers (2)

Clement MAUGER
Clement MAUGER

Reputation: 36

Use ChangeDetectorRef for detach view from change detection system at the end of your yearSelected or monthSelected. In viewChanged event set calendar.currentView to 'multi-year' or 'year' in function of type 'year' or 'month' and reattach to change detection system after.

Care to mat-calandar header impact.

Stackblitz : https://stackblitz.com/edit/angular-rxexdn-lc5xcx?file=src/app/datepicker-inline-calendar-example.ts

Upvotes: 2

Jarek C. Sour
Jarek C. Sour

Reputation: 94

chosenMonthHandler() need to receive something like

datepicker: MatDatepicker<Moment>

and in the end u need add

datepicker.close();

https://stackblitz.com/edit/angular-ryjq7n?file=package.json

Upvotes: 1

Related Questions