UNPKG

ng2-date-picker

Version:

[![Build Status](https://travis-ci.org/vlio20/angular-datepicker.svg?branch=master)](https://travis-ci.org/vlio20/angular-datepicker) [![Backers on Open Collective](https://opencollective.com/angular-datepicker/backers/badge.svg)](#backers) [![Sponsor

1,162 lines (1,152 loc) 118 kB
import { __decorate, __metadata, __param } from 'tslib'; import { Injectable, EventEmitter, Input, HostBinding, Output, Component, ViewEncapsulation, ChangeDetectionStrategy, forwardRef, ChangeDetectorRef, ViewChild, ElementRef, HostListener, Renderer, Directive, Optional, ViewContainerRef, ComponentFactoryResolver, NgModule } from '@angular/core'; import { NG_VALUE_ACCESSOR, NG_VALIDATORS, NgControl, FormsModule } from '@angular/forms'; import { CommonModule } from '@angular/common'; import * as momentNs from 'moment'; var ECalendarMode; (function (ECalendarMode) { ECalendarMode[ECalendarMode["Day"] = 0] = "Day"; ECalendarMode[ECalendarMode["DayTime"] = 1] = "DayTime"; ECalendarMode[ECalendarMode["Month"] = 2] = "Month"; ECalendarMode[ECalendarMode["Time"] = 3] = "Time"; })(ECalendarMode || (ECalendarMode = {})); var ECalendarValue; (function (ECalendarValue) { ECalendarValue[ECalendarValue["Moment"] = 1] = "Moment"; ECalendarValue[ECalendarValue["MomentArr"] = 2] = "MomentArr"; ECalendarValue[ECalendarValue["String"] = 3] = "String"; ECalendarValue[ECalendarValue["StringArr"] = 4] = "StringArr"; })(ECalendarValue || (ECalendarValue = {})); var SelectEvent; (function (SelectEvent) { SelectEvent["INPUT"] = "input"; SelectEvent["SELECTION"] = "selection"; })(SelectEvent || (SelectEvent = {})); var DomHelper_1; let DomHelper = DomHelper_1 = class DomHelper { static setYAxisPosition(element, container, anchor, drops) { const anchorRect = anchor.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); const bottom = anchorRect.bottom - containerRect.top; const top = anchorRect.top - containerRect.top; if (drops === 'down') { element.style.top = (bottom + 1 + 'px'); } else { element.style.top = (top - 1 - element.scrollHeight) + 'px'; } } static setXAxisPosition(element, container, anchor, dimElem, opens) { const anchorRect = anchor.getBoundingClientRect(); const containerRect = container.getBoundingClientRect(); const left = anchorRect.left - containerRect.left; if (opens === 'right') { element.style.left = left + 'px'; } else { element.style.left = left - dimElem.offsetWidth + anchor.offsetWidth + 'px'; } } static isTopInView(el) { const { top } = el.getBoundingClientRect(); return (top >= 0); } static isBottomInView(el) { const { bottom } = el.getBoundingClientRect(); return (bottom <= window.innerHeight); } static isLeftInView(el) { const { left } = el.getBoundingClientRect(); return (left >= 0); } static isRightInView(el) { const { right } = el.getBoundingClientRect(); return (right <= window.innerWidth); } appendElementToPosition(config) { const { container, element } = config; if (!container.style.position || container.style.position === 'static') { container.style.position = 'relative'; } if (element.style.position !== 'absolute') { element.style.position = 'absolute'; } element.style.visibility = 'hidden'; setTimeout(() => { this.setElementPosition(config); element.style.visibility = 'visible'; }); } setElementPosition({ element, container, anchor, dimElem, drops, opens }) { DomHelper_1.setYAxisPosition(element, container, anchor, 'down'); DomHelper_1.setXAxisPosition(element, container, anchor, dimElem, 'right'); if (drops !== 'down' && drops !== 'up') { if (DomHelper_1.isBottomInView(dimElem)) { DomHelper_1.setYAxisPosition(element, container, anchor, 'down'); } else if (DomHelper_1.isTopInView(dimElem)) { DomHelper_1.setYAxisPosition(element, container, anchor, 'up'); } } else { DomHelper_1.setYAxisPosition(element, container, anchor, drops); } if (opens !== 'left' && opens !== 'right') { if (DomHelper_1.isRightInView(dimElem)) { DomHelper_1.setXAxisPosition(element, container, anchor, dimElem, 'right'); } else if (DomHelper_1.isLeftInView(dimElem)) { DomHelper_1.setXAxisPosition(element, container, anchor, dimElem, 'left'); } } else { DomHelper_1.setXAxisPosition(element, container, anchor, dimElem, opens); } } }; DomHelper = DomHelper_1 = __decorate([ Injectable() ], DomHelper); const moment = momentNs; let UtilsService = class UtilsService { static debounce(func, wait) { let timeout; return function () { const context = this, args = arguments; timeout = clearTimeout(timeout); setTimeout(() => { func.apply(context, args); }, wait); }; } ; createArray(size) { return new Array(size).fill(1); } convertToMoment(date, format) { if (!date) { return null; } else if (typeof date === 'string') { return moment(date, format); } else { return date.clone(); } } isDateValid(date, format) { if (date === '') { return true; } return moment(date, format, true).isValid(); } // todo:: add unit test getDefaultDisplayDate(current, selected, allowMultiSelect, minDate) { if (current) { return current.clone(); } else if (minDate && minDate.isAfter(moment())) { return minDate.clone(); } else if (allowMultiSelect) { if (selected && selected[selected.length]) { return selected[selected.length].clone(); } } else if (selected && selected[0]) { return selected[0].clone(); } return moment(); } // todo:: add unit test getInputType(value, allowMultiSelect) { if (Array.isArray(value)) { if (!value.length) { return ECalendarValue.MomentArr; } else if (typeof value[0] === 'string') { return ECalendarValue.StringArr; } else if (moment.isMoment(value[0])) { return ECalendarValue.MomentArr; } } else { if (typeof value === 'string') { return ECalendarValue.String; } else if (moment.isMoment(value)) { return ECalendarValue.Moment; } } return allowMultiSelect ? ECalendarValue.MomentArr : ECalendarValue.Moment; } // todo:: add unit test convertToMomentArray(value, format, allowMultiSelect) { switch (this.getInputType(value, allowMultiSelect)) { case (ECalendarValue.String): return value ? [moment(value, format, true)] : []; case (ECalendarValue.StringArr): return value.map(v => v ? moment(v, format, true) : null).filter(Boolean); case (ECalendarValue.Moment): return value ? [value.clone()] : []; case (ECalendarValue.MomentArr): return (value || []).map(v => v.clone()); default: return []; } } // todo:: add unit test convertFromMomentArray(format, value, convertTo) { switch (convertTo) { case (ECalendarValue.String): return value[0] && value[0].format(format); case (ECalendarValue.StringArr): return value.filter(Boolean).map(v => v.format(format)); case (ECalendarValue.Moment): return value[0] ? value[0].clone() : value[0]; case (ECalendarValue.MomentArr): return value ? value.map(v => v.clone()) : value; default: return value; } } convertToString(value, format) { let tmpVal; if (typeof value === 'string') { tmpVal = [value]; } else if (Array.isArray(value)) { if (value.length) { tmpVal = value.map((v) => { return this.convertToMoment(v, format).format(format); }); } else { tmpVal = value; } } else if (moment.isMoment(value)) { tmpVal = [value.format(format)]; } else { return ''; } return tmpVal.filter(Boolean).join(' | '); } // todo:: add unit test clearUndefined(obj) { if (!obj) { return obj; } Object.keys(obj).forEach((key) => (obj[key] === undefined) && delete obj[key]); return obj; } updateSelected(isMultiple, currentlySelected, date, granularity = 'day') { if (isMultiple) { return !date.selected ? currentlySelected.concat([date.date]) : currentlySelected.filter(d => !d.isSame(date.date, granularity)); } else { return !date.selected ? [date.date] : []; } } closestParent(element, selector) { if (!element) { return undefined; } const match = element.querySelector(selector); return match || this.closestParent(element.parentElement, selector); } onlyTime(m) { return m && moment.isMoment(m) && moment(m.format('HH:mm:ss'), 'HH:mm:ss'); } granularityFromType(calendarType) { switch (calendarType) { case 'time': return 'second'; case 'daytime': return 'second'; default: return calendarType; } } createValidator({ minDate, maxDate, minTime, maxTime }, format, calendarType) { let isValid; let value; const validators = []; const granularity = this.granularityFromType(calendarType); if (minDate) { const md = this.convertToMoment(minDate, format); validators.push({ key: 'minDate', isValid: () => { const _isValid = value.every(val => val.isSameOrAfter(md, granularity)); isValid = isValid ? _isValid : false; return _isValid; } }); } if (maxDate) { const md = this.convertToMoment(maxDate, format); validators.push({ key: 'maxDate', isValid: () => { const _isValid = value.every(val => val.isSameOrBefore(md, granularity)); isValid = isValid ? _isValid : false; return _isValid; } }); } if (minTime) { const md = this.onlyTime(this.convertToMoment(minTime, format)); validators.push({ key: 'minTime', isValid: () => { const _isValid = value.every(val => this.onlyTime(val).isSameOrAfter(md)); isValid = isValid ? _isValid : false; return _isValid; } }); } if (maxTime) { const md = this.onlyTime(this.convertToMoment(maxTime, format)); validators.push({ key: 'maxTime', isValid: () => { const _isValid = value.every(val => this.onlyTime(val).isSameOrBefore(md)); isValid = isValid ? _isValid : false; return _isValid; } }); } return (inputVal) => { isValid = true; value = this.convertToMomentArray(inputVal, format, true).filter(Boolean); if (!value.every(val => val.isValid())) { return { format: { given: inputVal } }; } const errors = validators.reduce((map, err) => { if (!err.isValid()) { map[err.key] = { given: value }; } return map; }, {}); return !isValid ? errors : null; }; } datesStringToStringArray(value) { return (value || '').split('|').map(m => m.trim()).filter(Boolean); } getValidMomentArray(value, format) { return this.datesStringToStringArray(value) .filter(d => this.isDateValid(d, format)) .map(d => moment(d, format)); } shouldShowCurrent(showGoToCurrent, mode, min, max) { return showGoToCurrent && mode !== 'time' && this.isDateInRange(moment(), min, max); } isDateInRange(date, from, to) { return date.isBetween(from, to, 'day', '[]'); } convertPropsToMoment(obj, format, props) { props.forEach((prop) => { if (obj.hasOwnProperty(prop)) { obj[prop] = this.convertToMoment(obj[prop], format); } }); } shouldResetCurrentView(prevConf, currentConf) { if (prevConf && currentConf) { if (!prevConf.min && currentConf.min) { return true; } else if (prevConf.min && currentConf.min && !prevConf.min.isSame(currentConf.min, 'd')) { return true; } else if (!prevConf.max && currentConf.max) { return true; } else if (prevConf.max && currentConf.max && !prevConf.max.isSame(currentConf.max, 'd')) { return true; } return false; } return false; } getNativeElement(elem) { if (!elem) { return null; } else if (typeof elem === 'string') { return document.querySelector(elem); } else { return elem; } } }; UtilsService = __decorate([ Injectable() ], UtilsService); const moment$1 = momentNs; let DayCalendarService = class DayCalendarService { constructor(utilsService) { this.utilsService = utilsService; this.DAYS = ['su', 'mo', 'tu', 'we', 'th', 'fr', 'sa']; this.DEFAULT_CONFIG = { showNearMonthDays: true, showWeekNumbers: false, firstDayOfWeek: 'su', weekDayFormat: 'ddd', format: 'DD-MM-YYYY', allowMultiSelect: false, monthFormat: 'MMM, YYYY', enableMonthSelector: true, locale: moment$1.locale(), dayBtnFormat: 'DD', unSelectOnClick: true }; } removeNearMonthWeeks(currentMonth, monthArray) { if (monthArray[monthArray.length - 1].find((day) => day.date.isSame(currentMonth, 'month'))) { return monthArray; } else { return monthArray.slice(0, -1); } } getConfig(config) { const _config = Object.assign({}, this.DEFAULT_CONFIG, this.utilsService.clearUndefined(config)); this.utilsService.convertPropsToMoment(_config, _config.format, ['min', 'max']); moment$1.locale(_config.locale); return _config; } generateDaysMap(firstDayOfWeek) { const firstDayIndex = this.DAYS.indexOf(firstDayOfWeek); const daysArr = this.DAYS.slice(firstDayIndex, 7).concat(this.DAYS.slice(0, firstDayIndex)); return daysArr.reduce((map, day, index) => { map[day] = index; return map; }, {}); } generateMonthArray(config, month, selected) { let monthArray = []; const firstDayOfWeekIndex = this.DAYS.indexOf(config.firstDayOfWeek); const firstDayOfBoard = month.clone().startOf('month'); while (firstDayOfBoard.day() !== firstDayOfWeekIndex) { firstDayOfBoard.subtract(1, 'day'); } const current = firstDayOfBoard.clone(); const prevMonth = month.clone().subtract(1, 'month'); const nextMonth = month.clone().add(1, 'month'); const today = moment$1(); const daysOfCalendar = this.utilsService.createArray(42) .reduce((array) => { array.push({ date: current.clone(), selected: !!selected.find(selectedDay => current.isSame(selectedDay, 'day')), currentMonth: current.isSame(month, 'month'), prevMonth: current.isSame(prevMonth, 'month'), nextMonth: current.isSame(nextMonth, 'month'), currentDay: current.isSame(today, 'day'), disabled: this.isDateDisabled(current, config) }); current.add(1, 'day'); return array; }, []); daysOfCalendar.forEach((day, index) => { const weekIndex = Math.floor(index / 7); if (!monthArray[weekIndex]) { monthArray.push([]); } monthArray[weekIndex].push(day); }); if (!config.showNearMonthDays) { monthArray = this.removeNearMonthWeeks(month, monthArray); } return monthArray; } generateWeekdays(firstDayOfWeek) { const weekdayNames = { su: moment$1().day(0), mo: moment$1().day(1), tu: moment$1().day(2), we: moment$1().day(3), th: moment$1().day(4), fr: moment$1().day(5), sa: moment$1().day(6) }; const weekdays = []; const daysMap = this.generateDaysMap(firstDayOfWeek); for (const dayKey in daysMap) { if (daysMap.hasOwnProperty(dayKey)) { weekdays[daysMap[dayKey]] = weekdayNames[dayKey]; } } return weekdays; } isDateDisabled(date, config) { if (config.isDayDisabledCallback) { return config.isDayDisabledCallback(date); } if (config.min && date.isBefore(config.min, 'day')) { return true; } return !!(config.max && date.isAfter(config.max, 'day')); } // todo:: add unit tests getHeaderLabel(config, month) { if (config.monthFormatter) { return config.monthFormatter(month); } return month.format(config.monthFormat); } // todo:: add unit tests shouldShowLeft(min, currentMonthView) { return min ? min.isBefore(currentMonthView, 'month') : true; } // todo:: add unit tests shouldShowRight(max, currentMonthView) { return max ? max.isAfter(currentMonthView, 'month') : true; } generateDaysIndexMap(firstDayOfWeek) { const firstDayIndex = this.DAYS.indexOf(firstDayOfWeek); const daysArr = this.DAYS.slice(firstDayIndex, 7).concat(this.DAYS.slice(0, firstDayIndex)); return daysArr.reduce((map, day, index) => { map[index] = day; return map; }, {}); } getMonthCalendarConfig(componentConfig) { return this.utilsService.clearUndefined({ min: componentConfig.min, max: componentConfig.max, format: componentConfig.format, isNavHeaderBtnClickable: true, allowMultiSelect: false, yearFormat: componentConfig.yearFormat, yearFormatter: componentConfig.yearFormatter, monthBtnFormat: componentConfig.monthBtnFormat, monthBtnFormatter: componentConfig.monthBtnFormatter, monthBtnCssClassCallback: componentConfig.monthBtnCssClassCallback, multipleYearsNavigateBy: componentConfig.multipleYearsNavigateBy, showMultipleYearsNavigation: componentConfig.showMultipleYearsNavigation, showGoToCurrent: componentConfig.showGoToCurrent }); } getDayBtnText(config, day) { if (config.dayBtnFormatter) { return config.dayBtnFormatter(day); } return day.format(config.dayBtnFormat); } getDayBtnCssClass(config, day) { if (config.dayBtnCssClassCallback) { return config.dayBtnCssClassCallback(day); } return ''; } }; DayCalendarService = __decorate([ Injectable(), __metadata("design:paramtypes", [UtilsService]) ], DayCalendarService); var DayCalendarComponent_1; const moment$2 = momentNs; let DayCalendarComponent = DayCalendarComponent_1 = class DayCalendarComponent { constructor(dayCalendarService, utilsService, cd) { this.dayCalendarService = dayCalendarService; this.utilsService = utilsService; this.cd = cd; this.onSelect = new EventEmitter(); this.onMonthSelect = new EventEmitter(); this.onNavHeaderBtnClick = new EventEmitter(); this.onGoToCurrent = new EventEmitter(); this.onLeftNav = new EventEmitter(); this.onRightNav = new EventEmitter(); this.CalendarMode = ECalendarMode; this.isInited = false; this.currentCalendarMode = ECalendarMode.Day; this._shouldShowCurrent = true; this.api = { moveCalendarsBy: this.moveCalendarsBy.bind(this), moveCalendarTo: this.moveCalendarTo.bind(this), toggleCalendarMode: this.toggleCalendarMode.bind(this) }; } set selected(selected) { this._selected = selected; this.onChangeCallback(this.processOnChangeCallback(selected)); } get selected() { return this._selected; } set currentDateView(current) { this._currentDateView = current.clone(); this.weeks = this.dayCalendarService .generateMonthArray(this.componentConfig, this._currentDateView, this.selected); this.navLabel = this.dayCalendarService.getHeaderLabel(this.componentConfig, this._currentDateView); this.showLeftNav = this.dayCalendarService.shouldShowLeft(this.componentConfig.min, this.currentDateView); this.showRightNav = this.dayCalendarService.shouldShowRight(this.componentConfig.max, this.currentDateView); } get currentDateView() { return this._currentDateView; } ngOnInit() { this.isInited = true; this.init(); this.initValidators(); } init() { this.componentConfig = this.dayCalendarService.getConfig(this.config); this.selected = this.selected || []; this.currentDateView = this.displayDate ? this.utilsService.convertToMoment(this.displayDate, this.componentConfig.format).clone() : this.utilsService .getDefaultDisplayDate(this.currentDateView, this.selected, this.componentConfig.allowMultiSelect, this.componentConfig.min); this.weekdays = this.dayCalendarService .generateWeekdays(this.componentConfig.firstDayOfWeek); this.inputValueType = this.utilsService.getInputType(this.inputValue, this.componentConfig.allowMultiSelect); this.monthCalendarConfig = this.dayCalendarService.getMonthCalendarConfig(this.componentConfig); this._shouldShowCurrent = this.shouldShowCurrent(); } ngOnChanges(changes) { if (this.isInited) { const { minDate, maxDate, config } = changes; this.handleConfigChange(config); this.init(); if (minDate || maxDate) { this.initValidators(); } } } writeValue(value) { this.inputValue = value; if (value) { this.selected = this.utilsService .convertToMomentArray(value, this.componentConfig.format, this.componentConfig.allowMultiSelect); this.inputValueType = this.utilsService .getInputType(this.inputValue, this.componentConfig.allowMultiSelect); } else { this.selected = []; } this.weeks = this.dayCalendarService .generateMonthArray(this.componentConfig, this.currentDateView, this.selected); this.cd.markForCheck(); } registerOnChange(fn) { this.onChangeCallback = fn; } onChangeCallback(_) { } ; registerOnTouched(fn) { } validate(formControl) { if (this.minDate || this.maxDate) { return this.validateFn(formControl.value); } else { return () => null; } } processOnChangeCallback(value) { return this.utilsService.convertFromMomentArray(this.componentConfig.format, value, this.componentConfig.returnedValueType || this.inputValueType); } initValidators() { this.validateFn = this.utilsService.createValidator({ minDate: this.minDate, maxDate: this.maxDate }, this.componentConfig.format, 'day'); this.onChangeCallback(this.processOnChangeCallback(this.selected)); } dayClicked(day) { if (day.selected && !this.componentConfig.unSelectOnClick) { return; } this.selected = this.utilsService .updateSelected(this.componentConfig.allowMultiSelect, this.selected, day); this.weeks = this.dayCalendarService .generateMonthArray(this.componentConfig, this.currentDateView, this.selected); this.onSelect.emit(day); } getDayBtnText(day) { return this.dayCalendarService.getDayBtnText(this.componentConfig, day.date); } getDayBtnCssClass(day) { const cssClasses = { 'dp-selected': day.selected, 'dp-current-month': day.currentMonth, 'dp-prev-month': day.prevMonth, 'dp-next-month': day.nextMonth, 'dp-current-day': day.currentDay }; const customCssClass = this.dayCalendarService.getDayBtnCssClass(this.componentConfig, day.date); if (customCssClass) { cssClasses[customCssClass] = true; } return cssClasses; } onLeftNavClick() { const from = this.currentDateView.clone(); this.moveCalendarsBy(this.currentDateView, -1, 'month'); const to = this.currentDateView.clone(); this.onLeftNav.emit({ from, to }); } onRightNavClick() { const from = this.currentDateView.clone(); this.moveCalendarsBy(this.currentDateView, 1, 'month'); const to = this.currentDateView.clone(); this.onRightNav.emit({ from, to }); } onMonthCalendarLeftClick(change) { this.onLeftNav.emit(change); } onMonthCalendarRightClick(change) { this.onRightNav.emit(change); } onMonthCalendarSecondaryLeftClick(change) { this.onRightNav.emit(change); } onMonthCalendarSecondaryRightClick(change) { this.onLeftNav.emit(change); } getWeekdayName(weekday) { if (this.componentConfig.weekDayFormatter) { return this.componentConfig.weekDayFormatter(weekday.day()); } return weekday.format(this.componentConfig.weekDayFormat); } toggleCalendarMode(mode) { if (this.currentCalendarMode !== mode) { this.currentCalendarMode = mode; this.onNavHeaderBtnClick.emit(mode); } this.cd.markForCheck(); } monthSelected(month) { this.currentDateView = month.date.clone(); this.currentCalendarMode = ECalendarMode.Day; this.onMonthSelect.emit(month); } moveCalendarsBy(current, amount, granularity = 'month') { this.currentDateView = current.clone().add(amount, granularity); this.cd.markForCheck(); } moveCalendarTo(to) { if (to) { this.currentDateView = this.utilsService.convertToMoment(to, this.componentConfig.format); } this.cd.markForCheck(); } shouldShowCurrent() { return this.utilsService.shouldShowCurrent(this.componentConfig.showGoToCurrent, 'day', this.componentConfig.min, this.componentConfig.max); } goToCurrent() { this.currentDateView = moment$2(); this.onGoToCurrent.emit(); } handleConfigChange(config) { if (config) { const prevConf = this.dayCalendarService.getConfig(config.previousValue); const currentConf = this.dayCalendarService.getConfig(config.currentValue); if (this.utilsService.shouldResetCurrentView(prevConf, currentConf)) { this._currentDateView = null; } } } }; __decorate([ Input(), __metadata("design:type", Object) ], DayCalendarComponent.prototype, "config", void 0); __decorate([ Input(), __metadata("design:type", Object) ], DayCalendarComponent.prototype, "displayDate", void 0); __decorate([ Input(), __metadata("design:type", Object) ], DayCalendarComponent.prototype, "minDate", void 0); __decorate([ Input(), __metadata("design:type", Object) ], DayCalendarComponent.prototype, "maxDate", void 0); __decorate([ HostBinding('class'), Input(), __metadata("design:type", String) ], DayCalendarComponent.prototype, "theme", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DayCalendarComponent.prototype, "onSelect", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DayCalendarComponent.prototype, "onMonthSelect", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DayCalendarComponent.prototype, "onNavHeaderBtnClick", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DayCalendarComponent.prototype, "onGoToCurrent", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DayCalendarComponent.prototype, "onLeftNav", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], DayCalendarComponent.prototype, "onRightNav", void 0); DayCalendarComponent = DayCalendarComponent_1 = __decorate([ Component({ selector: 'dp-day-calendar', template: "<div class=\"dp-day-calendar-container\" *ngIf=\"currentCalendarMode === CalendarMode.Day\">\n <dp-calendar-nav\n [label]=\"navLabel\"\n [showLeftNav]=\"showLeftNav\"\n [showRightNav]=\"showRightNav\"\n [isLabelClickable]=\"componentConfig.enableMonthSelector\"\n [showGoToCurrent]=\"_shouldShowCurrent\"\n [theme]=\"theme\"\n (onLeftNav)=\"onLeftNavClick()\"\n (onRightNav)=\"onRightNavClick()\"\n (onLabelClick)=\"toggleCalendarMode(CalendarMode.Month)\"\n (onGoToCurrent)=\"goToCurrent()\">\n </dp-calendar-nav>\n\n <div class=\"dp-calendar-wrapper\"\n [ngClass]=\"{'dp-hide-near-month': !componentConfig.showNearMonthDays}\">\n <div class=\"dp-weekdays\">\n <span class=\"dp-calendar-weekday\"\n *ngFor=\"let weekday of weekdays\"\n [innerText]=\"getWeekdayName(weekday)\">\n </span>\n </div>\n <div class=\"dp-calendar-week\" *ngFor=\"let week of weeks\">\n <span class=\"dp-week-number\"\n *ngIf=\"componentConfig.showWeekNumbers\"\n [innerText]=\"week[0].date.isoWeek()\">\n </span>\n <button type=\"button\"\n class=\"dp-calendar-day\"\n *ngFor=\"let day of week\"\n [attr.data-date]=\"day.date.format(componentConfig.format)\"\n (click)=\"dayClicked(day)\"\n [disabled]=\"day.disabled\"\n [ngClass]=\"getDayBtnCssClass(day)\"\n [innerText]=\"getDayBtnText(day)\">\n </button>\n </div>\n </div>\n</div>\n\n<dp-month-calendar\n *ngIf=\"currentCalendarMode === CalendarMode.Month\"\n [config]=\"monthCalendarConfig\"\n [displayDate]=\"_currentDateView\"\n [theme]=\"theme\"\n (onSelect)=\"monthSelected($event)\"\n (onNavHeaderBtnClick)=\"toggleCalendarMode(CalendarMode.Day)\"\n (onLeftNav)=\"onMonthCalendarLeftClick($event)\"\n (onRightNav)=\"onMonthCalendarRightClick($event)\"\n (onLeftSecondaryNav)=\"onMonthCalendarSecondaryLeftClick($event)\"\n (onRightSecondaryNav)=\"onMonthCalendarSecondaryRightClick($event)\">\n</dp-month-calendar>\n", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ DayCalendarService, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DayCalendarComponent_1), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => DayCalendarComponent_1), multi: true } ], styles: ["dp-day-calendar{display:inline-block}dp-day-calendar .dp-day-calendar-container{background:#fff}dp-day-calendar .dp-calendar-wrapper{box-sizing:border-box;border:1px solid #000}dp-day-calendar .dp-calendar-wrapper .dp-calendar-weekday:first-child{border-left:none}dp-day-calendar .dp-weekdays{font-size:15px;margin-bottom:5px}dp-day-calendar .dp-calendar-weekday{box-sizing:border-box;display:inline-block;width:30px;text-align:center;border-left:1px solid #000;border-bottom:1px solid #000}dp-day-calendar .dp-calendar-day{box-sizing:border-box;width:30px;height:30px;cursor:pointer}dp-day-calendar .dp-selected{background:#106cc8;color:#fff}dp-day-calendar .dp-next-month,dp-day-calendar .dp-prev-month{opacity:.5}dp-day-calendar .dp-hide-near-month .dp-next-month,dp-day-calendar .dp-hide-near-month .dp-prev-month{visibility:hidden}dp-day-calendar .dp-week-number{position:absolute;font-size:9px}dp-day-calendar.dp-material .dp-calendar-weekday{height:25px;width:30px;line-height:25px;color:#7a7a7a;border:none}dp-day-calendar.dp-material .dp-calendar-wrapper{border:1px solid #e0e0e0}dp-day-calendar.dp-material .dp-calendar-day,dp-day-calendar.dp-material .dp-calendar-month{box-sizing:border-box;background:#fff;border-radius:50%;border:none;outline:0}dp-day-calendar.dp-material .dp-calendar-day:hover,dp-day-calendar.dp-material .dp-calendar-month:hover{background:#e0e0e0}dp-day-calendar.dp-material .dp-selected{background:#106cc8;color:#fff}dp-day-calendar.dp-material .dp-selected:hover{background:#106cc8}dp-day-calendar.dp-material .dp-current-day{border:1px solid #106cc8}"] }), __metadata("design:paramtypes", [DayCalendarService, UtilsService, ChangeDetectorRef]) ], DayCalendarComponent); const moment$3 = momentNs; const FIRST_PM_HOUR = 12; let TimeSelectService = class TimeSelectService { constructor(utilsService) { this.utilsService = utilsService; this.DEFAULT_CONFIG = { hours12Format: 'hh', hours24Format: 'HH', meridiemFormat: 'A', minutesFormat: 'mm', minutesInterval: 1, secondsFormat: 'ss', secondsInterval: 1, showSeconds: false, showTwentyFourHours: false, timeSeparator: ':', locale: moment$3.locale() }; } getConfig(config) { const timeConfigs = { maxTime: this.utilsService.onlyTime(config && config.maxTime), minTime: this.utilsService.onlyTime(config && config.minTime) }; const _config = Object.assign({}, this.DEFAULT_CONFIG, this.utilsService.clearUndefined(config), timeConfigs); moment$3.locale(_config.locale); return _config; } getTimeFormat(config) { return (config.showTwentyFourHours ? config.hours24Format : config.hours12Format) + config.timeSeparator + config.minutesFormat + (config.showSeconds ? (config.timeSeparator + config.secondsFormat) : '') + (config.showTwentyFourHours ? '' : ' ' + config.meridiemFormat); } getHours(config, t) { const time = t || moment$3(); return time && time.format(config.showTwentyFourHours ? config.hours24Format : config.hours12Format); } getMinutes(config, t) { const time = t || moment$3(); return time && time.format(config.minutesFormat); } getSeconds(config, t) { const time = t || moment$3(); return time && time.format(config.secondsFormat); } getMeridiem(config, time) { return time && time.format(config.meridiemFormat); } decrease(config, time, unit) { let amount = 1; switch (unit) { case 'minute': amount = config.minutesInterval; break; case 'second': amount = config.secondsInterval; break; } return time.clone().subtract(amount, unit); } increase(config, time, unit) { let amount = 1; switch (unit) { case 'minute': amount = config.minutesInterval; break; case 'second': amount = config.secondsInterval; break; } return time.clone().add(amount, unit); } toggleMeridiem(time) { if (time.hours() < FIRST_PM_HOUR) { return time.clone().add(12, 'hour'); } else { return time.clone().subtract(12, 'hour'); } } shouldShowDecrease(config, time, unit) { if (!config.min && !config.minTime) { return true; } const newTime = this.decrease(config, time, unit); return (!config.min || config.min.isSameOrBefore(newTime)) && (!config.minTime || config.minTime.isSameOrBefore(this.utilsService.onlyTime(newTime))); } shouldShowIncrease(config, time, unit) { if (!config.max && !config.maxTime) { return true; } const newTime = this.increase(config, time, unit); return (!config.max || config.max.isSameOrAfter(newTime)) && (!config.maxTime || config.maxTime.isSameOrAfter(this.utilsService.onlyTime(newTime))); } shouldShowToggleMeridiem(config, time) { if (!config.min && !config.max && !config.minTime && !config.maxTime) { return true; } const newTime = this.toggleMeridiem(time); return (!config.max || config.max.isSameOrAfter(newTime)) && (!config.min || config.min.isSameOrBefore(newTime)) && (!config.maxTime || config.maxTime.isSameOrAfter(this.utilsService.onlyTime(newTime))) && (!config.minTime || config.minTime.isSameOrBefore(this.utilsService.onlyTime(newTime))); } }; TimeSelectService = __decorate([ Injectable(), __metadata("design:paramtypes", [UtilsService]) ], TimeSelectService); const moment$4 = momentNs; const DAY_FORMAT = 'YYYYMMDD'; const TIME_FORMAT = 'HH:mm:ss'; const COMBINED_FORMAT = DAY_FORMAT + TIME_FORMAT; let DayTimeCalendarService = class DayTimeCalendarService { constructor(utilsService, dayCalendarService, timeSelectService) { this.utilsService = utilsService; this.dayCalendarService = dayCalendarService; this.timeSelectService = timeSelectService; this.DEFAULT_CONFIG = { locale: moment$4.locale() }; } getConfig(config) { const _config = Object.assign({}, this.DEFAULT_CONFIG, this.timeSelectService.getConfig(config), this.dayCalendarService.getConfig(config)); moment$4.locale(config.locale); return _config; } updateDay(current, day, config) { const time = current ? current : moment$4(); let updated = moment$4(day.format(DAY_FORMAT) + time.format(TIME_FORMAT), COMBINED_FORMAT); if (config.min) { const min = config.min; updated = min.isAfter(updated) ? min : updated; } if (config.max) { const max = config.max; updated = max.isBefore(updated) ? max : updated; } return updated; } updateTime(current, time) { const day = current ? current : moment$4(); return moment$4(day.format(DAY_FORMAT) + time.format(TIME_FORMAT), COMBINED_FORMAT); } }; DayTimeCalendarService = __decorate([ Injectable(), __metadata("design:paramtypes", [UtilsService, DayCalendarService, TimeSelectService]) ], DayTimeCalendarService); var TimeSelectComponent_1; const moment$5 = momentNs; let TimeSelectComponent = TimeSelectComponent_1 = class TimeSelectComponent { constructor(timeSelectService, utilsService, cd) { this.timeSelectService = timeSelectService; this.utilsService = utilsService; this.cd = cd; this.onChange = new EventEmitter(); this.isInited = false; this.api = { triggerChange: this.emitChange.bind(this) }; } set selected(selected) { this._selected = selected; this.calculateTimeParts(this.selected); this.showDecHour = this.timeSelectService.shouldShowDecrease(this.componentConfig, this._selected, 'hour'); this.showDecMinute = this.timeSelectService.shouldShowDecrease(this.componentConfig, this._selected, 'minute'); this.showDecSecond = this.timeSelectService.shouldShowDecrease(this.componentConfig, this._selected, 'second'); this.showIncHour = this.timeSelectService.shouldShowIncrease(this.componentConfig, this._selected, 'hour'); this.showIncMinute = this.timeSelectService.shouldShowIncrease(this.componentConfig, this._selected, 'minute'); this.showIncSecond = this.timeSelectService.shouldShowIncrease(this.componentConfig, this._selected, 'second'); this.showToggleMeridiem = this.timeSelectService.shouldShowToggleMeridiem(this.componentConfig, this._selected); this.onChangeCallback(this.processOnChangeCallback(selected)); } get selected() { return this._selected; } ngOnInit() { this.isInited = true; this.init(); this.initValidators(); } init() { this.componentConfig = this.timeSelectService.getConfig(this.config); this.selected = this.selected || moment$5(); this.inputValueType = this.utilsService.getInputType(this.inputValue, false); } ngOnChanges(changes) { if (this.isInited) { const { minDate, maxDate, minTime, maxTime } = changes; this.init(); if (minDate || maxDate || minTime || maxTime) { this.initValidators(); } } } writeValue(value) { this.inputValue = value; if (value) { const momentValue = this.utilsService .convertToMomentArray(value, this.timeSelectService.getTimeFormat(this.componentConfig), false)[0]; if (momentValue.isValid()) { this.selected = momentValue; this.inputValueType = this.utilsService .getInputType(this.inputValue, false); } } this.cd.markForCheck(); } registerOnChange(fn) { this.onChangeCallback = fn; } onChangeCallback(_) { } ; registerOnTouched(fn) { } validate(formControl) { if (this.minDate || this.maxDate || this.minTime || this.maxTime) { return this.validateFn(formControl.value); } else { return () => null; } } processOnChangeCallback(value) { return this.utilsService.convertFromMomentArray(this.timeSelectService.getTimeFormat(this.componentConfig), [value], this.componentConfig.returnedValueType || this.inputValueType); } initValidators() { this.validateFn = this.utilsService.createValidator({ minDate: this.minDate, maxDate: this.maxDate, minTime: this.minTime, maxTime: this.maxTime }, undefined, 'day'); this.onChangeCallback(this.processOnChangeCallback(this.selected)); } decrease(unit) { this.selected = this.timeSelectService.decrease(this.componentConfig, this.selected, unit); this.emitChange(); } increase(unit) { this.selected = this.timeSelectService.increase(this.componentConfig, this.selected, unit); this.emitChange(); } toggleMeridiem() { this.selected = this.timeSelectService.toggleMeridiem(this.selected); this.emitChange(); } emitChange() { this.onChange.emit({ date: this.selected, selected: false }); this.cd.markForCheck(); } calculateTimeParts(time) { this.hours = this.timeSelectService.getHours(this.componentConfig, time); this.minutes = this.timeSelectService.getMinutes(this.componentConfig, time); this.seconds = this.timeSelectService.getSeconds(this.componentConfig, time); this.meridiem = this.timeSelectService.getMeridiem(this.componentConfig, time); } }; __decorate([ Input(), __metadata("design:type", Object) ], TimeSelectComponent.prototype, "config", void 0); __decorate([ Input(), __metadata("design:type", Object) ], TimeSelectComponent.prototype, "displayDate", void 0); __decorate([ Input(), __metadata("design:type", Object) ], TimeSelectComponent.prototype, "minDate", void 0); __decorate([ Input(), __metadata("design:type", Object) ], TimeSelectComponent.prototype, "maxDate", void 0); __decorate([ Input(), __metadata("design:type", Object) ], TimeSelectComponent.prototype, "minTime", void 0); __decorate([ Input(), __metadata("design:type", Object) ], TimeSelectComponent.prototype, "maxTime", void 0); __decorate([ HostBinding('class'), Input(), __metadata("design:type", String) ], TimeSelectComponent.prototype, "theme", void 0); __decorate([ Output(), __metadata("design:type", EventEmitter) ], TimeSelectComponent.prototype, "onChange", void 0); TimeSelectComponent = TimeSelectComponent_1 = __decorate([ Component({ selector: 'dp-time-select', template: "<ul class=\"dp-time-select-controls\">\n <li class=\"dp-time-select-control dp-time-select-control-hours\">\n <button type=\"button\"\n class=\"dp-time-select-control-up\"\n [disabled]=\"!showIncHour\"\n (click)=\"increase('hour')\">\n </button>\n <span class=\"dp-time-select-display-hours\"\n [innerText]=\"hours\">\n </span>\n <button type=\"button\"\n class=\"dp-time-select-control-down\"\n [disabled]=\"!showDecHour\"\n (click)=\"decrease('hour')\"></button>\n </li>\n <li class=\"dp-time-select-control dp-time-select-separator\"\n [innerText]=\"componentConfig.timeSeparator\">\n </li>\n <li class=\"dp-time-select-control dp-time-select-control-minutes\">\n <button type=\"button\"\n class=\"dp-time-select-control-up\"\n [disabled]=\"!showIncMinute\"\n (click)=\"increase('minute')\"></button>\n <span class=\"dp-time-select-display-minutes\"\n [innerText]=\"minutes\">\n </span>\n <button type=\"button\"\n [disabled]=\"!showDecMinute\" class=\"dp-time-select-control-down\"\n (click)=\"decrease('minute')\"></button>\n </li>\n <ng-container *ngIf=\"componentConfig.showSeconds\">\n <li class=\"dp-time-select-control dp-time-select-separator\"\n [innerText]=\"componentConfig.timeSeparator\">\n </li>\n <li class=\"dp-time-select-control dp-time-select-control-seconds\">\n <button type=\"button\"\n class=\"dp-time-select-control-up\"\n [disabled]=\"!showIncSecond\"\n (click)=\"increase('second')\"></button>\n <span class=\"dp-time-select-display-seconds\"\n [innerText]=\"seconds\">\n </span>\n <button type=\"button\"\n class=\"dp-time-select-control-down\"\n [disabled]=\"!showDecSecond\"\n (click)=\"decrease('second')\"></button>\n </li>\n </ng-container>\n <li class=\"dp-time-select-control dp-time-select-control-meridiem\" *ngIf=\"!componentConfig.showTwentyFourHours\">\n <button type=\"button\"\n class=\"dp-time-select-control-up\"\n [disabled]=\"!showToggleMeridiem\"\n (click)=\"toggleMeridiem()\"></button>\n <span class=\"dp-time-select-display-meridiem\"\n [innerText]=\"meridiem\">\n </span>\n <button type=\"button\"\n class=\"dp-time-select-control-down\"\n [disabled]=\"!showToggleMeridiem\"\n (click)=\"toggleMeridiem()\"></button>\n </li>\n</ul>\n", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ TimeSelectService, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimeSelectComponent_1), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => TimeSelectComponent_1), multi: true } ], styles: ["dp-time-select{display:inline-block}dp-time-select .dp-time-select-controls{margin:0;padding:0;text-align:center;line-height:normal;background:#fff}dp-time-select .dp-time-select-control{display:inline-block;width:35px;margin:0 auto;vertical-align:middle;font-size:inherit;letter-spacing:1px}dp-time-select .dp-time-select-control-down,dp-time-select .dp-time-select-control-up{position:relative;display:block;width:24px;height:24px;margin:3px auto;cursor:pointer}dp-time-select .dp-time-select-control-down::before,dp-time-select .dp-time-select-control-up::before{position:relative;content:'';display:inline-block;height:8px;width:8px;vertical-align:baseline;border-style:solid;border-width:2px 2px 0 0}dp-time-select .dp-time-select-control-up::