angular-weblineindia-date-picker
Version:
Date Picker component built in AngularJS to select date and time. Supports Angular 9 version.
1,287 lines (1,277 loc) • 116 kB
JavaScript
import { __decorate, __param } from 'tslib';
import { ɵɵdefineInjectable, Injectable, EventEmitter, ElementRef, Renderer2, ChangeDetectorRef, Input, HostBinding, Output, ViewChild, HostListener, Component, ViewEncapsulation, ChangeDetectionStrategy, forwardRef, ViewContainerRef, ComponentFactoryResolver, Optional, Directive, 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.ɵprov = ɵɵdefineInjectable({ factory: function DomHelper_Factory() { return new DomHelper(); }, token: DomHelper, providedIn: "root" });
DomHelper = DomHelper_1 = __decorate([
Injectable({
providedIn: 'root'
})
], 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, config) {
let retVal;
switch (this.getInputType(value, config.allowMultiSelect)) {
case (ECalendarValue.String):
retVal = value ? [moment(value, config.format, true)] : [];
break;
case (ECalendarValue.StringArr):
retVal = value.map(v => v ? moment(v, config.format, true) : null).filter(Boolean);
break;
case (ECalendarValue.Moment):
retVal = value ? [value.clone()] : [];
break;
case (ECalendarValue.MomentArr):
retVal = (value || []).map(v => v.clone());
break;
default:
retVal = [];
}
return retVal;
}
// 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,
allowMultiSelect: 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.ɵprov = ɵɵdefineInjectable({ factory: function UtilsService_Factory() { return new UtilsService(); }, token: UtilsService, providedIn: "root" });
UtilsService = __decorate([
Injectable({
providedIn: 'root'
})
], UtilsService);
const moment$1 = momentNs;
let DayCalendarService = class DayCalendarService {
constructor(utilsService) {
this.utilsService = utilsService;
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
};
this.DAYS = ['su', 'mo', 'tu', 'we', 'th', 'fr', 'sa'];
}
getConfig(config) {
const _config = Object.assign(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,
locale: componentConfig.locale,
yearFormat: componentConfig.yearFormat,
yearFormatter: componentConfig.yearFormatter,
monthBtnFormat: componentConfig.monthBtnFormat,
monthBtnFormatter: componentConfig.monthBtnFormatter,
monthBtnCssClassCallback: componentConfig.monthBtnCssClassCallback,
multipleYearsNavigateBy: componentConfig.multipleYearsNavigateBy,
showMultipleYearsNavigation: componentConfig.showMultipleYearsNavigation,
showGoToCurrent: componentConfig.showGoToCurrent,
numOfMonthRows: componentConfig.numOfMonthRows
});
}
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 '';
}
removeNearMonthWeeks(currentMonth, monthArray) {
if (monthArray[monthArray.length - 1].find((day) => day.date.isSame(currentMonth, 'month'))) {
return monthArray;
}
else {
return monthArray.slice(0, -1);
}
}
};
DayCalendarService.ctorParameters = () => [
{ type: UtilsService }
];
DayCalendarService = __decorate([
Injectable()
], DayCalendarService);
const moment$2 = 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$2.locale()
};
}
getConfig(config) {
const timeConfigs = {
maxTime: this.utilsService.onlyTime(config && config.maxTime),
minTime: this.utilsService.onlyTime(config && config.minTime)
};
const _config = Object.assign(Object.assign(Object.assign({}, this.DEFAULT_CONFIG), this.utilsService.clearUndefined(config)), timeConfigs);
moment$2.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$2();
return time && time.format(config.showTwentyFourHours ? config.hours24Format : config.hours12Format);
}
getMinutes(config, t) {
const time = t || moment$2();
return time && time.format(config.minutesFormat);
}
getSeconds(config, t) {
const time = t || moment$2();
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.ctorParameters = () => [
{ type: UtilsService }
];
TimeSelectService = __decorate([
Injectable()
], TimeSelectService);
const moment$3 = 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$3.locale()
};
}
getConfig(config) {
const _config = Object.assign(Object.assign(Object.assign({}, this.DEFAULT_CONFIG), this.timeSelectService.getConfig(config)), this.dayCalendarService.getConfig(config));
moment$3.locale(config.locale);
return _config;
}
updateDay(current, day, config) {
const time = current ? current : moment$3();
let updated = moment$3(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$3();
return moment$3(day.format(DAY_FORMAT) + time.format(TIME_FORMAT), COMBINED_FORMAT);
}
};
DayTimeCalendarService.ctorParameters = () => [
{ type: UtilsService },
{ type: DayCalendarService },
{ type: TimeSelectService }
];
DayTimeCalendarService = __decorate([
Injectable()
], DayTimeCalendarService);
const moment$4 = momentNs;
let DatePickerService = class DatePickerService {
constructor(utilsService, timeSelectService, daytimeCalendarService) {
this.utilsService = utilsService;
this.timeSelectService = timeSelectService;
this.daytimeCalendarService = daytimeCalendarService;
this.onPickerClosed = new EventEmitter();
this.defaultConfig = {
closeOnSelect: true,
closeOnSelectDelay: 100,
closeOnEnter: true,
format: 'DD-MM-YYYY',
openOnFocus: true,
openOnClick: true,
onOpenDelay: 0,
disableKeypress: false,
showNearMonthDays: true,
showWeekNumbers: false,
enableMonthSelector: true,
showGoToCurrent: true,
locale: moment$4.locale(),
hideOnOutsideClick: true
};
}
// todo:: add unit tests
getConfig(config, mode = 'daytime') {
const _config = Object.assign(Object.assign(Object.assign({}, this.defaultConfig), { format: this.getDefaultFormatByMode(mode) }), this.utilsService.clearUndefined(config));
this.utilsService.convertPropsToMoment(_config, _config.format, ['min', 'max']);
if (config && config.allowMultiSelect && config.closeOnSelect === undefined) {
_config.closeOnSelect = false;
}
moment$4.locale(_config.locale);
return _config;
}
getDayConfigService(pickerConfig) {
return {
min: pickerConfig.min,
max: pickerConfig.max,
isDayDisabledCallback: pickerConfig.isDayDisabledCallback,
weekDayFormat: pickerConfig.weekDayFormat,
weekDayFormatter: pickerConfig.weekDayFormatter,
showNearMonthDays: pickerConfig.showNearMonthDays,
showWeekNumbers: pickerConfig.showWeekNumbers,
firstDayOfWeek: pickerConfig.firstDayOfWeek,
format: pickerConfig.format,
allowMultiSelect: pickerConfig.allowMultiSelect,
monthFormat: pickerConfig.monthFormat,
monthFormatter: pickerConfig.monthFormatter,
enableMonthSelector: pickerConfig.enableMonthSelector,
yearFormat: pickerConfig.yearFormat,
yearFormatter: pickerConfig.yearFormatter,
dayBtnFormat: pickerConfig.dayBtnFormat,
dayBtnFormatter: pickerConfig.dayBtnFormatter,
dayBtnCssClassCallback: pickerConfig.dayBtnCssClassCallback,
monthBtnFormat: pickerConfig.monthBtnFormat,
monthBtnFormatter: pickerConfig.monthBtnFormatter,
monthBtnCssClassCallback: pickerConfig.monthBtnCssClassCallback,
multipleYearsNavigateBy: pickerConfig.multipleYearsNavigateBy,
showMultipleYearsNavigation: pickerConfig.showMultipleYearsNavigation,
locale: pickerConfig.locale,
returnedValueType: pickerConfig.returnedValueType,
showGoToCurrent: pickerConfig.showGoToCurrent,
unSelectOnClick: pickerConfig.unSelectOnClick,
numOfMonthRows: pickerConfig.numOfMonthRows
};
}
getDayTimeConfigService(pickerConfig) {
return this.daytimeCalendarService.getConfig(pickerConfig);
}
getTimeConfigService(pickerConfig) {
return this.timeSelectService.getConfig(pickerConfig);
}
pickerClosed() {
this.onPickerClosed.emit();
}
// todo:: add unit tests
isValidInputDateValue(value, config) {
value = value ? value : '';
const datesStrArr = this.utilsService.datesStringToStringArray(value);
return datesStrArr.every(date => this.utilsService.isDateValid(date, config.format));
}
// todo:: add unit tests
convertInputValueToMomentArray(value, config) {
value = value ? value : '';
const datesStrArr = this.utilsService.datesStringToStringArray(value);
return this.utilsService.convertToMomentArray(datesStrArr, config);
}
getDefaultFormatByMode(mode) {
switch (mode) {
case 'day':
return 'DD-MM-YYYY';
case 'daytime':
return 'DD-MM-YYYY HH:mm:ss';
case 'time':
return 'HH:mm:ss';
case 'month':
return 'MMM, YYYY';
}
}
};
DatePickerService.ctorParameters = () => [
{ type: UtilsService },
{ type: TimeSelectService },
{ type: DayTimeCalendarService }
];
DatePickerService = __decorate([
Injectable()
], DatePickerService);
var DatePickerComponent_1;
let DatePickerComponent = DatePickerComponent_1 = class DatePickerComponent {
constructor(dayPickerService, domHelper, elemRef, renderer, utilsService, cd) {
this.dayPickerService = dayPickerService;
this.domHelper = domHelper;
this.elemRef = elemRef;
this.renderer = renderer;
this.utilsService = utilsService;
this.cd = cd;
this.isInitialized = false;
this.mode = 'day';
this.placeholder = '';
this.disabled = false;
this.open = new EventEmitter();
this.close = new EventEmitter();
this.onChange = new EventEmitter();
this.onGoToCurrent = new EventEmitter();
this.onLeftNav = new EventEmitter();
this.onRightNav = new EventEmitter();
this.onSelect = new EventEmitter();
this.hideStateHelper = false;
this.isFocusedTrigger = false;
this.handleInnerElementClickUnlisteners = [];
this.globalListenersUnlisteners = [];
this.api = {
open: this.showCalendars.bind(this),
close: this.hideCalendar.bind(this),
moveCalendarTo: this.moveCalendarTo.bind(this)
};
this.selectEvent = SelectEvent;
this._areCalendarsShown = false;
this._selected = [];
}
get openOnFocus() {
return this.componentConfig.openOnFocus;
}
get openOnClick() {
return this.componentConfig.openOnClick;
}
get areCalendarsShown() {
return this._areCalendarsShown;
}
set areCalendarsShown(value) {
if (value) {
this.startGlobalListeners();
this.domHelper.appendElementToPosition({
container: this.appendToElement,
element: this.calendarWrapper,
anchor: this.inputElementContainer,
dimElem: this.popupElem,
drops: this.componentConfig.drops,
opens: this.componentConfig.opens
});
}
else {
this.stopGlobalListeners();
this.dayPickerService.pickerClosed();
}
this._areCalendarsShown = value;
}
get selected() {
return this._selected;
}
set selected(selected) {
this._selected = selected;
this.inputElementValue = this.utilsService
.convertFromMomentArray(this.componentConfig.format, selected, ECalendarValue.StringArr)
.join(' | ');
const val = this.processOnChangeCallback(selected);
this.onChangeCallback(val, false);
this.onChange.emit(val);
}
get currentDateView() {
return this._currentDateView;
}
set currentDateView(date) {
this._currentDateView = date;
if (this.dayCalendarRef) {
this.dayCalendarRef.moveCalendarTo(date);
}
if (this.monthCalendarRef) {
this.monthCalendarRef.moveCalendarTo(date);
}
if (this.dayTimeCalendarRef) {
this.dayTimeCalendarRef.moveCalendarTo(date);
}
}
onClick() {
if (!this.openOnClick) {
return;
}
if (!this.isFocusedTrigger && !this.disabled) {
this.hideStateHelper = true;
if (!this.areCalendarsShown) {
this.showCalendars();
}
}
}
onBodyClick() {
if (this.componentConfig.hideOnOutsideClick) {
if (!this.hideStateHelper && this.areCalendarsShown) {
this.hideCalendar();
}
this.hideStateHelper = false;
}
}
onScroll() {
if (this.areCalendarsShown) {
this.domHelper.setElementPosition({
container: this.appendToElement,
element: this.calendarWrapper,
anchor: this.inputElementContainer,
dimElem: this.popupElem,
drops: this.componentConfig.drops,
opens: this.componentConfig.opens
});
}
}
writeValue(value) {
this.inputValue = value;
if (value || value === '') {
this.selected = this.utilsService
.convertToMomentArray(value, this.componentConfig);
this.init();
}
else {
this.selected = [];
}
this.cd.markForCheck();
}
registerOnChange(fn) {
this.onChangeCallback = fn;
}
onChangeCallback(_, changedByInput) {
}
registerOnTouched(fn) {
this.onTouchedCallback = fn;
}
onTouchedCallback() {
}
validate(formControl) {
return this.validateFn(formControl.value);
}
processOnChangeCallback(selected) {
if (typeof selected === 'string') {
return selected;
}
else {
return this.utilsService.convertFromMomentArray(this.componentConfig.format, selected, this.componentConfig.returnedValueType || this.utilsService.getInputType(this.inputValue, this.componentConfig.allowMultiSelect));
}
}
initValidators() {
this.validateFn = this.utilsService.createValidator({
minDate: this.minDate,
maxDate: this.maxDate,
minTime: this.minTime,
maxTime: this.maxTime
}, this.componentConfig.format, this.mode);
this.onChangeCallback(this.processOnChangeCallback(this.selected), false);
}
ngOnInit() {
this.isInitialized = true;
this.init();
}
ngOnChanges(changes) {
if (this.isInitialized) {
this.init();
}
}
ngAfterViewInit() {
this.setElementPositionInDom();
}
setDisabledState(isDisabled) {
this.disabled = isDisabled;
this.cd.markForCheck();
}
setElementPositionInDom() {
this.calendarWrapper = this.calendarContainer.nativeElement;
this.setInputElementContainer();
this.popupElem = this.elemRef.nativeElement.querySelector('.dp-popup');
this.handleInnerElementClick(this.popupElem);
const { appendTo } = this.componentConfig;
if (appendTo) {
if (typeof appendTo === 'string') {
this.appendToElement = document.querySelector(appendTo);
}
else {
this.appendToElement = appendTo;
}
}
else {
this.appendToElement = this.elemRef.nativeElement;
}
this.appendToElement.appendChild(this.calendarWrapper);
}
setInputElementContainer() {
this.inputElementContainer = this.utilsService.getNativeElement(this.componentConfig.inputElementContainer)
|| this.elemRef.nativeElement.querySelector('.dp-input-container')
|| document.body;
}
handleInnerElementClick(element) {
this.handleInnerElementClickUnlisteners.push(this.renderer.listen(element, 'click', () => {
this.hideStateHelper = true;
}));
}
init() {
this.componentConfig = this.dayPickerService.getConfig(this.config, this.mode);
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.dayCalendarConfig = this.dayPickerService.getDayConfigService(this.componentConfig);
this.dayTimeCalendarConfig = this.dayPickerService.getDayTimeConfigService(this.componentConfig);
this.timeSelectConfig = this.dayPickerService.getTimeConfigService(this.componentConfig);
this.initValidators();
}
inputFocused() {
if (!this.openOnFocus) {
return;
}
clearTimeout(this.onOpenDelayTimeoutHandler);
this.isFocusedTrigger = true;
this.onOpenDelayTimeoutHandler = setTimeout(() => {
if (!this.areCalendarsShown) {
this.showCalendars();
}
this.hideStateHelper = false;
this.isFocusedTrigger = false;
this.cd.markForCheck();
}, this.componentConfig.onOpenDelay);
}
inputBlurred() {
clearTimeout(this.onOpenDelayTimeoutHandler);
this.onTouchedCallback();
}
showCalendars() {
this.hideStateHelper = true;
this.areCalendarsShown = true;
if (this.timeSelectRef) {
this.timeSelectRef.api.triggerChange();
}
this.open.emit();
this.cd.markForCheck();
}
hideCalendar() {
this.areCalendarsShown = false;
if (this.dayCalendarRef) {
this.dayCalendarRef.api.toggleCalendarMode(ECalendarMode.Day);
}
this.close.emit();
this.cd.markForCheck();
}
onViewDateChange(value) {
const strVal = value ? this.utilsService.convertToString(value, this.componentConfig.format) : '';
if (this.dayPickerService.isValidInputDateValue(strVal, this.componentConfig)) {
this.selected = this.dayPickerService.convertInputValueToMomentArray(strVal, this.componentConfig);
this.currentDateView = this.selected.length
? this.utilsService.getDefaultDisplayDate(null, this.selected, this.componentConfig.allowMultiSelect, this.componentConfig.min)
: this.currentDateView;
this.onSelect.emit({
date: strVal,
type: SelectEvent.INPUT,
granularity: null
});
}
else {
this._selected = this.utilsService
.getValidMomentArray(strVal, this.componentConfig.format);
this.onChangeCallback(this.processOnChangeCallback(strVal), true);
}
}
dateSelected(date, granularity, type, ignoreClose) {
this.selected = this.utilsService
.updateSelected(this.componentConfig.allowMultiSelect, this.selected, date, granularity);
if (!ignoreClose) {
this.onDateClick();
}
this.onSelect.emit({
date: date.date,
granularity,
type
});
}
onDateClick() {
if (this.componentConfig.closeOnSelect) {
setTimeout(this.hideCalendar.bind(this), this.componentConfig.closeOnSelectDelay);
}
}
onKeyPress(event) {
switch (event.keyCode) {
case (9):
case (27):
this.hideCalendar();
break;
}
}
moveCalendarTo(date) {
const momentDate = this.utilsService.convertToMoment(date, this.componentConfig.format);
this.currentDateView = momentDate;
}
onLeftNavClick(change) {
this.onLeftNav.emit(change);
}
onRightNavClick(change) {
this.onRightNav.emit(change);
}
startGlobalListeners() {
this.globalListenersUnlisteners.push(this.renderer.listen(document, 'keydown', (e) => {
this.onKeyPress(e);
}), this.renderer.listen(document, 'scroll', () => {
this.onScroll();
}), this.renderer.listen(document, 'click', () => {
this.onBodyClick();
}));
}
stopGlobalListeners() {
this.globalListenersUnlisteners.forEach((ul) => ul());
this.globalListenersUnlisteners = [];
}
ngOnDestroy() {
this.handleInnerElementClickUnlisteners.forEach(ul => ul());
if (this.appendToElement) {
this.appendToElement.removeChild(this.calendarWrapper);
}
}
};
DatePickerComponent.ctorParameters = () => [
{ type: DatePickerService },
{ type: DomHelper },
{ type: ElementRef },
{ type: Renderer2 },
{ type: UtilsService },
{ type: ChangeDetectorRef }
];
__decorate([
Input()
], DatePickerComponent.prototype, "config", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "mode", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "placeholder", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "disabled", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "displayDate", void 0);
__decorate([
HostBinding('class'), Input()
], DatePickerComponent.prototype, "theme", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "minDate", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "maxDate", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "minTime", void 0);
__decorate([
Input()
], DatePickerComponent.prototype, "maxTime", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "open", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "close", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "onChange", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "onGoToCurrent", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "onLeftNav", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "onRightNav", void 0);
__decorate([
Output()
], DatePickerComponent.prototype, "onSelect", void 0);
__decorate([
ViewChild('container')
], DatePickerComponent.prototype, "calendarContainer", void 0);
__decorate([
ViewChild('dayCalendar')
], DatePickerComponent.prototype, "dayCalendarRef", void 0);
__decorate([
ViewChild('monthCalendar')
], DatePickerComponent.prototype, "monthCalendarRef", void 0);
__decorate([
ViewChild('daytimeCalendar')
], DatePickerComponent.prototype, "dayTimeCalendarRef", void 0);
__decorate([
ViewChild('timeSelect')
], DatePickerComponent.prototype, "timeSelectRef", void 0);
__decorate([
HostListener('click')
], DatePickerComponent.prototype, "onClick", null);
__decorate([
HostListener('window:resize')
], DatePickerComponent.prototype, "onScroll", null);
DatePickerComponent = DatePickerComponent_1 = __decorate([
Component({
selector: 'dp-date-picker',
template: "<div [ngClass]=\"{'dp-open': areCalendarsShown}\">\n <div [attr.data-hidden]=\"componentConfig.hideInputContainer\"\n [hidden]=\"componentConfig.hideInputContainer\"\n class=\"dp-input-container\">\n <input (blur)=\"inputBlurred()\"\n (focus)=\"inputFocused()\"\n (ngModelChange)=\"onViewDateChange($event)\"\n (keydown.enter)=\"componentConfig.closeOnEnter && hideCalendar()\"\n [disabled]=\"disabled\"\n [ngModel]=\"inputElementValue\"\n [placeholder]=\"placeholder\"\n [readonly]=\"componentConfig.disableKeypress\"\n class=\"dp-picker-input\"\n type=\"text\"/>\n </div>\n <div #container>\n <div [attr.data-hidden]=\"!_areCalendarsShown\"\n [hidden]=\"!_areCalendarsShown\"\n [ngSwitch]=\"mode\"\n class=\"dp-popup {{theme}}\">\n <dp-day-calendar #dayCalendar\n (onGoToCurrent)=\"onGoToCurrent.emit()\"\n (onLeftNav)=\"onLeftNavClick($event)\"\n (onRightNav)=\"onRightNavClick($event)\"\n (onSelect)=\"dateSelected($event, 'day', selectEvent.SELECTION, false)\"\n *ngSwitchCase=\"'day'\"\n [config]=\"dayCalendarConfig\"\n [displayDate]=\"displayDate\"\n [ngModel]=\"_selected\"\n [theme]=\"theme\">\n </dp-day-calendar>\n\n <dp-month-calendar #monthCalendar\n (onGoToCurrent)=\"onGoToCurrent.emit()\"\n (onLeftNav)=\"onLeftNavClick($event)\"\n (onRightNav)=\"onRightNavClick($event)\"\n (onSelect)=\"dateSelected($event, 'month', selectEvent.SELECTION, false)\"\n *ngSwitchCase=\"'month'\"\n [config]=\"dayCalendarConfig\"\n [displayDate]=\"displayDate\"\n [ngModel]=\"_selected\"\n [theme]=\"theme\">\n </dp-month-calendar>\n\n <dp-time-select #timeSelect\n (onChange)=\"dateSelected($event, 'second', selectEvent.SELECTION, true)\"\n *ngSwitchCase=\"'time'\"\n [config]=\"timeSelectConfig\"\n [ngModel]=\"_selected && _selected[0]\"\n [theme]=\"theme\">\n </dp-time-select>\n\n <dp-day-time-calendar #daytimeCalendar\n (onChange)=\"dateSelected($event, 'second', selectEvent.SELECTION, true)\"\n (onGoToCurrent)=\"onGoToCurrent.emit()\"\n (onLeftNav)=\"onLeftNavClick($event)\"\n (onRightNav)=\"onRightNavClick($event)\"\n *ngSwitchCase=\"'daytime'\"\n [config]=\"dayTimeCalendarConfig\"\n [displayDate]=\"displayDate\"\n [ngModel]=\"_selected && _selected[0]\"\n [theme]=\"theme\">\n </dp-day-time-calendar>\n </div>\n </div>\n</div>\n",
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
DatePickerService,
DayTimeCalendarService,
DayCalendarService,
TimeSelectService,
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerComponent_1),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DatePickerComponent_1),
multi: true
}
],
styles: ["dp-date-picker{display:inline-block}dp-date-picker.dp-material .dp-picker-input{box-sizing:border-box;height:30px;width:213px;font-size:13px;outline:0}dp-date-picker .dp-input-container{position:relative}dp-date-