import { Component, Input, Output, EventEmitter, forwardRef, OnInit } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import * as moment from 'moment'; import { getMonth } from './calendar-utils'; import './calendar.scss'; const CALENDAR_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CalendarComponent), multi: true }; @Component({ selector: 'swui-calendar', providers: [CALENDAR_VALUE_ACCESSOR], template: `
{{ activeDate | amDateFormat: 'MMMM YYYY' }}
{{d}}
`, host: { class: 'swui-calendar', tabindex: '1', '(blur)': 'onTouchedCallback()' } }) export class CalendarComponent implements OnInit, ControlValueAccessor { @Input() minDate: Date; @Input() disabled: boolean; @Input() maxDate: Date; @Input() daysOfWeek: string[] = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; @Output() change: EventEmitter = new EventEmitter(); get value() { return this._value; } set value(val: any) { const isSame = moment(val).isSame(this._value, 'day'); if (!isSame) { this._value = val; this.onChangeCallback(this._value); this.change.emit(this._value); } } private activeDate: any; private _value: any; private weeks: any[]; ngOnInit() { this.activeDate = moment(this.value); this.weeks = getMonth(this.activeDate); } getDayClass(day) { return { 'first-day-of-month': day.num === 1, 'last-day-of-week': day.dayOfWeek === 6, today: day.today, active: day.date.isSame(this.value, 'day') }; } getDayDisabled(date) { if(this.disabled) return true; if(!date) return false; const isBeforeMin = this.minDate && date.isSameOrBefore(this.minDate); const isAfterMax = this.maxDate && date.isSameOrAfter(this.maxDate); return isBeforeMin || isAfterMax; } onDayClick(day) { this.value = day.clone().toDate(); } prevMonth() { let date = this.activeDate.clone(); this.activeDate = date.subtract(1, 'month'); this.weeks = getMonth(this.activeDate); } nextMonth() { let date = this.activeDate.clone(); this.activeDate = date.add(1, 'month'); this.weeks = getMonth(this.activeDate); } writeValue(val: any) { const isSame = moment(val).isSame(this.value, 'day'); if (!isSame) { this._value = val; this.activeDate = moment(val); this.weeks = getMonth(this.activeDate); } } registerOnChange(fn: any) { this.onChangeCallback = fn; } registerOnTouched(fn: any) { this.onTouchedCallback = fn; } private onTouchedCallback: () => void = () => { // placeholder } private onChangeCallback: (_: any) => void = () => { // placeholder } }