angular-mydatepicker
Version:
Angular datepicker and date range picker
1,596 lines (1,587 loc) • 160 kB
JavaScript
import { CommonModule } from '@angular/common';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { Injectable, Component, ElementRef, ViewEncapsulation, ViewChild, Renderer2, ChangeDetectorRef, HostBinding, EventEmitter, Input, Output, Directive, ViewContainerRef, ComponentFactoryResolver, forwardRef, HostListener, NgModule } from '@angular/core';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const KeyCode = {
enter: 13,
esc: 27,
space: 32,
leftArrow: 37,
upArrow: 38,
rightArrow: 39,
downArrow: 40,
tab: 9,
shift: 16,
};
KeyCode[KeyCode.enter] = 'enter';
KeyCode[KeyCode.esc] = 'esc';
KeyCode[KeyCode.space] = 'space';
KeyCode[KeyCode.leftArrow] = 'leftArrow';
KeyCode[KeyCode.upArrow] = 'upArrow';
KeyCode[KeyCode.rightArrow] = 'rightArrow';
KeyCode[KeyCode.downArrow] = 'downArrow';
KeyCode[KeyCode.tab] = 'tab';
KeyCode[KeyCode.shift] = 'shift';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {string} */
const KeyName = {
enter: "Enter",
esc: "Escape|Esc",
space: " |Spacebar",
leftArrow: "ArrowLeft|Left",
upArrow: "ArrowUp|Up",
rightArrow: "ArrowRight|Right",
downArrow: "ArrowDown|Down",
tab: "Tab",
shift: "Shift",
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* Constants
* @type {?}
*/
const D = "d";
/** @type {?} */
const DD = "dd";
/** @type {?} */
const M = "m";
/** @type {?} */
const MM = "mm";
/** @type {?} */
const MMM = "mmm";
/** @type {?} */
const Y = "y";
/** @type {?} */
const YYYY = "yyyy";
/** @type {?} */
const ORDINAL = "##";
/** @type {?} */
const ST = 'st';
/** @type {?} */
const ND = "nd";
/** @type {?} */
const RD = "rd";
/** @type {?} */
const DATE_ROW_COUNT = 5;
/** @type {?} */
const DATE_COL_COUNT = 6;
/** @type {?} */
const MONTH_ROW_COUNT = 3;
/** @type {?} */
const MONTH_COL_COUNT = 2;
/** @type {?} */
const YEAR_ROW_COUNT = 4;
/** @type {?} */
const YEAR_COL_COUNT = 4;
/** @type {?} */
const DOT = ".";
/** @type {?} */
const UNDER_LINE = "_";
/** @type {?} */
const PIPE = "|";
/** @type {?} */
const YEAR_SEPARATOR = " - ";
/** @type {?} */
const SU = "su";
/** @type {?} */
const MO = "mo";
/** @type {?} */
const TU = "tu";
/** @type {?} */
const WE = "we";
/** @type {?} */
const TH = "th";
/** @type {?} */
const FR = "fr";
/** @type {?} */
const SA = "sa";
/** @type {?} */
const DEFAULT_LOCALE = "en";
/** @type {?} */
const ZERO_STR = "0";
/** @type {?} */
const EMPTY_STR = "";
/** @type {?} */
const SPACE_STR = " ";
/** @type {?} */
const CLICK = "click";
/** @type {?} */
const KEYUP = "keyup";
/** @type {?} */
const BLUR = "blur";
/** @type {?} */
const DISABLED = "disabled";
/** @type {?} */
const BODY = "body";
/** @type {?} */
const VALUE = "value";
/** @type {?} */
const OPTIONS = "options";
/** @type {?} */
const DEFAULT_MONTH = "defaultMonth";
/** @type {?} */
const LOCALE = "locale";
/** @type {?} */
const OBJECT = "object";
/** @type {?} */
const PX = "px";
/** @type {?} */
const STYLE = "style";
/** @type {?} */
const INNER_HTML = "innerHTML";
/** @type {?} */
const OPTS = "opts";
/** @type {?} */
const YEARS_DURATION = "yearsDuration";
/** @type {?} */
const YEARS = "years";
/** @type {?} */
const VISIBLE_MONTH = "visibleMonth";
/** @type {?} */
const SELECT_MONTH = "selectMonth";
/** @type {?} */
const SELECT_YEAR = "selectYear";
/** @type {?} */
const PREV_VIEW_DISABLED = "prevViewDisabled";
/** @type {?} */
const NEXT_VIEW_DISABLED = "nextViewDisabled";
/** @type {?} */
const DATES = "dates";
/** @type {?} */
const WEEK_DAYS = "weekDays";
/** @type {?} */
const SELECTED_DATE = "selectedDate";
/** @type {?} */
const SELECTED_DATE_RANGE = "selectedDateRange";
/** @type {?} */
const MONTHS = "months";
/** @type {?} */
const ANIMATION_END = "animationend";
/** @type {?} */
const ANIMATION_TIMEOUT = 550;
/** @type {?} */
const MY_DP_ANIMATION = "myDpAnimation";
/** @type {?} */
const ANIMATION_NAMES = ["Fade", "ScaleTop", "ScaleCenter", "Rotate", "FlipDiagonal", "Own"];
/** @type {?} */
const IN = "In";
/** @type {?} */
const OUT = "Out";
/** @type {?} */
const TABINDEX = "tabindex";
/** @type {?} */
const TD_SELECTOR = "table tbody tr td:not(.myDpDaycellWeekNbr)";
/** @type {?} */
const PREVENT_CLOSE_TIMEOUT = 50;
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class UtilService {
constructor() {
this.weekDays = [SU, MO, TU, WE, TH, FR, SA];
}
/**
* @param {?} dateStr
* @param {?} options
* @param {?} validateOpts
* @return {?}
*/
isDateValid(dateStr, options, validateOpts) {
const { dateFormat, minYear, maxYear, monthLabels } = options;
/** @type {?} */
const returnDate = this.resetDate();
/** @type {?} */
const datesInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
/** @type {?} */
const isMonthStr = dateFormat.indexOf(MMM) !== -1;
/** @type {?} */
const delimeters = dateFormat.match(/[^(d#my)]{1,}/g);
if (!dateStr || dateStr === EMPTY_STR) {
return returnDate;
}
/** @type {?} */
const dateValues = this.getDateValue(dateStr, dateFormat, delimeters);
/** @type {?} */
let year = 0;
/** @type {?} */
let month = 0;
/** @type {?} */
let day = 0;
for (let dv of dateValues) {
if (dv.format.indexOf(ORDINAL) != -1) {
/** @type {?} */
const dayNumber = parseInt(dv.value.replace(/\D/g, ''));
/** @type {?} */
const ordinalStr = dv.value.replace(/[0-9]/g, '');
/** @type {?} */
const ordinal = this.getOrdinal(dayNumber);
if (ordinal !== ordinalStr) {
return returnDate;
}
dv.value = dv.value.replace(ST, EMPTY_STR).replace(ND, EMPTY_STR).replace(RD, EMPTY_STR).replace(TH, EMPTY_STR);
dv.format = dv.format.replace(ORDINAL, EMPTY_STR);
}
const { value, format } = dv;
if (value && /^\d+$/.test(value) && Number(value) === 0) {
return returnDate;
}
if (format.indexOf(YYYY) !== -1) {
year = this.getNumberByValue(dv);
}
else if (format.indexOf(M) !== -1) {
month = isMonthStr ? this.getMonthNumberByMonthName(dv, monthLabels) : this.getNumberByValue(dv);
}
else if (format.indexOf(D) !== -1) {
day = this.getNumberByValue(dv);
}
}
const { validateDisabledDates, selectedValue } = validateOpts;
year = year === 0 && selectedValue ? selectedValue.year : year;
month = month === 0 && selectedValue ? selectedValue.month : month;
day = day === 0 && selectedValue ? selectedValue.day : day;
/** @type {?} */
const today = this.getToday();
if (year === 0 && (month !== 0 || day !== 0)) {
year = today.year;
}
if (month === 0 && (year !== 0 || day !== 0)) {
month = today.month;
}
if (day === 0 && (year !== 0 || month !== 0)) {
day = today.day;
}
if (month !== -1 && day !== -1 && year !== -1) {
if (year < minYear || year > maxYear || month < 1 || month > 12) {
return returnDate;
}
/** @type {?} */
const date = { year, month, day };
if (validateDisabledDates && this.isDisabledDate(date, options).disabled) {
return returnDate;
}
if (year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0)) {
datesInMonth[1] = 29;
}
if (day < 1 || day > datesInMonth[month - 1]) {
return returnDate;
}
// Valid date
return date;
}
return returnDate;
}
/**
* @param {?} dateRangeStr
* @param {?} options
* @param {?} validateOpts
* @return {?}
*/
isDateValidDateRange(dateRangeStr, options, validateOpts) {
/** @type {?} */
let dateRange = { begin: this.resetDate(), end: this.resetDate() };
if (dateRangeStr && dateRangeStr.length) {
/** @type {?} */
const dates = dateRangeStr.split(options.dateRangeDatesDelimiter);
if (dates && dates.length === 2) {
const [beginDate, endDate] = dates;
let { selectedValue } = validateOpts;
if (selectedValue) {
validateOpts.selectedValue = selectedValue.begin;
}
/** @type {?} */
const begin = this.isDateValid(beginDate, options, validateOpts);
if (this.isInitializedDate(begin)) {
if (selectedValue) {
validateOpts.selectedValue = selectedValue.end;
}
/** @type {?} */
const end = this.isDateValid(endDate, options, validateOpts);
if (this.isInitializedDate(end) && this.isDateSameOrEarlier(begin, end)) {
dateRange = { begin, end };
}
}
}
}
return dateRange;
}
/**
* @param {?} dateStr
* @param {?} dateFormat
* @param {?} delimeters
* @return {?}
*/
getDateValue(dateStr, dateFormat, delimeters) {
/** @type {?} */
let del = EMPTY_STR;
if (delimeters) {
for (const d of delimeters) {
if (del.indexOf(d) === -1) {
del += d;
}
}
}
/** @type {?} */
const re = new RegExp("[" + del + "]");
/** @type {?} */
const ds = dateStr.split(re);
/** @type {?} */
const df = dateFormat.split(re);
/** @type {?} */
const da = [];
for (let i = 0; i < df.length; i++) {
if (df[i].indexOf(YYYY) !== -1) {
da.push({ value: ds[i], format: df[i] });
}
if (df[i].indexOf(M) !== -1) {
da.push({ value: ds[i], format: df[i] });
}
if (df[i].indexOf(D) !== -1) {
da.push({ value: ds[i], format: df[i] });
}
}
return da;
}
/**
* @param {?} df
* @param {?} monthLabels
* @return {?}
*/
getMonthNumberByMonthName(df, monthLabels) {
if (df.value) {
for (let key = 1; key <= 12; key++) {
if (df.value.toLowerCase() === monthLabels[key].toLowerCase()) {
return key;
}
}
}
return -1;
}
/**
* @param {?} df
* @return {?}
*/
getNumberByValue(df) {
if (!/^\d+$/.test(df.value)) {
return -1;
}
/** @type {?} */
let nbr = Number(df.value);
if (df.format.length === 1 && df.value.length !== 1 && nbr < 10 || df.format.length === 1 && df.value.length !== 2 && nbr >= 10) {
nbr = -1;
}
else if (df.format.length === 2 && df.value.length > 2) {
nbr = -1;
}
return nbr;
}
/**
* @param {?} monthString
* @return {?}
*/
parseDefaultMonth(monthString) {
/** @type {?} */
const month = { monthTxt: EMPTY_STR, monthNbr: 0, year: 0 };
if (monthString !== EMPTY_STR) {
/** @type {?} */
const split = monthString.split(monthString.match(/[^0-9]/)[0]);
month.monthNbr = split[0].length === 2 ? Number(split[0]) : Number(split[1]);
month.year = split[0].length === 2 ? Number(split[1]) : Number(split[0]);
}
return month;
}
/**
* @param {?} date
* @param {?} options
* @return {?}
*/
isDisabledDate(date, options) {
const { minYear, maxYear, disableUntil, disableSince, disableWeekends, disableDates, disableDateRanges, disableWeekdays, enableDates } = options;
if (this.dateMatchToDates(date, enableDates)) {
return this.getDisabledValue(false, EMPTY_STR);
}
if (date.year < minYear && date.month === 12 || date.year > maxYear && date.month === 1) {
return this.getDisabledValue(true, EMPTY_STR);
}
/** @type {?} */
const inputDates = (/** @type {?} */ (disableDates));
/** @type {?} */
const result = inputDates.find((/**
* @param {?} d
* @return {?}
*/
(d) => {
return d.dates;
}));
if (!result) {
if (this.dateMatchToDates(date, inputDates)) {
return this.getDisabledValue(true, EMPTY_STR);
}
}
else {
for (const dd of inputDates) {
if (this.dateMatchToDates(date, dd.dates)) {
return this.getDisabledValue(true, dd.styleClass);
}
}
}
if (this.isDisabledByDisableUntil(date, disableUntil)) {
return this.getDisabledValue(true, EMPTY_STR);
}
if (this.isDisabledByDisableSince(date, disableSince)) {
return this.getDisabledValue(true, EMPTY_STR);
}
if (disableWeekends) {
/** @type {?} */
const dayNbr = this.getDayNumber(date);
if (dayNbr === 0 || dayNbr === 6) {
return this.getDisabledValue(true, EMPTY_STR);
}
}
/** @type {?} */
const dn = this.getDayNumber(date);
if (disableWeekdays.length > 0) {
for (const wd of disableWeekdays) {
if (dn === this.getWeekdayIndex(wd)) {
return this.getDisabledValue(true, EMPTY_STR);
}
}
}
if (this.isDisabledByDisableDateRange(date, date, disableDateRanges)) {
return this.getDisabledValue(true, EMPTY_STR);
}
return this.getDisabledValue(false, EMPTY_STR);
}
/**
* @param {?} disabled
* @param {?} styleClass
* @return {?}
*/
getDisabledValue(disabled, styleClass) {
return { disabled, styleClass };
}
/**
* @param {?} date
* @param {?} dates
* @return {?}
*/
dateMatchToDates(date, dates) {
for (const d of dates) {
if ((d.year === 0 || d.year === date.year) && (d.month === 0 || d.month === date.month) && d.day === date.day) {
return true;
}
}
return false;
}
/**
* @param {?} year
* @param {?} month
* @param {?} options
* @return {?}
*/
isDisabledMonth(year, month, options) {
const { disableUntil, disableSince, disableDateRanges, enableDates } = options;
/** @type {?} */
const dateEnd = { year, month, day: this.datesInMonth(month, year) };
/** @type {?} */
const dateBegin = { year, month, day: 1 };
if (this.isDatesEnabled(dateBegin, dateEnd, enableDates)) {
return false;
}
if (this.isDisabledByDisableUntil(dateEnd, disableUntil)) {
return true;
}
if (this.isDisabledByDisableSince(dateBegin, disableSince)) {
return true;
}
if (this.isDisabledByDisableDateRange(dateBegin, dateEnd, disableDateRanges)) {
return true;
}
return false;
}
/**
* @param {?} year
* @param {?} options
* @return {?}
*/
isDisabledYear(year, options) {
const { disableUntil, disableSince, disableDateRanges, enableDates, minYear, maxYear } = options;
/** @type {?} */
const dateEnd = { year, month: 12, day: 31 };
/** @type {?} */
const dateBegin = { year, month: 1, day: 1 };
if (this.isDatesEnabled(dateBegin, dateEnd, enableDates)) {
return false;
}
if (this.isDisabledByDisableUntil(dateEnd, disableUntil)) {
return true;
}
if (this.isDisabledByDisableSince(dateBegin, disableSince)) {
return true;
}
if (this.isDisabledByDisableDateRange(dateBegin, dateEnd, disableDateRanges)) {
return true;
}
if (year < minYear || year > maxYear) {
return true;
}
return false;
}
/**
* @param {?} date
* @param {?} disableUntil
* @return {?}
*/
isDisabledByDisableUntil(date, disableUntil) {
return this.isInitializedDate(disableUntil) && this.getTimeInMilliseconds(date) <= this.getTimeInMilliseconds(disableUntil);
}
/**
* @param {?} date
* @param {?} disableSince
* @return {?}
*/
isDisabledByDisableSince(date, disableSince) {
return this.isInitializedDate(disableSince) && this.getTimeInMilliseconds(date) >= this.getTimeInMilliseconds(disableSince);
}
/**
* @param {?} date
* @param {?} enableDates
* @return {?}
*/
isPastDatesEnabled(date, enableDates) {
for (const d of enableDates) {
if (this.getTimeInMilliseconds(d) <= this.getTimeInMilliseconds(date)) {
return true;
}
}
return false;
}
/**
* @param {?} date
* @param {?} enableDates
* @return {?}
*/
isFutureDatesEnabled(date, enableDates) {
for (const d of enableDates) {
if (this.getTimeInMilliseconds(d) >= this.getTimeInMilliseconds(date)) {
return true;
}
}
return false;
}
/**
* @param {?} dateBegin
* @param {?} dateEnd
* @param {?} enableDates
* @return {?}
*/
isDatesEnabled(dateBegin, dateEnd, enableDates) {
for (const d of enableDates) {
if (this.getTimeInMilliseconds(d) >= this.getTimeInMilliseconds(dateBegin)
&& this.getTimeInMilliseconds(d) <= this.getTimeInMilliseconds(dateEnd)) {
return true;
}
}
return false;
}
/**
* @param {?} dateBegin
* @param {?} dateEnd
* @param {?} disableDateRanges
* @return {?}
*/
isDisabledByDisableDateRange(dateBegin, dateEnd, disableDateRanges) {
/** @type {?} */
const dateMsBegin = this.getTimeInMilliseconds(dateBegin);
/** @type {?} */
const dateMsEnd = this.getTimeInMilliseconds(dateEnd);
for (const d of disableDateRanges) {
if (this.isInitializedDate(d.begin) && this.isInitializedDate(d.end)
&& dateMsBegin >= this.getTimeInMilliseconds(d.begin) && dateMsEnd <= this.getTimeInMilliseconds(d.end)) {
return true;
}
}
return false;
}
/**
* @param {?} date
* @param {?} options
* @return {?}
*/
isMarkedDate(date, options) {
const { markDates, markWeekends } = options;
for (const md of markDates) {
if (this.dateMatchToDates(date, md.dates)) {
return this.getMarkedValue(true, md.color, md.styleClass);
}
}
if (markWeekends && markWeekends.marked) {
/** @type {?} */
const dayNbr = this.getDayNumber(date);
if (dayNbr === 0 || dayNbr === 6) {
return this.getMarkedValue(true, markWeekends.color, EMPTY_STR);
}
}
return this.getMarkedValue(false, EMPTY_STR, EMPTY_STR);
}
/**
* @param {?} marked
* @param {?} color
* @param {?} styleClass
* @return {?}
*/
getMarkedValue(marked, color, styleClass) {
return { marked, color: color ? color : EMPTY_STR, styleClass: styleClass ? styleClass : EMPTY_STR };
}
/**
* @param {?} date
* @param {?} options
* @return {?}
*/
isHighlightedDate(date, options) {
const { sunHighlight, satHighlight, highlightDates } = options;
/** @type {?} */
const dayNbr = this.getDayNumber(date);
if (sunHighlight && dayNbr === 0 || satHighlight && dayNbr === 6) {
return true;
}
if (this.dateMatchToDates(date, highlightDates)) {
return true;
}
return false;
}
/**
* @param {?} date
* @return {?}
*/
getWeekNumber(date) {
/** @type {?} */
const d = new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0);
d.setDate(d.getDate() + (d.getDay() === 0 ? -3 : 4 - d.getDay()));
return Math.round(((d.getTime() - new Date(d.getFullYear(), 0, 4).getTime()) / 86400000) / 7) + 1;
}
/**
* @param {?} date
* @param {?} dateRange
* @param {?} dateFormat
* @param {?} monthLabels
* @param {?} rangeDelimiter
* @param {?=} dateStr
* @return {?}
*/
getDateModel(date, dateRange, dateFormat, monthLabels, rangeDelimiter, dateStr = EMPTY_STR) {
/** @type {?} */
let singleDateModel = null;
/** @type {?} */
let dateRangeModel = null;
if (date) {
singleDateModel = {
date,
jsDate: this.myDateToJsDate(date),
formatted: dateStr.length ? dateStr : this.formatDate(date, dateFormat, monthLabels),
epoc: this.getEpocTime(date)
};
}
else {
dateRangeModel = {
beginDate: dateRange.begin,
beginJsDate: this.myDateToJsDate(dateRange.begin),
beginEpoc: this.getEpocTime(dateRange.begin),
endDate: dateRange.end,
endJsDate: this.myDateToJsDate(dateRange.end),
endEpoc: this.getEpocTime(dateRange.end),
formatted: this.formatDate(dateRange.begin, dateFormat, monthLabels) + rangeDelimiter + this.formatDate(dateRange.end, dateFormat, monthLabels)
};
}
return {
isRange: date === null,
singleDate: singleDateModel,
dateRange: dateRangeModel
};
}
/**
* @param {?} date
* @param {?} dateFormat
* @param {?} monthLabels
* @return {?}
*/
formatDate(date, dateFormat, monthLabels) {
/** @type {?} */
let formatted = dateFormat.replace(YYYY, String(date.year));
if (dateFormat.indexOf(MMM) !== -1) {
formatted = formatted.replace(MMM, monthLabels[date.month]);
}
else if (dateFormat.indexOf(MM) !== -1) {
formatted = formatted.replace(MM, this.preZero(date.month));
}
else {
formatted = formatted.replace(M, String(date.month));
}
if (dateFormat.indexOf(DD) !== -1) {
formatted = formatted.replace(DD, this.preZero(date.day));
}
else {
formatted = formatted.replace(D, String(date.day));
}
if (dateFormat.indexOf(ORDINAL) !== -1) {
formatted = formatted.replace(ORDINAL, this.getOrdinal(date.day));
}
return formatted;
}
/**
* @param {?} date
* @return {?}
*/
getOrdinal(date) {
if (date > 3 && date < 21) {
return TH;
}
switch (date % 10) {
case 1:
return ST;
case 2:
return ND;
case 3:
return RD;
default:
return TH;
}
}
/**
* @param {?} model
* @return {?}
*/
getFormattedDate(model) {
return !model.isRange ? model.singleDate.formatted : model.dateRange.formatted;
}
/**
* @param {?} val
* @return {?}
*/
preZero(val) {
return val < 10 ? ZERO_STR + val : String(val);
}
/**
* @param {?} date
* @return {?}
*/
isInitializedDate(date) {
return date.year !== 0 && date.month !== 0 && date.day !== 0;
}
/**
* @param {?} firstDate
* @param {?} secondDate
* @return {?}
*/
isDateEarlier(firstDate, secondDate) {
return this.getTimeInMilliseconds(firstDate) < this.getTimeInMilliseconds(secondDate);
}
/**
* @param {?} firstDate
* @param {?} secondDate
* @return {?}
*/
isDateSameOrEarlier(firstDate, secondDate) {
return this.getTimeInMilliseconds(firstDate) <= this.getTimeInMilliseconds(secondDate);
}
/**
* @param {?} firstDate
* @param {?} secondDate
* @return {?}
*/
isDateSame(firstDate, secondDate) {
return this.getTimeInMilliseconds(firstDate) === this.getTimeInMilliseconds(secondDate);
}
/**
* @param {?} dateRange
* @param {?} date
* @return {?}
*/
isDateRangeBeginOrEndSame(dateRange, date) {
/** @type {?} */
const dateMs = this.getTimeInMilliseconds(date);
return this.getTimeInMilliseconds(dateRange.begin) === dateMs || this.getTimeInMilliseconds(dateRange.end) === dateMs;
}
/**
* @param {?} dateRange
* @param {?} date
* @return {?}
*/
isDateRangeBegin(dateRange, date) {
/** @type {?} */
const dateMs = this.getTimeInMilliseconds(date);
return this.getTimeInMilliseconds(dateRange.begin) === dateMs;
}
/**
* @param {?} dateRange
* @param {?} date
* @return {?}
*/
isDateRangeEnd(dateRange, date) {
/** @type {?} */
const dateMs = this.getTimeInMilliseconds(date);
return this.getTimeInMilliseconds(dateRange.end) === dateMs;
}
/**
* @param {?} date
* @param {?} dateRange
* @return {?}
*/
isDateInRange(date, dateRange) {
if (!this.isInitializedDate(dateRange.begin) || !this.isInitializedDate(dateRange.end)) {
return false;
}
return this.isDateSameOrEarlier(dateRange.begin, date) && this.isDateSameOrEarlier(date, dateRange.end);
}
/**
* @return {?}
*/
resetDate() {
return { year: 0, month: 0, day: 0 };
}
/**
* @param {?} date
* @return {?}
*/
getTimeInMilliseconds(date) {
return this.myDateToJsDate(date).getTime();
}
/**
* @return {?}
*/
getToday() {
/** @type {?} */
const date = new Date();
return { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate() };
}
/**
* @param {?} date
* @return {?}
*/
getDayNumber(date) {
return new Date(date.year, date.month - 1, date.day, 0, 0, 0, 0).getDay();
}
/**
* @param {?} wd
* @return {?}
*/
getWeekdayIndex(wd) {
return this.weekDays.indexOf(wd);
}
/**
* @param {?} date
* @return {?}
*/
getEpocTime(date) {
return Math.round(this.getTimeInMilliseconds(date) / 1000.0);
}
/**
* @param {?} date
* @return {?}
*/
jsDateToMyDate(date) {
return { year: date.getFullYear(), month: date.getMonth() + 1, day: date.getDate() };
}
/**
* @param {?} date
* @return {?}
*/
myDateToJsDate(date) {
const { year, month, day } = date;
return new Date(year, month - 1, day, 0, 0, 0, 0);
}
/**
* @param {?} m
* @param {?} y
* @return {?}
*/
datesInMonth(m, y) {
return new Date(y, m, 0).getDate();
}
/**
* @param {?} m
* @param {?} y
* @return {?}
*/
datesInPrevMonth(m, y) {
/** @type {?} */
const d = this.getJsDate(y, m, 1);
d.setMonth(d.getMonth() - 1);
return this.datesInMonth(d.getMonth() + 1, d.getFullYear());
}
/**
* @param {?} year
* @param {?} month
* @param {?} day
* @return {?}
*/
getJsDate(year, month, day) {
return new Date(year, month - 1, day, 0, 0, 0, 0);
}
/**
* @param {?} selectedValue
* @param {?} dateRange
* @return {?}
*/
getSelectedValue(selectedValue, dateRange) {
if (!selectedValue) {
return null;
}
if (!dateRange) {
return selectedValue.date;
}
else {
const { beginDate, endDate } = selectedValue;
return { begin: beginDate, end: endDate };
}
}
/**
* @param {?} event
* @return {?}
*/
getKeyCodeFromEvent(event) {
/** @type {?} */
let key = event.key || event.keyCode || event.which;
if (this.checkKeyName(key, KeyName.enter) || key === KeyCode.enter) {
return KeyCode.enter;
}
else if (this.checkKeyName(key, KeyName.esc) || key === KeyCode.esc) {
return KeyCode.esc;
}
else if (this.checkKeyName(key, KeyName.space) || key === KeyCode.space) {
return KeyCode.space;
}
else if (this.checkKeyName(key, KeyName.leftArrow) || key === KeyCode.leftArrow) {
return KeyCode.leftArrow;
}
else if (this.checkKeyName(key, KeyName.upArrow) || key === KeyCode.upArrow) {
return KeyCode.upArrow;
}
else if (this.checkKeyName(key, KeyName.rightArrow) || key === KeyCode.rightArrow) {
return KeyCode.rightArrow;
}
else if (this.checkKeyName(key, KeyName.downArrow) || key === KeyCode.downArrow) {
return KeyCode.downArrow;
}
else if (this.checkKeyName(key, KeyName.tab) || key === KeyCode.tab) {
return KeyCode.tab;
}
else if (this.checkKeyName(key, KeyName.shift) || key === KeyCode.shift) {
return KeyCode.shift;
}
else {
return null;
}
}
/**
* @param {?} key
* @param {?} keyName
* @return {?}
*/
checkKeyName(key, keyName) {
/** @type {?} */
const arr = keyName.split(PIPE);
return arr.indexOf(key) !== -1;
}
}
UtilService.decorators = [
{ type: Injectable }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const MonthId = {
prev: 1,
curr: 2,
next: 3,
};
MonthId[MonthId.prev] = 'prev';
MonthId[MonthId.curr] = 'curr';
MonthId[MonthId.next] = 'next';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const DefaultView = {
Date: 1,
Month: 2,
Year: 3,
};
DefaultView[DefaultView.Date] = 'Date';
DefaultView[DefaultView.Month] = 'Month';
DefaultView[DefaultView.Year] = 'Year';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const CalAnimation = {
None: 0,
Fade: 1,
ScaleTop: 2,
ScaleCenter: 3,
Rotate: 4,
FlipDiagonal: 5,
Own: 6,
};
CalAnimation[CalAnimation.None] = 'None';
CalAnimation[CalAnimation.Fade] = 'Fade';
CalAnimation[CalAnimation.ScaleTop] = 'ScaleTop';
CalAnimation[CalAnimation.ScaleCenter] = 'ScaleCenter';
CalAnimation[CalAnimation.Rotate] = 'Rotate';
CalAnimation[CalAnimation.FlipDiagonal] = 'FlipDiagonal';
CalAnimation[CalAnimation.Own] = 'Own';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/** @enum {number} */
const HeaderAction = {
PrevBtnClick: 1,
NextBtnClick: 2,
MonthBtnClick: 3,
YearBtnClick: 4,
};
HeaderAction[HeaderAction.PrevBtnClick] = 'PrevBtnClick';
HeaderAction[HeaderAction.NextBtnClick] = 'NextBtnClick';
HeaderAction[HeaderAction.MonthBtnClick] = 'MonthBtnClick';
HeaderAction[HeaderAction.YearBtnClick] = 'YearBtnClick';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class CalendarComponent {
/**
* @param {?} elem
* @param {?} renderer
* @param {?} cdr
* @param {?} utilService
*/
constructor(elem, renderer, cdr, utilService) {
this.elem = elem;
this.renderer = renderer;
this.cdr = cdr;
this.utilService = utilService;
this.position = "static";
this.visibleMonth = { monthTxt: EMPTY_STR, monthNbr: 0, year: 0 };
this.selectedMonth = { monthNbr: 0, year: 0 };
this.selectedDate = { year: 0, month: 0, day: 0 };
this.selectedDateRange = { begin: { year: 0, month: 0, day: 0 }, end: { year: 0, month: 0, day: 0 } };
this.weekDays = [];
this.dates = [];
this.months = [];
this.years = [];
this.yearsDuration = "";
this.dayIdx = 0;
this.weekDayOpts = [SU, MO, TU, WE, TH, FR, SA];
this.selectMonth = false;
this.selectYear = false;
this.viewChanged = false;
this.selectorPos = null;
this.prevViewDisabled = false;
this.nextViewDisabled = false;
this.clickListener = renderer.listen(elem.nativeElement, CLICK, (/**
* @param {?} event
* @return {?}
*/
(event) => {
if ((this.opts.monthSelector || this.opts.yearSelector) && event.target) {
this.resetMonthYearSelect();
}
}));
}
/**
* @return {?}
*/
ngAfterViewInit() {
const { stylesData, calendarAnimation, inline } = this.opts;
if (stylesData.styles.length) {
/** @type {?} */
const styleElTemp = this.renderer.createElement(STYLE);
this.renderer.appendChild(styleElTemp, this.renderer.createText(stylesData.styles));
this.renderer.appendChild(this.styleEl.nativeElement, styleElTemp);
}
if (calendarAnimation.in !== CalAnimation.None) {
this.setCalendarAnimation(calendarAnimation, true);
}
if (!inline) {
this.focusToSelector();
}
}
/**
* @return {?}
*/
ngOnDestroy() {
this.clickListener();
}
/**
* @param {?} opts
* @param {?} defaultMonth
* @param {?} selectedValue
* @param {?} inputValue
* @param {?} selectorPos
* @param {?} dc
* @param {?} cvc
* @param {?} rds
* @param {?} va
* @param {?} cbe
* @return {?}
*/
initializeComponent(opts, defaultMonth, selectedValue, inputValue, selectorPos, dc, cvc, rds, va, cbe) {
this.opts = opts;
this.selectorPos = selectorPos;
this.dateChanged = dc;
this.calendarViewChanged = cvc;
this.rangeDateSelection = rds;
this.viewActivated = va;
this.closedByEsc = cbe;
const { defaultView, firstDayOfWeek, dayLabels } = opts;
this.weekDays.length = 0;
this.dayIdx = this.weekDayOpts.indexOf(firstDayOfWeek);
if (this.dayIdx !== -1) {
/** @type {?} */
let idx = this.dayIdx;
for (let i = 0; i < this.weekDayOpts.length; i++) {
this.weekDays.push(dayLabels[this.weekDayOpts[idx]]);
idx = this.weekDayOpts[idx] === SA ? 0 : idx + 1;
}
}
this.initializeView(defaultMonth, selectedValue, inputValue);
this.setCalendarVisibleMonth();
this.setDefaultView(defaultView);
}
/**
* @param {?} defaultMonth
* @param {?} selectedValue
* @param {?} inputValue
* @return {?}
*/
initializeView(defaultMonth, selectedValue, inputValue) {
const { dateRange } = this.opts;
// use today as a selected month
/** @type {?} */
const today = this.utilService.getToday();
this.selectedMonth = { monthNbr: today.month, year: today.year };
// If default month attribute valur given use it as a selected month
const { defMonth, overrideSelection } = defaultMonth;
if (defMonth && defMonth.length) {
this.selectedMonth = this.utilService.parseDefaultMonth(defMonth);
}
/** @type {?} */
let validateOpts = null;
if (!dateRange) {
// Single date mode - If date selected use it as selected month
validateOpts = { validateDisabledDates: false, selectedValue: this.utilService.getSelectedValue(selectedValue, dateRange) };
/** @type {?} */
const date = this.utilService.isDateValid(inputValue, this.opts, validateOpts);
if (this.utilService.isInitializedDate(date)) {
this.selectedDate = date;
if (!overrideSelection) {
this.selectedMonth = { monthNbr: date.month, year: date.year };
}
}
}
else {
// Date range mode - If date range selected use begin date as selected month
validateOpts = { validateDisabledDates: false, selectedValue: this.utilService.getSelectedValue(selectedValue, dateRange) };
const { begin, end } = this.utilService.isDateValidDateRange(inputValue, this.opts, validateOpts);
if (this.utilService.isInitializedDate(begin) && this.utilService.isInitializedDate(end)) {
this.selectedDateRange = { begin, end };
if (!overrideSelection) {
this.selectedMonth = { monthNbr: begin.month, year: begin.year };
}
}
}
}
/**
* @param {?} opts
* @param {?} defaultMonth
* @param {?} selectedValue
* @param {?} inputValue
* @return {?}
*/
refreshComponent(opts, defaultMonth, selectedValue, inputValue) {
this.opts = opts;
const { defaultView } = opts;
this.initializeView(defaultMonth, selectedValue, inputValue);
this.setCalendarVisibleMonth();
this.setDefaultView(defaultView);
}
/**
* @param {?} headerAction
* @return {?}
*/
headerAction(headerAction) {
const { monthSelector, yearSelector } = this.opts;
if (headerAction === HeaderAction.PrevBtnClick) {
if (!this.prevViewDisabled) {
this.onPrevNavigateBtnClicked();
}
}
else if (headerAction === HeaderAction.NextBtnClick) {
if (!this.nextViewDisabled) {
this.onNextNavigateBtnClicked();
}
}
else if (headerAction === HeaderAction.MonthBtnClick) {
if (monthSelector) {
this.onMonthViewBtnClicked();
}
}
else if (headerAction === HeaderAction.YearBtnClick) {
if (yearSelector) {
this.onYearViewBtnClicked();
}
}
}
/**
* @param {?} defaultView
* @return {?}
*/
setDefaultView(defaultView) {
if (defaultView === DefaultView.Month) {
this.monthViewBtnClicked();
}
else if (defaultView === DefaultView.Year) {
this.yearViewBtnClicked();
}
}
/**
* @param {?} calAnimation
* @param {?} isOpen
* @return {?}
*/
setCalendarAnimation(calAnimation, isOpen) {
const { nativeElement } = this.selectorEl;
const { renderer } = this;
/** @type {?} */
const classIn = MY_DP_ANIMATION + ANIMATION_NAMES[calAnimation.in - 1];
if (isOpen) {
renderer.addClass(nativeElement, classIn + IN);
}
else {
/** @type {?} */
const classOut = MY_DP_ANIMATION + ANIMATION_NAMES[calAnimation.out - 1];
renderer.removeClass(nativeElement, classIn + IN);
renderer.addClass(nativeElement, classOut + OUT);
}
}
/**
* @return {?}
*/
resetDateValue() {
if (!this.opts.dateRange) {
this.selectedDate = this.utilService.resetDate();
}
else {
this.selectedDateRange.begin = this.utilService.resetDate();
this.selectedDateRange.end = this.utilService.resetDate();
}
}
/**
* @return {?}
*/
clearDate() {
const { month, year } = this.utilService.getToday();
this.selectedMonth = { monthNbr: month, year: year };
this.resetDateValue();
this.setCalendarVisibleMonth();
this.resetMonthYearSelect();
}
/**
* @return {?}
*/
resetMonthYearSelect() {
this.selectMonth = false;
this.selectYear = false;
}
/**
* @return {?}
*/
onMonthViewBtnClicked() {
this.viewChanged = true;
this.monthViewBtnClicked();
}
/**
* @return {?}
*/
monthViewBtnClicked() {
this.selectMonth = !this.selectMonth;
this.selectYear = false;
this.cdr.detectChanges();
if (this.selectMonth) {
this.generateMonths();
}
else {
const { year, monthNbr } = this.selectedMonth;
this.visibleMonth = { monthTxt: this.opts.monthLabels[monthNbr], monthNbr, year };
this.generateCalendar(monthNbr, year, true);
}
}
/**
* @param {?} cell
* @return {?}
*/
onMonthCellClicked(cell) {
this.viewChanged = true;
const { year, monthNbr } = this.visibleMonth;
/** @type {?} */
const monthChange = cell.nbr !== monthNbr;
this.visibleMonth = { monthTxt: this.opts.monthLabels[cell.nbr], monthNbr: cell.nbr, year };
this.selectedMonth.year = year;
this.generateCalendar(cell.nbr, year, monthChange);
this.selectMonth = false;
this.focusToSelector();
}
/**
* @param {?} event
* @return {?}
*/
onMonthCellKeyDown(event) {
// Move focus by arrow keys
const { sourceRow, sourceCol } = this.getSourceRowAndColumnFromEvent(event);
const { moveFocus, targetRow, targetCol, direction } = this.getTargetFocusRowAndColumn(event, sourceRow, sourceCol, MONTH_ROW_COUNT, MONTH_COL_COUNT);
if (moveFocus) {
this.focusCellElement(M, targetRow, targetCol, direction, MONTH_COL_COUNT);
}
}
/**
* @return {?}
*/
onYearViewBtnClicked() {
this.viewChanged = true;
this.yearViewBtnClicked();
}
/**
* @return {?}
*/
yearViewBtnClicked() {
this.selectYear = !this.selectYear;
this.selectMonth = false;
this.cdr.detectChanges();
if (this.selectYear) {
this.generateYears(this.visibleMonth.year);
}
else {
const { year, monthNbr } = this.selectedMonth;
this.visibleMonth = { monthTxt: this.opts.monthLabels[monthNbr], monthNbr, year };
this.generateCalendar(monthNbr, year, true);
}
}
/**
* @param {?} cell
* @return {?}
*/
onYearCellClicked(cell) {
this.viewChanged = true;
const { year, monthNbr, monthTxt } = this.visibleMonth;
/** @type {?} */
const yc = cell.year !== year;
this.visibleMonth = { monthTxt, monthNbr, year: cell.year };
this.selectedMonth.year = cell.year;
this.generateCalendar(monthNbr, cell.year, yc);
this.selectYear = false;
this.focusToSelector();
}
/**
* @param {?} event
* @return {?}
*/
onYearCellKeyDown(event) {
// Move focus by arrow keys
const { sourceRow, sourceCol } = this.getSourceRowAndColumnFromEvent(event);
const { moveFocus, targetRow, targetCol, direction } = this.getTargetFocusRowAndColumn(event, sourceRow, sourceCol, YEAR_ROW_COUNT, YEAR_COL_COUNT);
if (moveFocus) {
this.focusCellElement(Y, targetRow, targetCol, direction, YEAR_COL_COUNT);
}
}
/**
* @return {?}
*/
generateMonths() {
/** @type {?} */
const today = this.utilService.getToday();
this.months.length = 0;
const { year, monthNbr } = this.visibleMonth;
const { rtl, monthLabels } = this.opts;
/** @type {?} */
let row = 0;
for (let i = 1; i <= 12; i += 3) {
/** @type {?} */
const rowData = [];
/** @type {?} */
let col = rtl ? 2 : 0;
for (let j = i; j < i + 3; j++) {
/** @type {?} */
const disabled = this.utilService.isDisabledMonth(year, j, this.opts);
rowData.push({
nbr: j,
year,
name: monthLabels[j],
currMonth: j === today.month && year === today.year,
selected: j === monthNbr && year === this.selectedMonth.year,
disabled,
row,
col: rtl ? col-- : col++
});
}
row++;
this.months.push(rowData);
}
this.setMonthViewHeaderBtnDisabledState(year);
}
/**
* @param {?} inputYear
* @return {?}
*/
generateYears(inputYear) {
const { minYear, maxYear, rtl } = this.opts;
/** @type {?} */
let y = inputYear - 12;
if (inputYear < minYear) {
y = minYear;
}
if (inputYear + 25 > maxYear) {
y = maxYear - 24;
}
const { year } = this.visibleMonth;
this.years.length = 0;
/** @type {?} */
const today = this.utilService.getToday();
/** @type {?} */
let row = 0;
for (let i = y; i < y + 25; i += 5) {
/** @type {?} */
const rowData = [];
/** @type {?} */
let col = rtl ? 4 : 0;
for (let j = i; j < i + 5; j++) {
/** @type {?} */
const disabled = this.utilService.isDisabledYear(j, this.opts);
rowData.push({
year: j,
currYear: j === today.year,
selected: j === year,
disabled,
row,
col: rtl ? col-- : col++
});
}
row++;
this.years.push(rowData);
}
/** @type {?} */
const beginYear = this.getYearValueByRowAndCol(0, 0);
/** @type {?} */
const endYear = beginYear + 24;
this.yearsDuration = (!rtl ? beginYear : endYear) + YEAR_SEPARATOR + (!rtl ? endYear : beginYear);
this.setYearViewHeaderBtnDisabledState(beginYear, endYear);
}
/**
* @return {?}
*/
onTodayFooterClicked() {
/** @type {?} */
const date = this.utilService.getToday();
this.selectDate(date);
}
/**
* @param {?} row
* @param {?} col
* @return {?}
*/
getYearValueByRowAndCol(row, col) {
const { years } = this;
if (!years || years.length === 0) {
const { year } = this.utilService.getToday();
return year;
}
return years[row][col].year;
}
/**
* @return {?}
*/
setCalendarVisibleMonth() {
// Sets visible month of calendar
const { year, monthNbr } = this.selectedMonth;
this.visibleMonth = { monthTxt: this.opts.monthLabels[monthNbr], monthNbr, year };
// Create current month
this.generateCalendar(monthNbr, year, true);
}
/**
* @param {?} event
* @return {?}
*/
onViewActivated(event) {
this.viewActivated(event);
}
/**
* @return {?}
*/
onPrevNavigateBtnClicked() {
if (!this.selectMonth && !this.selectYear) {
this.setDateViewMonth(false);
}
else if (this.selectMonth) {
this.visibleMonth.year--;
this.generateMonths();
}
else if (this.selectYear) {
this.generateYears(this.getYearValueByRowAndCol(2, 2) - 25);
}
}
/**
* @return {?}
*/
onNextNavigateBtnClicked() {
if (!this.selectMonth && !this.selectYear) {
this.setDateViewMonth(true);
}
else if (this.selectMonth) {
this.visibleMonth.year++;
this.generateMonths();
}
else if (this.selectYear) {
this.generateYears(this.getYearValueByRowAndCol(2, 2) + 25);
}
}
/**
* @param {?} isNext
* @return {?}
*/
setDateViewMonth(isNext) {
/** @type {?} */
let change = isNext ? 1 : -1;
const { year, monthNbr } = this.visibleMonth;
/** @type {?} */
const d = this.utilService.getJsDate(year, monthNbr, 1);
d.setMonth(d.getMonth() + change);
/** @type {?} */
const y = d.getFullYear();
/** @type {?} */
const m = d.getMonth() + 1;
this.visibleMonth = { monthTxt: this.opts.monthLabels[m], monthNbr: m, year: y };
this.generateCalendar(m, y, true);
}
/**
* @param {?} event
* @return {?}
*/
onCloseSelector(event) {
/** @type {?} */
const keyCode = this.utilService.getKeyCodeFromEvent(event);
if (keyCode === KeyCode.esc) {
this.