@syncfusion/ej2-calendars
Version:
A complete package of date or time components with built-in features such as date formatting, inline editing, multiple (range) selection, range restriction, month and year selection, strict mode, and globalization.
1,088 lines (1,087 loc) • 684 kB
JavaScript
import { Component, Internationalization, isNullOrUndefined, Browser, attributes, closest, addClass, removeClass, rippleEffect, EventHandler, getValue, getDefaultDateObject, cldrData, detach, L10n, extend, KeyboardEvents, getUniqueID, Property, Event, NotifyPropertyChanges, throwError, HijriParser, Touch, formatUnit, Animation, setValue, ChildProperty, merge, isUndefined, createElement, select, remove, prepend, Collection, append, setStyleAttribute } from '@syncfusion/ej2-base';
import { Popup } from '@syncfusion/ej2-popups';
import { Input } from '@syncfusion/ej2-inputs';
import { Button } from '@syncfusion/ej2-buttons';
import { ListBase } from '@syncfusion/ej2-lists';
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
//class constant defination.
const OTHERMONTH = 'e-other-month';
const OTHERDECADE = 'e-other-year';
const ROOT = 'e-calendar';
const DEVICE = 'e-device';
const HEADER = 'e-header';
const RTL = 'e-rtl';
const CONTENT = 'e-content';
const CONTENTTABLE = 'e-calendar-content-table';
const YEAR = 'e-year';
const MONTH = 'e-month';
const DECADE = 'e-decade';
const ICON = 'e-icons';
const PREVICON = 'e-prev';
const NEXTICON = 'e-next';
const PREVSPAN = 'e-date-icon-prev';
const NEXTSPAN = 'e-date-icon-next ';
const ICONCONTAINER = 'e-icon-container';
const DISABLED = 'e-disabled';
const OVERLAY = 'e-overlay';
const WEEKEND = 'e-weekend';
const WEEKNUMBER = 'e-week-number';
const SELECTED = 'e-selected';
const FOCUSEDDATE = 'e-focused-date';
const FOCUSEDCELL = 'e-focused-cell';
const OTHERMONTHROW = 'e-month-hide';
const TODAY = 'e-today';
const TITLE = 'e-title';
const LINK = 'e-day';
const CELL = 'e-cell';
const WEEKHEADER = 'e-week-header';
const ZOOMIN = 'e-zoomin';
const FOOTER = 'e-footer-container';
const BTN = 'e-btn';
const FLAT = 'e-flat';
const CSS = 'e-css';
const PRIMARY = 'e-primary';
const DAYHEADERLONG = 'e-calendar-day-header-lg';
const dayMilliSeconds = 86400000;
const minutesMilliSeconds = 60000;
/**
*
* @private
*/
let CalendarBase = class CalendarBase extends Component {
/**
* Initialized new instance of Calendar Class.
* Constructor for creating the widget
*
* @param {CalendarBaseModel} options - Specifies the CalendarBase model.
* @param {string | HTMLElement} element - Specifies the element to render as component.
* @private
*/
constructor(options, element) {
super(options, element);
this.effect = '';
this.isPopupClicked = false;
this.isDateSelected = true;
this.isTodayClicked = false;
this.preventChange = false;
this.previousDates = false;
}
/**
* To Initialize the control rendering.
*
* @returns {void}
* @private
*/
render() {
this.rangeValidation(this.min, this.max);
this.calendarEleCopy = this.element.cloneNode(true);
if (this.calendarMode === 'Islamic') {
if (+(this.min.setSeconds(0)) === +new Date(1900, 0, 1, 0, 0, 0)) {
this.min = new Date(1944, 2, 18);
}
if (+this.max === +new Date(2099, 11, 31)) {
this.max = new Date(2069, 10, 16);
}
}
this.globalize = new Internationalization(this.locale);
if (isNullOrUndefined(this.firstDayOfWeek) || this.firstDayOfWeek > 6 || this.firstDayOfWeek < 0) {
this.setProperties({ firstDayOfWeek: this.globalize.getFirstDayOfWeek() }, true);
}
this.todayDisabled = false;
this.todayDate = new Date(new Date().setHours(0, 0, 0, 0));
if (this.getModuleName() === 'calendar') {
this.element.classList.add(ROOT);
if (this.enableRtl) {
this.element.classList.add(RTL);
}
if (Browser.isDevice) {
this.element.classList.add(DEVICE);
}
attributes(this.element, {
'data-role': 'calendar'
});
this.tabIndex = this.element.hasAttribute('tabindex') ? this.element.getAttribute('tabindex') : '0';
this.element.setAttribute('tabindex', this.tabIndex);
}
else {
this.calendarElement = this.createElement('div');
this.calendarElement.classList.add(ROOT);
if (this.enableRtl) {
this.calendarElement.classList.add(RTL);
}
if (Browser.isDevice) {
this.calendarElement.classList.add(DEVICE);
}
attributes(this.calendarElement, {
'data-role': 'calendar'
});
}
if (!isNullOrUndefined(closest(this.element, 'fieldset')) && closest(this.element, 'fieldset').disabled) {
this.enabled = false;
}
this.createHeader();
this.createContent();
this.wireEvents();
}
rangeValidation(min, max) {
if (isNullOrUndefined(min)) {
this.setProperties({ min: new Date(1900, 0, 1) }, true);
}
if (isNullOrUndefined(max)) {
this.setProperties({ max: new Date(2099, 11, 31) }, true);
}
}
getDefaultKeyConfig() {
this.defaultKeyConfigs = {
controlUp: 'ctrl+38',
controlDown: 'ctrl+40',
moveDown: 'downarrow',
moveUp: 'uparrow',
moveLeft: 'leftarrow',
moveRight: 'rightarrow',
select: 'enter',
home: 'home',
end: 'end',
pageUp: 'pageup',
pageDown: 'pagedown',
shiftPageUp: 'shift+pageup',
shiftPageDown: 'shift+pagedown',
controlHome: 'ctrl+home',
controlEnd: 'ctrl+end',
altUpArrow: 'alt+uparrow',
spacebar: 'space',
altRightArrow: 'alt+rightarrow',
altLeftArrow: 'alt+leftarrow'
};
return this.defaultKeyConfigs;
}
validateDate(value) {
this.setProperties({ min: this.checkDateValue(new Date(this.checkValue(this.min))) }, true);
this.setProperties({ max: this.checkDateValue(new Date(this.checkValue(this.max))) }, true);
this.currentDate = this.currentDate ? this.currentDate : new Date(new Date().setHours(0, 0, 0, 0));
if (!isNullOrUndefined(value) && this.min <= this.max && value >= this.min && value <= this.max) {
this.currentDate = new Date(this.checkValue(value));
}
}
setOverlayIndex(popupWrapper, popupElement, modal, isDevice) {
if (isDevice && !isNullOrUndefined(popupElement) && !isNullOrUndefined(modal) && !isNullOrUndefined(popupWrapper)) {
const index = parseInt(popupElement.style.zIndex, 10) ? parseInt(popupElement.style.zIndex, 10) : 1000;
modal.style.zIndex = (index - 1).toString();
popupWrapper.style.zIndex = index.toString();
}
}
minMaxUpdate(value) {
if (!(+this.min <= +this.max)) {
this.setProperties({ min: this.min }, true);
addClass([this.element], OVERLAY);
}
else {
removeClass([this.element], OVERLAY);
}
this.min = isNullOrUndefined(this.min) || !(+this.min) ? this.min = new Date(1900, 0, 1) : this.min;
this.max = isNullOrUndefined(this.max) || !(+this.max) ? this.max = new Date(2099, 11, 31) : this.max;
if (+this.min <= +this.max && value && +value <= +this.max && +value >= +this.min) {
this.currentDate = new Date(this.checkValue(value));
}
else {
if (+this.min <= +this.max && !value && +this.currentDate > +this.max) {
this.currentDate = new Date(this.checkValue(this.max));
}
else {
if (+this.currentDate < +this.min) {
this.currentDate = new Date(this.checkValue(this.min));
}
}
}
}
createHeader() {
const ariaPrevAttrs = {
'aria-disabled': 'false',
'aria-label': 'previous month'
};
const ariaNextAttrs = {
'aria-disabled': 'false',
'aria-label': 'next month'
};
const ariaTitleAttrs = {
'aria-atomic': 'true', 'aria-live': 'assertive', 'aria-label': 'title'
};
const tabIndexAttr = { 'tabindex': '0' };
this.headerElement = this.createElement('div', { className: HEADER });
const iconContainer = this.createElement('div', { className: ICONCONTAINER });
this.previousIcon = this.createElement('button', { className: '' + PREVICON, attrs: { type: 'button' } });
rippleEffect(this.previousIcon, {
duration: 400,
selector: '.e-prev',
isCenterRipple: true
});
attributes(this.previousIcon, ariaPrevAttrs);
attributes(this.previousIcon, tabIndexAttr);
this.nextIcon = this.createElement('button', { className: '' + NEXTICON, attrs: { type: 'button' } });
rippleEffect(this.nextIcon, {
selector: '.e-next',
duration: 400,
isCenterRipple: true
});
if (this.getModuleName() === 'daterangepicker') {
attributes(this.previousIcon, { tabIndex: '-1' });
attributes(this.nextIcon, { tabIndex: '-1' });
}
attributes(this.nextIcon, ariaNextAttrs);
attributes(this.nextIcon, tabIndexAttr);
this.headerTitleElement = this.createElement('div', { className: '' + LINK + ' ' + TITLE });
attributes(this.headerTitleElement, ariaTitleAttrs);
attributes(this.headerTitleElement, tabIndexAttr);
this.headerElement.appendChild(this.headerTitleElement);
this.previousIcon.appendChild(this.createElement('span', { className: '' + PREVSPAN + ' ' + ICON }));
this.nextIcon.appendChild(this.createElement('span', { className: '' + NEXTSPAN + ' ' + ICON }));
iconContainer.appendChild(this.previousIcon);
iconContainer.appendChild(this.nextIcon);
this.headerElement.appendChild(iconContainer);
if (this.getModuleName() === 'calendar') {
this.element.appendChild(this.headerElement);
}
else {
this.calendarElement.appendChild(this.headerElement);
}
this.adjustLongHeaderSize();
}
createContent() {
this.contentElement = this.createElement('div', { className: CONTENT });
this.table = this.createElement('table', { attrs: { 'class': CONTENTTABLE, 'tabIndex': '0', 'role': 'grid', 'aria-activedescendant': '', 'aria-labelledby': this.element.id } });
if (this.getModuleName() === 'calendar') {
this.element.appendChild(this.contentElement);
}
else {
this.calendarElement.appendChild(this.contentElement);
}
this.contentElement.appendChild(this.table);
this.createContentHeader();
this.createContentBody();
if (this.showTodayButton) {
this.createContentFooter();
}
if (this.getModuleName() !== 'daterangepicker') {
EventHandler.add(this.table, 'focus', this.addContentFocus, this);
EventHandler.add(this.table, 'blur', this.removeContentFocus, this);
}
}
addContentFocus(args) {
const focusedDate = this.tableBodyElement.querySelector('tr td.e-focused-date');
const selectedDate = this.tableBodyElement.querySelector('tr td.e-selected');
if (!isNullOrUndefined(selectedDate)) {
selectedDate.classList.add(FOCUSEDCELL);
}
else if (!isNullOrUndefined(focusedDate)) {
focusedDate.classList.add(FOCUSEDCELL);
}
}
removeContentFocus(args) {
const focusedDate = !isNullOrUndefined(this.tableBodyElement) ? this.tableBodyElement.querySelector('tr td.e-focused-date') : null;
const selectedDate = !isNullOrUndefined(this.tableBodyElement) ? this.tableBodyElement.querySelector('tr td.e-selected') : null;
if (!isNullOrUndefined(selectedDate)) {
selectedDate.classList.remove(FOCUSEDCELL);
}
else if (!isNullOrUndefined(focusedDate)) {
focusedDate.classList.remove(FOCUSEDCELL);
}
}
getCultureValues() {
const culShortNames = [];
let cldrObj;
const dayFormat = !isNullOrUndefined(this.dayHeaderFormat) ? 'days.stand-alone.' + this.dayHeaderFormat.toLowerCase() : null;
if ((this.locale === 'en' || this.locale === 'en-US') && !isNullOrUndefined(dayFormat)) {
cldrObj = (getValue(dayFormat, getDefaultDateObject()));
}
else {
cldrObj = (this.getCultureObjects(cldrData, '' + this.locale));
}
if (!isNullOrUndefined(cldrObj)) {
for (const obj of Object.keys(cldrObj)) {
culShortNames.push(getValue(obj, cldrObj));
}
}
return culShortNames;
}
toCapitalize(text) {
return !isNullOrUndefined(text) && text.length ? text[0].toUpperCase() + text.slice(1) : text;
}
createContentHeader() {
if (this.getModuleName() === 'calendar') {
if (!isNullOrUndefined(this.element.querySelectorAll('.e-content .e-week-header')[0])) {
detach(this.element.querySelectorAll('.e-content .e-week-header')[0]);
}
}
else {
if (!isNullOrUndefined(this.calendarElement.querySelectorAll('.e-content .e-week-header')[0])) {
detach(this.calendarElement.querySelectorAll('.e-content .e-week-header')[0]);
}
}
const daysCount = 6;
let html = '';
if (this.firstDayOfWeek > 6 || this.firstDayOfWeek < 0) {
this.setProperties({ firstDayOfWeek: 0 }, true);
}
this.tableHeadElement = this.createElement('thead', { className: WEEKHEADER });
if (this.weekNumber) {
html += '<th class="e-week-number" aria-hidden="true"></th>';
if (this.getModuleName() === 'calendar') {
addClass([this.element], '' + WEEKNUMBER);
}
else {
addClass([this.calendarElement], '' + WEEKNUMBER);
}
}
const shortNames = this.getCultureValues().length > 0 &&
this.getCultureValues() ? this.shiftArray(((this.getCultureValues().length > 0 &&
this.getCultureValues())), this.firstDayOfWeek) : null;
if (!isNullOrUndefined(shortNames)) {
for (let days = 0; days <= daysCount; days++) {
html += '<th class="">' + this.toCapitalize(shortNames[days]) + '</th>';
}
}
html = '<tr>' + html + '</tr>';
this.tableHeadElement.innerHTML = html;
this.table.appendChild(this.tableHeadElement);
}
createContentBody() {
if (this.getModuleName() === 'calendar') {
if (!isNullOrUndefined(this.element.querySelectorAll('.e-content tbody')[0])) {
detach(this.element.querySelectorAll('.e-content tbody')[0]);
}
}
else {
if (!isNullOrUndefined(this.calendarElement.querySelectorAll('.e-content tbody')[0])) {
detach(this.calendarElement.querySelectorAll('.e-content tbody')[0]);
}
}
switch (this.start) {
case 'Year':
this.renderYears();
break;
case 'Decade':
this.renderDecades();
break;
default:
this.renderMonths();
}
}
updateFooter() {
this.todayElement.textContent = this.l10.getConstant('today');
this.todayElement.setAttribute('aria-label', this.l10.getConstant('today'));
this.todayElement.setAttribute('tabindex', '0');
}
createContentFooter() {
if (this.showTodayButton) {
const minimum = new Date(+this.min);
const maximum = new Date(+this.max);
const l10nLocale = { today: 'Today' };
this.globalize = new Internationalization(this.locale);
this.l10 = new L10n(this.getModuleName(), l10nLocale, this.locale);
this.todayElement = this.createElement('button', { attrs: { role: 'button' } });
rippleEffect(this.todayElement);
this.updateFooter();
addClass([this.todayElement], [BTN, TODAY, FLAT, PRIMARY, CSS]);
if ((!(+new Date(minimum.setHours(0, 0, 0, 0)) <= +this.todayDate &&
+this.todayDate <= +new Date(maximum.setHours(0, 0, 0, 0)))) || (this.todayDisabled)) {
addClass([this.todayElement], DISABLED);
}
this.footer = this.createElement('div', { className: FOOTER });
this.footer.appendChild(this.todayElement);
if (this.getModuleName() === 'calendar') {
this.element.appendChild(this.footer);
}
if (this.getModuleName() === 'datepicker') {
this.calendarElement.appendChild(this.footer);
}
if (this.getModuleName() === 'datetimepicker') {
this.calendarElement.appendChild(this.footer);
}
if (!this.todayElement.classList.contains(DISABLED)) {
EventHandler.add(this.todayElement, 'click', this.todayButtonClick, this);
}
}
}
wireEvents(id, ref, keyConfig, moduleName) {
EventHandler.add(this.headerTitleElement, 'click', this.navigateTitle, this);
this.defaultKeyConfigs = extend(this.defaultKeyConfigs, this.keyConfigs);
if (this.getModuleName() === 'calendar') {
this.keyboardModule = new KeyboardEvents(this.element, {
eventName: 'keydown',
keyAction: this.keyActionHandle.bind(this),
keyConfigs: this.defaultKeyConfigs
});
}
else {
this.keyboardModule = new KeyboardEvents(this.calendarElement, {
eventName: 'keydown',
keyAction: this.keyActionHandle.bind(this),
keyConfigs: this.defaultKeyConfigs
});
}
}
dateWireEvents(id, ref, keyConfig, moduleName) {
this.defaultKeyConfigs = this.getDefaultKeyConfig();
this.defaultKeyConfigs = extend(this.defaultKeyConfigs, keyConfig);
this.serverModuleName = moduleName;
}
todayButtonClick(e, value, isCustomDate) {
if (this.showTodayButton) {
if (this.currentView() === this.depth) {
this.effect = '';
}
else {
this.effect = 'e-zoomin';
}
if (this.getViewNumber(this.start) >= this.getViewNumber(this.depth)) {
this.navigateTo(this.depth, new Date(this.checkValue(value)), isCustomDate);
}
else {
this.navigateTo('Month', new Date(this.checkValue(value)), isCustomDate);
}
}
}
resetCalendar() {
this.calendarElement && detach(this.calendarElement);
this.tableBodyElement && detach(this.tableBodyElement);
this.table && detach(this.table);
this.tableHeadElement && detach(this.tableHeadElement);
this.nextIcon && detach(this.nextIcon);
this.previousIcon && detach(this.previousIcon);
this.footer && detach(this.footer);
this.todayElement = null;
this.renderDayCellArgs = null;
this.calendarElement = this.tableBodyElement = this.footer = this.tableHeadElement =
this.nextIcon = this.previousIcon = this.table = null;
}
keyActionHandle(e, value, multiSelection) {
if (this.calendarElement === null && e.action === 'escape') {
return;
}
const focusedDate = this.tableBodyElement.querySelector('tr td.e-focused-date');
let selectedDate;
if (multiSelection) {
if (!isNullOrUndefined(focusedDate) && +value === parseInt(focusedDate.getAttribute('id').split('_')[0], 10)) {
selectedDate = focusedDate;
}
else {
selectedDate = this.tableBodyElement.querySelector('tr td.e-selected');
}
}
else {
selectedDate = this.tableBodyElement.querySelector('tr td.e-selected');
}
let view = this.getViewNumber(this.currentView());
const depthValue = this.getViewNumber(this.depth);
const levelRestrict = (view === depthValue && this.getViewNumber(this.start) >= depthValue);
this.effect = '';
switch (e.action) {
case 'moveLeft':
if (this.getModuleName() !== 'daterangepicker' && !isNullOrUndefined(e.target)) {
this.keyboardNavigate(-1, view, e, this.max, this.min);
e.preventDefault();
}
break;
case 'moveRight':
if (this.getModuleName() !== 'daterangepicker' && !isNullOrUndefined(e.target)) {
this.keyboardNavigate(1, view, e, this.max, this.min);
e.preventDefault();
}
break;
case 'moveUp':
if (this.getModuleName() !== 'daterangepicker' && !isNullOrUndefined(e.target)) {
if (view === 0) {
this.keyboardNavigate(-7, view, e, this.max, this.min); // move the current date to the previous seven days.
}
else {
this.keyboardNavigate(-4, view, e, this.max, this.min); // move the current year to the previous four days.
}
e.preventDefault();
}
break;
case 'moveDown':
if (this.getModuleName() !== 'daterangepicker' && !isNullOrUndefined(e.target)) {
if (view === 0) {
this.keyboardNavigate(7, view, e, this.max, this.min);
}
else {
this.keyboardNavigate(4, view, e, this.max, this.min);
}
e.preventDefault();
}
break;
case 'select':
if (e.target === this.headerTitleElement) {
this.navigateTitle(e);
}
else if (e.target === this.previousIcon && !e.target.className.includes(DISABLED)) {
this.navigatePrevious(e);
}
else if (e.target === this.nextIcon && !e.target.className.includes(DISABLED)) {
this.navigateNext(e);
}
else if (e.target === this.todayElement && !e.target.className.includes(DISABLED)) {
this.todayButtonClick(e, value);
if (this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') {
if (this.isAngular) {
this.inputElement.focus();
}
else {
this.element.focus();
}
}
}
else {
const element = !isNullOrUndefined(focusedDate) ? focusedDate : selectedDate;
if (!isNullOrUndefined(element) && !element.classList.contains(DISABLED)) {
if (levelRestrict) {
// eslint-disable-next-line radix
const d = new Date(parseInt('' + (element).id, 0));
this.selectDate(e, d, (element));
if (this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') {
if (this.isAngular) {
this.inputElement.focus();
}
else {
this.element.focus();
}
}
}
else {
if (!e.target.className.includes(DISABLED)) {
this.contentClick(null, --view, (element), value);
}
}
}
}
break;
case 'controlUp':
this.title();
e.preventDefault();
break;
case 'controlDown':
if (!isNullOrUndefined(focusedDate) && !levelRestrict || !isNullOrUndefined(selectedDate) && !levelRestrict) {
this.contentClick(null, --view, (focusedDate || selectedDate), value);
}
e.preventDefault();
break;
case 'home':
this.currentDate = this.firstDay(this.currentDate);
detach(this.tableBodyElement);
if (view === 0) {
this.renderMonths(e);
}
else if (view === 1) {
this.renderYears(e);
}
else {
this.renderDecades(e);
}
e.preventDefault();
break;
case 'end':
this.currentDate = this.lastDay(this.currentDate, view);
detach(this.tableBodyElement);
if (view === 0) {
this.renderMonths(e);
}
else if (view === 1) {
this.renderYears(e);
}
else {
this.renderDecades(e);
}
e.preventDefault();
break;
case 'pageUp':
this.addMonths(this.currentDate, -1);
this.navigateTo('Month', this.currentDate);
e.preventDefault();
break;
case 'pageDown':
this.addMonths(this.currentDate, 1);
this.navigateTo('Month', this.currentDate);
e.preventDefault();
break;
case 'shiftPageUp':
this.addYears(this.currentDate, -1);
this.navigateTo('Month', this.currentDate);
e.preventDefault();
break;
case 'shiftPageDown':
this.addYears(this.currentDate, 1);
this.navigateTo('Month', this.currentDate);
e.preventDefault();
break;
case 'controlHome':
this.navigateTo('Month', new Date(this.currentDate.getFullYear(), 0, 1));
e.preventDefault();
break;
case 'controlEnd':
this.navigateTo('Month', new Date(this.currentDate.getFullYear(), 11, 31));
e.preventDefault();
break;
case 'tab':
if ((this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') && e.target === this.todayElement) {
e.preventDefault();
if (this.isAngular) {
this.inputElement.focus();
}
else {
this.element.focus();
}
this.hide();
}
break;
case 'shiftTab':
if ((this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') && e.target === this.headerTitleElement) {
e.preventDefault();
if (this.isAngular) {
this.inputElement.focus();
}
else {
this.element.focus();
}
this.hide();
}
break;
case 'escape':
if ((this.getModuleName() === 'datepicker' || this.getModuleName() === 'datetimepicker') && (e.target === this.headerTitleElement || e.target === this.previousIcon || e.target === this.nextIcon || e.target === this.todayElement)) {
this.hide();
}
break;
}
}
keyboardNavigate(number, currentView, e, max, min) {
const date = new Date(this.checkValue(this.currentDate));
switch (currentView) {
case 2:
this.addYears(this.currentDate, number);
if (this.isMonthYearRange(this.currentDate)) {
detach(this.tableBodyElement);
this.renderDecades(e);
}
else {
this.currentDate = date;
}
break;
case 1:
this.addMonths(this.currentDate, number);
if (this.calendarMode === 'Gregorian') {
if (this.isMonthYearRange(this.currentDate)) {
detach(this.tableBodyElement);
this.renderYears(e);
}
else {
this.currentDate = date;
}
}
else {
if (this.isMonthYearRange(this.currentDate)) {
detach(this.tableBodyElement);
this.renderYears(e);
}
else {
this.currentDate = date;
}
}
break;
case 0:
this.addDay(this.currentDate, number, e, max, min);
if (this.isMinMaxRange(this.currentDate)) {
detach(this.tableBodyElement);
this.renderMonths(e);
}
else {
this.currentDate = date;
}
break;
}
}
/**
* Initialize the event handler
*
* @param {Date} value - Specifies value of date.
* @returns {void}
* @private
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
preRender(value) {
this.navigatePreviousHandler = this.navigatePrevious.bind(this);
this.navigateNextHandler = this.navigateNext.bind(this);
this.defaultKeyConfigs = this.getDefaultKeyConfig();
this.navigateHandler = (e) => {
this.triggerNavigate(e);
};
}
minMaxDate(localDate) {
const currentDate = new Date(new Date(+localDate).setHours(0, 0, 0, 0));
const minDate = new Date(new Date(+this.min).setHours(0, 0, 0, 0));
const maxDate = new Date(new Date(+this.max).setHours(0, 0, 0, 0));
if (+currentDate === +minDate || +currentDate === +maxDate) {
if (+localDate < +this.min) {
localDate = new Date(+this.min);
}
if (+localDate > +this.max) {
localDate = new Date(+this.max);
}
}
return localDate;
}
renderMonths(e, value, isCustomDate) {
const numCells = this.weekNumber ? 8 : 7;
let tdEles;
if (this.calendarMode === 'Gregorian') {
tdEles = this.renderDays(this.currentDate, value, null, null, isCustomDate, e);
}
else {
tdEles = !isNullOrUndefined(this.islamicModule) ? this.islamicModule.islamicRenderDays(this.currentDate, value) : null;
}
this.createContentHeader();
if (this.calendarMode === 'Gregorian') {
this.renderTemplate(tdEles, numCells, MONTH, e, value);
}
else if (!isNullOrUndefined(this.islamicModule)) {
this.islamicModule.islamicRenderTemplate(tdEles, numCells, MONTH, e, value);
}
}
renderDays(currentDate, value, multiSelection, values, isTodayDate, e) {
const tdEles = [];
const cellsCount = 42;
const todayDate = isTodayDate ? new Date(+currentDate) : this.getDate(new Date(), this.timezone);
let localDate = new Date(this.checkValue(currentDate));
let minMaxDate;
const currentMonth = localDate.getMonth();
this.titleUpdate(currentDate, 'days');
const d = localDate;
localDate = new Date(d.getFullYear(), d.getMonth(), 0, d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
while (localDate.getDay() !== this.firstDayOfWeek) {
this.setStartDate(localDate, -1 * dayMilliSeconds);
}
for (let day = 0; day < cellsCount; ++day) {
const weekEle = this.createElement('td', { className: CELL });
const weekAnchor = this.createElement('span');
if (day % 7 === 0 && this.weekNumber) {
// 6 days are added to get Last day of the week and 3 days are added to get middle day of the week.
const numberOfDays = this.weekRule === 'FirstDay' ? 6 : (this.weekRule === 'FirstFourDayWeek' ? 3 : 0);
const finalDate = new Date(localDate.getFullYear(), localDate.getMonth(), (localDate.getDate() + numberOfDays));
weekAnchor.textContent = '' + this.getWeek(finalDate);
weekEle.appendChild(weekAnchor);
addClass([weekEle], '' + WEEKNUMBER);
tdEles.push(weekEle);
}
minMaxDate = new Date(+localDate);
localDate = this.minMaxDate(localDate);
const dateFormatOptions = { type: 'dateTime', skeleton: 'full' };
const date = this.globalize.parseDate(this.globalize.formatDate(localDate, dateFormatOptions), dateFormatOptions);
const tdEle = this.dayCell(localDate);
const title = this.globalize.formatDate(localDate, { type: 'date', skeleton: 'full' });
const dayLink = this.createElement('span');
dayLink.textContent = this.globalize.formatDate(localDate, { format: 'd', type: 'date', skeleton: 'yMd' });
const disabled = (this.min > localDate) || (this.max < localDate);
if (disabled) {
addClass([tdEle], DISABLED);
addClass([tdEle], OVERLAY);
}
else {
dayLink.setAttribute('title', '' + title);
}
if (currentMonth !== localDate.getMonth()) {
addClass([tdEle], OTHERMONTH);
dayLink.setAttribute('aria-disabled', 'true');
}
if (localDate.getDay() === 0 || localDate.getDay() === 6) {
addClass([tdEle], WEEKEND);
}
tdEle.appendChild(dayLink);
this.renderDayCellArgs = {
date: localDate,
isDisabled: false,
element: tdEle,
isOutOfRange: disabled
};
const argument = this.renderDayCellArgs;
this.renderDayCellEvent(argument);
if (argument.isDisabled) {
const selectDate = new Date(this.checkValue(value));
const argsDate = new Date(this.checkValue(argument.date));
if (multiSelection) {
if (!isNullOrUndefined(values) && values.length > 0) {
for (let index = 0; index < values.length; index++) {
const localDateString = +new Date(this.globalize.formatDate(argument.date, { type: 'date', skeleton: 'yMd' }));
const tempDateString = +new Date(this.globalize.formatDate(values[index], { type: 'date', skeleton: 'yMd' }));
if (localDateString === tempDateString) {
values.splice(index, 1);
index = -1;
}
}
}
}
else if (selectDate && +selectDate === +argsDate) {
this.setProperties({ value: null }, true);
}
}
if (this.renderDayCellArgs.isDisabled && !tdEle.classList.contains(SELECTED)) {
addClass([tdEle], DISABLED);
addClass([tdEle], OVERLAY);
dayLink.setAttribute('aria-disabled', 'true');
if (+this.renderDayCellArgs.date === +this.todayDate) {
this.todayDisabled = true;
}
}
const otherMnthBool = tdEle.classList.contains(OTHERMONTH);
const disabledCls = tdEle.classList.contains(DISABLED);
if (!disabledCls) {
EventHandler.add(tdEle, 'click', this.clickHandler, this);
}
// to set the value as null while setting the disabled date onProperty change.
// if (args.isDisabled && +this.value === +args.date) {
// this.setProperties({ value: null }, true);
// }
let currentTarget;
if (!isNullOrUndefined(e) && e.type === 'click') {
currentTarget = e.currentTarget;
}
if (multiSelection && !isNullOrUndefined(values) && !disabledCls) {
for (let tempValue = 0; tempValue < values.length; tempValue++) {
const type = (this.calendarMode === 'Gregorian') ? 'gregorian' : 'islamic';
const formatOptions = { format: null, type: 'date', skeleton: 'short', calendar: type };
const localDateString = this.globalize.formatDate(localDate, formatOptions);
const tempDateString = this.globalize.formatDate(values[tempValue], formatOptions);
if ((localDateString === tempDateString && this.getDateVal(localDate, values[tempValue]))
|| (this.getDateVal(localDate, value))) {
addClass([tdEle], SELECTED);
}
if (!isNullOrUndefined(currentTarget) && currentTarget.innerText === tdEle.innerText &&
this.previousDates && tdEle.classList.contains(SELECTED) && currentTarget.classList.contains(SELECTED)) {
removeClass([tdEle], SELECTED);
this.previousDates = false;
const copyValues = this.copyValues(values);
for (let i = 0; i < copyValues.length; i++) {
const type = (this.calendarMode === 'Gregorian') ? 'gregorian' : 'islamic';
const formatOptions = { format: null, type: 'date', skeleton: 'short', calendar: type };
const localDateString = this.globalize.formatDate(date, formatOptions);
const tempDateString = this.globalize.formatDate(copyValues[i], formatOptions);
if (localDateString === tempDateString) {
const index = copyValues.indexOf(copyValues[i]);
copyValues.splice(index, 1);
values.splice(index, 1);
}
}
this.setProperties({ values: copyValues }, true);
}
else {
this.updateFocus(otherMnthBool, disabledCls, localDate, tdEle, currentDate);
}
}
if (values.length <= 0) {
this.updateFocus(otherMnthBool, disabledCls, localDate, tdEle, currentDate);
}
}
else if (!disabledCls && this.getDateVal(localDate, value)) {
addClass([tdEle], SELECTED);
}
this.updateFocus(otherMnthBool, disabledCls, localDate, tdEle, currentDate);
if (!isNullOrUndefined(date) && date.getFullYear() === todayDate.getFullYear() && date.getMonth() === todayDate.getMonth()
&& date.getDate() === todayDate.getDate()) {
addClass([tdEle], TODAY);
}
tdEles.push(this.renderDayCellArgs.element);
localDate = new Date(+minMaxDate);
this.addDay(localDate, 1, null, this.max, this.min);
}
return tdEles;
}
updateFocus(otherMonth, disabled, localDate, tableElement, currentDate) {
if (currentDate.getDate() === localDate.getDate() && !otherMonth && !disabled) {
addClass([tableElement], FOCUSEDDATE);
}
else {
// eslint-disable-next-line radix
if (currentDate >= this.max && parseInt(tableElement.id, 0) === +this.max && !otherMonth && !disabled) {
addClass([tableElement], FOCUSEDDATE);
}
// eslint-disable-next-line radix
if (currentDate <= this.min && parseInt(tableElement.id, 0) === +this.min && !otherMonth && !disabled) {
addClass([tableElement], FOCUSEDDATE);
}
}
}
renderYears(e, value) {
this.removeTableHeadElement();
const numCells = 4;
const tdEles = [];
const valueUtil = isNullOrUndefined(value);
const curDate = new Date(this.checkValue(this.currentDate));
const mon = curDate.getMonth();
const yr = curDate.getFullYear();
const localDate = curDate;
const curYrs = localDate.getFullYear();
const minYr = new Date(this.checkValue(this.min)).getFullYear();
const minMonth = new Date(this.checkValue(this.min)).getMonth();
const maxYr = new Date(this.checkValue(this.max)).getFullYear();
const maxMonth = new Date(this.checkValue(this.max)).getMonth();
localDate.setMonth(0);
this.titleUpdate(this.currentDate, 'months');
localDate.setDate(1);
for (let month = 0; month < 12; ++month) {
const tdEle = this.dayCell(localDate);
const dayLink = this.createElement('span');
const localMonth = (value && (value).getMonth() === localDate.getMonth());
const select = (value && (value).getFullYear() === yr && localMonth);
const title = this.globalize.formatDate(localDate, { type: 'date', format: 'MMM y' });
dayLink.textContent = this.toCapitalize(this.globalize.formatDate(localDate, {
format: null, type: 'dateTime', skeleton: 'MMM'
}));
if ((this.min && (curYrs < minYr || (month < minMonth && curYrs === minYr))) || (this.max && (curYrs > maxYr || (month > maxMonth && curYrs >= maxYr)))) {
addClass([tdEle], DISABLED);
}
else if (!valueUtil && select) {
addClass([tdEle], SELECTED);
}
else {
if (localDate.getMonth() === mon && this.currentDate.getMonth() === mon) {
addClass([tdEle], FOCUSEDDATE);
}
}
localDate.setDate(1);
localDate.setMonth(localDate.getMonth() + 1);
if (!tdEle.classList.contains(DISABLED)) {
EventHandler.add(tdEle, 'click', this.clickHandler, this);
dayLink.setAttribute('title', '' + title);
}
tdEle.appendChild(dayLink);
tdEles.push(tdEle);
}
this.renderTemplate(tdEles, numCells, YEAR, e, value);
}
renderDecades(e, value) {
this.removeTableHeadElement();
const numCells = 4;
const yearCell = 12;
const tdEles = [];
const localDate = new Date(this.checkValue(this.currentDate));
localDate.setMonth(0);
localDate.setDate(1);
const localYr = localDate.getFullYear();
const startYr = new Date(localDate.setFullYear((localYr - localYr % 10)));
const endYr = new Date(localDate.setFullYear((localYr - localYr % 10 + (10 - 1))));
const startFullYr = startYr.getFullYear();
const endFullYr = endYr.getFullYear();
const startHdrYr = this.globalize.formatDate(startYr, {
format: null, type: 'dateTime', skeleton: 'y'
});
const endHdrYr = this.globalize.formatDate(endYr, { format: null, type: 'dateTime', skeleton: 'y' });
this.headerTitleElement.textContent = startHdrYr + ' - ' + (endHdrYr);
const start = new Date(localYr - (localYr % 10) - 1, 0, 1);
const startYear = start.getFullYear();
for (let rowIterator = 0; rowIterator < yearCell; ++rowIterator) {
const year = startYear + rowIterator;
localDate.setFullYear(year);
const tdEle = this.dayCell(localDate);
const dayLink = this.createElement('span');
dayLink.textContent = this.globalize.formatDate(localDate, {
format: null, type: 'dateTime', skeleton: 'y'
});
if ((year < startFullYr) || (year > endFullYr)) {
addClass([tdEle], OTHERDECADE);
dayLink.setAttribute('aria-disabled', 'true');
if (!isNullOrUndefined(value) && localDate.getFullYear() === (value).getFullYear()) {
addClass([tdEle], SELECTED);
}
if (year < new Date(this.checkValue(this.min)).getFullYear() ||
year > new Date(this.checkValue(this.max)).getFullYear()) {
addClass([tdEle], DISABLED);
}
}
else if (year < new Date(this.checkValue(this.min)).getFullYear() ||
year > new Date(this.checkValue(this.max)).getFullYear()) {
addClass([tdEle], DISABLED);
}
else if (!isNullOrUndefined(value) && localDate.getFullYear() === (value).getFullYear()) {
addClass([tdEle], SELECTED);
}
else {
if (localDate.getFullYear() === this.currentDate.getFullYear() && !tdEle.classList.contains(DISABLED)) {
addClass([tdEle], FOCUSEDDATE);
}
}
if (!tdEle.classList.contains(DISABLED)) {
EventHandler.add(tdEle, 'click', this.clickHandler, this);
dayLink.setAttribute('title', '' + dayLink.textContent);
}
tdEle.appendChild(dayLink);
tdEles.push(tdEle);
}
this.renderTemplate(tdEles, numCells, 'e-decade', e, value);
}
dayCell(localDate) {
const type = (this.calendarMode === 'Gregorian') ? 'gregorian' : 'islamic';
const dateFormatOptions = { skeleton: 'full', type: 'dateTime', calendar: type };
const date = this.globalize.parseDate(this.globalize.formatDate(localDate, dateFormatOptions), dateFormatOptions);
let value;
if (!isNullOrUndefined(date)) {
value = date.valueOf();
}
const attrs = {
className: CELL, attrs: { 'id': '' + getUniqueID('' + value), 'aria-selected': 'false' }
};
return this.createElement('td', attrs);
}
firstDay(date) {
const collection = this.currentView() !== 'Decade' ? this.tableBodyElement.querySelectorAll('td:not(.' + OTHERMONTH + '):not(.' + WEEKNUMBER + ')') :
this.tableBodyElement.querySelectorAll('td' + ':not(.' + OTHERDECADE + '');
if (collection.length) {
for (let i = 0; i < collection.length; i++) {
if (!collection[i].classList.contains(DISABLED)) {
// eslint-disable-next-line radix
date = new Date(parseInt(collection[i].id, 0));
break;
}
}
}
return date;
}
lastDay(date, view) {
const lastDate = new Date(date.getFullYear(), date.getMonth() + 1, 0);
if (view !== 2) {
const timeOffset = Math.abs(lastDate.getTimezoneOffset() - this.firstDay(date).getTimezoneOffset());
if (timeOffset) {
lastDate.setHours(this.firstDay(date).getHours() + (timeOffset / 60));
}
return this.findLastDay(lastDate);
}
else {
return this.findLastDay(this.firstDay(lastDate));
}
}
checkDateValue(value) {
return (!isNullOrUndefined(value) && value instanceof Date && !isNaN(+value)) ? value : null;
}
findLastDay(date) {
const collection = this.currentView() === 'Decade' ? this.tableBodyElement.querySelectorAll('td' + ':not(.' + OTHERDECADE + '') :
this.tableBodyElement.querySelectorAll('td:not(.' + OTHERMONTH + '):not(.' + WEEKNUMBER + ')');
if (collection.length) {
for (let i = collection.length - 1; i >= 0; i--) {
if (!collection[i].classList.contains(DISABLED)) {
// eslint-disable-next-line radix
date = new Date(parseInt(collection[i].id, 0));
break;
}
}
}
return date;
}
removeTableHeadElement() {
if (this.getModuleName() === 'calendar') {
if (!isNullOrUndefined(this.element.querySelectorAll('.e-content table thead')[0])) {
detach(this.tableHeadElement);
}
}
else {
if (!isNullOrU