UNPKG

ng-ytl-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

369 lines (334 loc) 12.2 kB
import { forwardRef, ChangeDetectorRef, Component, Input, OnInit, ViewChild, ViewEncapsulation, } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import * as moment from 'moment'; import { dropDownAnimation } from '../core/animation/dropdown-animations'; import { reqAnimFrame } from '../core/polyfill/request-animation'; import { NzLocaleService } from '../locale/index'; import { toBoolean } from '../util/convert'; export interface TimeUnitInterface { index: number; name: string; disabled: boolean; } @Component({ selector : 'nz-timepicker-inner', encapsulation: ViewEncapsulation.None, template : ` <span class="ant-calendar-time-picker" [ngClass]="{'ant-time-picker-large':nzSize=='large','ant-time-picker-small':nzSize=='small'}"> <div class="ant-calendar-time-picker-panel" [@dropDownAnimation]="'bottom'"> <div class="ant-calendar-time-picker-inner" [class.ant-calendar-time-picker-column-3]="_showHour&&_showMinute&&_showSecond" [class.ant-calendar-time-picker-column-2]="_showHour&&_showMinute&&!_showSecond" [class.ant-calendar-time-picker-column-1]="_showHour&&(!_showMinute)&&(!_showSecond)"> <div class="ant-calendar-time-picker-combobox"> <div class="ant-calendar-time-picker-select" #hourListInstance *ngIf="_showHour"> <ul> <ng-template ngFor let-_hour [ngForOf]="_hourList" let-i="index"> <li [ngClass]="_hour.name" *ngIf="!(nzHideDisabledOptions&&_hour.disabled)" [class.ant-time-picker-panel-select-option-selected]="_hour.index===_selectedHour" [class.ant-time-picker-panel-select-option-disabled]="_hour.disabled" (click)="_selectHour(hourListInstance,_hour.index,_hour.disabled)"> {{ _hour.name }} </li> </ng-template> </ul> </div> <div class="ant-calendar-time-picker-select" #minuteListInstance *ngIf="_showMinute"> <ul> <ng-template ngFor let-_minute [ngForOf]="_minuteList" let-i="index"> <li [ngClass]="_minute.name" *ngIf="!(nzHideDisabledOptions&&_minute.disabled)" [class.ant-time-picker-panel-select-option-selected]="_minute.index===_selectedMinute" [class.ant-time-picker-panel-select-option-disabled]="_minute.disabled" (click)="_selectMinute(minuteListInstance,_minute.index,_minute.disabled)"> {{ _minute.name }} </li> </ng-template> </ul> </div> <div class="ant-calendar-time-picker-select" #secondListInstance *ngIf="_showSecond"> <ul> <ng-template ngFor let-_second [ngForOf]="_secondList" let-i="index"> <li [ngClass]="_second.name" *ngIf="!(nzHideDisabledOptions&&_second.disabled)" [class.ant-time-picker-panel-select-option-selected]="_second.index===_selectedSecond" [class.ant-time-picker-panel-select-option-disabled]="_second.disabled" (click)="_selectSecond(secondListInstance,_second.index,_second.disabled)"> {{ _second.name }} </li> </ng-template> </ul> </div> </div> </div> </div> </span>`, animations : [ dropDownAnimation ], providers : [ { provide : NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzTimePickerInnerComponent), multi : true } ], styleUrls : [ './style/index.less', './style/patch.less' ] }) export class NzTimePickerInnerComponent implements OnInit, ControlValueAccessor { private _disabled = false; private _hideDisabledOptions = false; _now = new Date(); _el: HTMLElement; _open = false; _hourList: TimeUnitInterface[] = []; _minuteList: TimeUnitInterface[] = []; _secondList: TimeUnitInterface[] = []; _value = null; _selectedHour = moment(this._now).hours(); _selectedMinute = moment(this._now).minutes(); _selectedSecond = moment(this._now).seconds(); _format = 'HH:mm:ss'; _showHour = this._format.indexOf('HH') > -1; _showMinute = this._format.indexOf('mm') > -1; _showSecond = this._format.indexOf('ss') > -1; _width = `${( +this._showHour + +this._showMinute + +this._showSecond) * 56 + 1 }px`; _nzDisabledHours: () => number[]; // ngModel Access onChange: (value: Date) => void = () => null; onTouched: () => void = () => null; @ViewChild('hourListInstance') _hourListInstance; @ViewChild('minuteListInstance') _minuteListInstance; @ViewChild('inputTimeInstance') _inputTimeInstance; @ViewChild('secondListInstance') _secondListInstance; @Input() set nzHideDisabledOptions(value: boolean) { this._hideDisabledOptions = toBoolean(value); } get nzHideDisabledOptions(): boolean { return this._hideDisabledOptions; } @Input() nzPlaceHolder = this._locale.translate('DateTime.chooseTimePlease'); @Input() nzSize: 'small' | 'large' | 'default' = 'default'; @Input() set nzDisabledHours(fun: () => number[]) { this._nzDisabledHours = fun; this._buildHours(); } get nzDisabledHours(): () => number[] { return this._nzDisabledHours; } @Input() nzDisabledMinutes: (hour: number) => number[]; @Input() nzDisabledSeconds: (hour: number, minute: number) => number[]; @Input() set nzDisabled(value: boolean) { this._disabled = toBoolean(value); } get nzDisabled(): boolean { return this._disabled; } @Input() set nzFormat(value: string) { this._format = value; this._showHour = this._format.indexOf('HH') > -1; this._showMinute = this._format.indexOf('mm') > -1; this._showSecond = this._format.indexOf('ss') > -1; this._width = `${( +this._showHour + +this._showMinute + +this._showSecond) * 56 + 1 }px`; } get nzFormat(): string { return this._format; } get nzValue(): Date { return this._value || this._now; } set nzValue(value: Date) { if (this._value === value) { return; } this._value = value; this._selectedHour = moment(this.nzValue).hours(); this._selectedMinute = moment(this.nzValue).minutes(); this._selectedSecond = moment(this.nzValue).seconds(); } _scrollToSelected(instance: HTMLElement, index: number, duration: number = 0, unit: string): void { const _transIndex = this._translateIndex(index, unit); const currentOption = (instance.children[ 0 ].children[ _transIndex ] || instance.children[ 0 ].children[ 0 ]) as HTMLElement; this.scrollTo(instance, currentOption.offsetTop, duration); } // got from rc-timepicker scrollTo(element: HTMLElement, to: number, duration: number): void { if (duration <= 0) { element.scrollTop = to; return; } const difference = to - element.scrollTop; const perTick = difference / duration * 10; reqAnimFrame(() => { element.scrollTop = element.scrollTop + perTick; if (element.scrollTop === to) { return; } this.scrollTo(element, to, duration - 10); }); } _selectHour(instance: HTMLElement, index: number, disabled: boolean): void { if (disabled) { return; } this._scrollToSelected(instance, index, 120, 'hour'); this._selectedHour = index; this.nzValue = moment(this.nzValue).hour(index).toDate(); this.onChange(this._value); this._buildMinutes(); this._buildSeconds(); } _selectMinute(instance: HTMLElement, index: number, disabled: boolean): void { if (disabled) { return; } this._scrollToSelected(instance, index, 120, 'minute'); this._selectedMinute = index; this.nzValue = moment(this.nzValue).minute(index).toDate(); this.onChange(this._value); this._buildSeconds(); } _selectSecond(instance: HTMLElement, index: number, disabled: boolean): void { if (disabled) { return; } this._scrollToSelected(instance, index, 120, 'second'); this._selectedSecond = index; this.nzValue = moment(this.nzValue).second(index).toDate(); this.onChange(this._value); } _translateIndex(index: number, unit: string): number { if (!this.nzHideDisabledOptions) { return index; } if (unit === 'hour') { const disabledHours = this.nzDisabledHours && this.nzDisabledHours(); return this._calcIndex(disabledHours, index); } else if (unit === 'minute') { const disabledMinutes = this.nzDisabledMinutes && this.nzDisabledMinutes(this._selectedHour); return this._calcIndex(disabledMinutes, index); } else if (unit === 'second') { const disabledSeconds = this.nzDisabledSeconds && this.nzDisabledSeconds(this._selectedHour, this._selectedMinute); return this._calcIndex(disabledSeconds, index); } } _calcIndex(array: number[], index: number): number { if (array && array.length) { return index - array.reduce((pre, value) => { return pre + (value < index ? 1 : 0); }, 0); } else { return index; } } _initPosition(): void { this._selectedHour = moment(this.nzValue).hours(); this._selectedMinute = moment(this.nzValue).minutes(); this._selectedSecond = moment(this.nzValue).seconds(); if (this._showHour) { this._scrollToSelected(this._hourListInstance.nativeElement, this._selectedHour, 0, 'hour'); } if (this._showMinute) { this._scrollToSelected(this._minuteListInstance.nativeElement, this._selectedMinute, 0, 'minute'); } if (this._showSecond) { this._scrollToSelected(this._secondListInstance.nativeElement, this._selectedSecond, 0, 'second'); } } _buildTime(): void { this._buildHours(); this._buildMinutes(); this._buildSeconds(); } _buildHours(): void { this._hourList = []; for (let i = 0; i <= 23; i++) { this._hourList.push({ disabled: this.nzDisabledHours && (this.nzDisabledHours().indexOf(i) !== -1), name : i.toString().length === 1 ? ('0' + i) : ('' + i), index : i }); } } _buildMinutes(): void { this._minuteList = []; for (let i = 0; i <= 59; i++) { this._minuteList.push({ disabled: this.nzDisabledMinutes && (this.nzDisabledMinutes(this._selectedHour).indexOf(i) !== -1), name : i.toString().length === 1 ? ('0' + i) : ('' + i), index : i }); } } _buildSeconds(): void { this._secondList = []; for (let i = 0; i <= 59; i++) { this._secondList.push({ disabled: this.nzDisabledSeconds && (this.nzDisabledSeconds(this._selectedHour, this._selectedMinute).indexOf(i) !== -1), name : i.toString().length === 1 ? ('0' + i) : ('' + i), index : i }); } } writeValue(value: Date): void { this.nzValue = value; } registerOnChange(fn: (_: Date) => void): void { this.onChange = fn; } registerOnTouched(fn: () => void): void { this.onTouched = fn; } setDisabledState(isDisabled: boolean): void { this.nzDisabled = isDisabled; } constructor(public _cdr: ChangeDetectorRef, private _locale: NzLocaleService) { } ngOnInit(): void { this._buildTime(); } }