ng-ytl-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
478 lines (435 loc) • 18.3 kB
text/typescript
import { ConnectedOverlayPositionChange, ConnectionPositionPair } from '@angular/cdk/overlay';
import {
forwardRef,
ChangeDetectorRef,
Component,
ElementRef,
Input,
OnInit,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import * as moment from 'moment';
import { DayInterface, MonthInterface } from '../calendar/nz-calendar.component';
import { dropDownAnimation } from '../core/animation/dropdown-animations';
import { DEFAULT_DATEPICKER_POSITIONS } from '../core/overlay/overlay-position-map';
import { NzLocaleService } from '../locale/index';
import { NzTimePickerInnerComponent } from '../time-picker/nz-timepicker-inner.component';
import { toBoolean } from '../util/convert';
export class NzDatePickerComponent implements ControlValueAccessor, OnInit {
private _allowClear = true;
private _disabled = false;
private _showTime: Partial<NzTimePickerInnerComponent> = null;
_el: HTMLElement;
_open = false;
_mode = 'year';
_dropDownPosition = 'bottom';
_value: Date = null;
_disabledDate;
_today = new Date();
_selectedMonth = moment(this.nzValue).month();
_selectedYear = moment(this.nzValue).year();
_selectedDate = moment(this.nzValue).date();
_showMonth = moment(new Date()).month();
_showYear = moment(new Date()).year();
_startDecade = Math.floor(this._showYear / 10) * 10;
_yearPanel: string[][] = [];
_positions: ConnectionPositionPair[] = [ ...DEFAULT_DATEPICKER_POSITIONS ];
// ngModel Access
onChange: (value: Date) => void = () => null;
onTouched: () => void = () => null;
nzPlaceHolder = this._locale.translate('DateTime.chooseDatePlease');
nzFormat = 'YYYY-MM-DD';
nzSize = '';
nzMode: 'day' | 'month' = 'day';
trigger;
timePickerInner: NzTimePickerInnerComponent;
set nzShowTime(value: Partial<NzTimePickerInnerComponent>) {
if (typeof value === 'string' || typeof value === 'boolean') {
this._showTime = toBoolean(value) ? {} : null;
} else {
this._showTime = value;
}
}
get nzShowTime(): Partial<NzTimePickerInnerComponent> {
return this._showTime;
}
set nzAllowClear(value: boolean) {
this._allowClear = toBoolean(value);
}
get nzAllowClear(): boolean {
return this._allowClear;
}
set nzDisabled(value: boolean) {
this._disabled = toBoolean(value);
this._closeCalendar();
}
get nzDisabled(): boolean {
return this._disabled;
}
set nzDisabledDate(value: () => boolean) {
this._disabledDate = value;
}
get nzDisabledDate(): () => boolean {
if (this._mode === 'month' && this.nzMode === 'day') {
return;
}
return this._disabledDate;
}
get _disabledToday(): boolean {
if (this._disabledDate) {
return this._disabledDate(new Date());
} else {
return false;
}
}
onPositionChange(position: ConnectedOverlayPositionChange): void {
const _position = position.connectionPair.originY === 'bottom' ? 'top' : 'bottom';
if (this._dropDownPosition !== _position) {
this._dropDownPosition = _position;
this._cdr.detectChanges();
}
}
get nzValue(): Date {
return this._value || new Date();
}
set nzValue(value: Date) {
this._updateValue(value);
}
_changeTime($event: Date): void {
this._value = $event;
}
_blurInput(box: HTMLInputElement): void {
if (Date.parse(box.value)) {
this.nzValue = new Date(box.value);
this.onChange(this._value);
}
}
_preYear(): void {
this._showYear = this._showYear - 1;
}
_nextYear(): void {
this._showYear = this._showYear + 1;
}
_preMonth(): void {
if (this._showMonth - 1 < 0) {
this._showMonth = 11;
this._preYear();
} else {
this._showMonth = this._showMonth - 1;
}
}
_nextMonth(): void {
if (this._showMonth + 1 > 11) {
this._showMonth = 0;
this._nextYear();
} else {
this._showMonth = this._showMonth + 1;
}
}
_setShowYear(year: number, $event: MouseEvent): void {
$event.stopPropagation();
this._showYear = year;
this._mode = this.nzMode === 'day' ? 'year' : 'month';
}
_preDecade(): void {
this._startDecade = this._startDecade - 10;
}
_nextDecade(): void {
this._startDecade = this._startDecade + 10;
}
_clearValue(e: MouseEvent): void {
e.preventDefault();
e.stopPropagation();
this.nzValue = null;
this.onChange(this._value);
}
_changeToToday(): void {
if (!this._disabledToday) {
this.nzValue = new Date();
this.onChange(this._value);
this._closeCalendar();
}
}
_clickDay(day: DayInterface): void {
if (!this.nzShowTime) {
this._closeCalendar();
this.nzValue = day.date.toDate();
this.onChange(this._value);
} else {
this.nzValue = moment(this.nzValue).year(day.date.year()).month(day.date.month()).date(day.date.date()).toDate();
this.onChange(this._value);
}
}
_clickMonth(month: MonthInterface): void {
if (this.nzMode === 'month') {
this._closeCalendar();
this.nzValue = moment(this.nzValue).year(this._showYear).month(month.index).toDate();
this.onChange(this._value);
} else {
this._showMonth = month.index;
this._mode = 'year';
}
}
_openCalendar(): void {
if (this.nzDisabled) {
return;
}
this._mode = this.nzMode === 'day' ? 'year' : 'month';
this._open = true;
}
_closeCalendar(): void {
if (!this._open) {
return;
}
if (this.nzShowTime) {
this._updateValue(this._value);
this.onChange(this._value);
}
this._open = false;
}
_changeMonthView(): void {
this._mode = 'month';
}
_changeDecadeView($event: MouseEvent): void {
$event.stopPropagation();
this._mode = 'decade';
}
_changeTimeView($event: MouseEvent): void {
$event.stopPropagation();
this._mode = 'time';
setTimeout(_ => {
this.timePickerInner._initPosition();
});
}
_changeYearView($event: MouseEvent): void {
$event.stopPropagation();
this._mode = 'year';
}
get _showClearIcon(): boolean {
return this._value && !this.nzDisabled && this.nzAllowClear;
}
_generateYearPanel(): void {
let _t = [];
for (let i = 0; i < 10; i++) {
if (i === 1 || i === 4 || i === 7 || i === 9) {
_t.push(i);
this._yearPanel.push(_t);
_t = [];
} else {
_t.push(i);
}
}
this._yearPanel[ 0 ].unshift('start');
this._yearPanel[ 3 ].push('end');
}
constructor(private _elementRef: ElementRef, private _cdr: ChangeDetectorRef, private _locale: NzLocaleService) {
this._el = this._elementRef.nativeElement;
}
ngOnInit(): void {
this._generateYearPanel();
}
writeValue(value: Date): void {
// this.nzValue = value;
this._updateValue(value);
}
registerOnChange(fn: (_: Date) => void): void {
this.onChange = fn;
}
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
this.nzDisabled = isDisabled;
}
private _updateValue(value: Date): void {
if (this._value === value) {
return;
}
if (this._disabledDate && this._disabledDate(value)) {
return;
}
this._value = value;
this._selectedMonth = moment(this.nzValue).month();
this._selectedYear = moment(this.nzValue).year();
this._selectedDate = moment(this.nzValue).date();
this._showYear = moment(this.nzValue).year();
this._showMonth = moment(this.nzValue).month();
this._startDecade = Math.floor(this._showYear / 10) * 10;
}
}