import { Component, EventEmitter, Input, Output, ViewChild, forwardRef } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { DatePickerInnerComponent } from './datepicker-inner.component'; import { DatepickerConfig } from './datepicker.config'; export const DATEPICKER_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, // tslint:disable-next-line useExisting: forwardRef(() => DatePickerComponent), multi: true }; /* tslint:disable:component-selector-name component-selector-type */ @Component({ selector: 'datepicker', template: ` `, providers: [DATEPICKER_CONTROL_VALUE_ACCESSOR] }) /* tslint:enable:component-selector-name component-selector-type */ export class DatePickerComponent implements ControlValueAccessor { /** sets datepicker mode, supports: `day`, `month`, `year` */ @Input() datepickerMode = 'day'; /** default date to show if `ng-model` value is not specified */ @Input() initDate: Date; /** oldest selectable date */ @Input() minDate: Date; /** latest selectable date */ @Input() maxDate: Date; /** set lower datepicker mode, supports: `day`, `month`, `year` */ @Input() minMode: string; /** sets upper datepicker mode, supports: `day`, `month`, `year` */ @Input() maxMode: string; /** if false week numbers will be hidden */ @Input() showWeeks = true; /** format of day in month */ @Input() formatDay: string; /** format of month in year */ @Input() formatMonth: string; /** format of year in year range */ @Input() formatYear: string; /** format of day in week header */ @Input() formatDayHeader: string; /** format of title when selecting day */ @Input() formatDayTitle: string; /** format of title when selecting month */ @Input() formatMonthTitle: string; /** starting day of the week from 0-6 (0=Sunday, ..., 6=Saturday) */ @Input() startingDay: number; /** number of years displayed in year selection */ @Input() yearRange: number; /** if true only dates from the currently displayed month will be shown */ @Input() onlyCurrentMonth: boolean; /** if true shortcut`s event propagation will be disabled */ @Input() shortcutPropagation: boolean; /** number of months displayed in a single row of month picker */ @Input() monthColLimit: number; /** number of years displayed in a single row of year picker */ @Input() yearColLimit: number; /** array of custom css classes to be applied to targeted dates */ @Input() customClass: { date: Date; mode: string; clazz: string }[]; /** array of disabled dates */ @Input() dateDisabled: { date: Date; mode: string }[]; /** disabled days of the week from 0-6 (0=Sunday, ..., 6=Saturday) */ @Input() dayDisabled: number[]; /** currently active date */ @Input() get activeDate(): Date { return this._activeDate || this._now; } set activeDate(value: Date) { this._activeDate = value; } @Output() selectionDone: EventEmitter = new EventEmitter(undefined); /** callback to invoke when the activeDate is changed. */ @Output() activeDateChange: EventEmitter = new EventEmitter( undefined ); @ViewChild(DatePickerInnerComponent) _datePicker: DatePickerInnerComponent; onChange: any = Function.prototype; onTouched: any = Function.prototype; config: DatepickerConfig; protected _now: Date = new Date(); protected _activeDate: Date; constructor(config: DatepickerConfig) { this.config = config; this.configureOptions(); } configureOptions(): void { Object.assign(this, this.config); } onUpdate(event: any): void { this.activeDate = event; this.onChange(event); } onSelectionDone(event: Date): void { this.selectionDone.emit(event); } onActiveDateChange(event: Date): void { this.activeDateChange.emit(event); } // todo: support null value writeValue(value: any): void { if (this._datePicker.compare(value, this._activeDate) === 0) { return; } if (value && value instanceof Date) { this.activeDate = value; this._datePicker.select(value, false); return; } this.activeDate = value ? new Date(value) : void 0; } registerOnChange(fn: (_: any) => {}): void { this.onChange = fn; } registerOnTouched(fn: () => {}): void { this.onTouched = fn; } }