UNPKG

@syncfusion/ej2-schedule

Version:

Flexible scheduling library with more built-in features and enhanced customization options similar to outlook and google calendar, allowing the users to plan and manage their appointments with efficient data-binding support.

1,187 lines 141 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__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; }; /* eslint-disable @typescript-eslint/no-explicit-any */ import { Component, Property, Event, Animation, Collection, append } from '@syncfusion/ej2-base'; import { EventHandler, Browser, Internationalization, getDefaultDateObject, cldrData, L10n } from '@syncfusion/ej2-base'; import { getValue, compile, extend, isNullOrUndefined, NotifyPropertyChanges, Complex } from '@syncfusion/ej2-base'; import { getElement, removeClass, addClass, classList, remove, SanitizeHtmlHelper } from '@syncfusion/ej2-base'; import { createSpinner, hideSpinner, showSpinner } from '@syncfusion/ej2-popups'; import { HeaderRenderer } from '../renderer/header-renderer'; import { Scroll } from '../actions/scroll'; import { ScheduleTouch } from '../actions/touch'; import { KeyboardInteraction } from '../actions/keyboard'; import { Data } from '../actions/data'; import { EventBase } from '../event-renderer/event-base'; import { InlineEdit } from '../event-renderer/inline-edit'; import { QuickPopups } from '../popups/quick-popups'; import { EventTooltip } from '../popups/event-tooltip'; import { EventWindow } from '../popups/event-window'; import { Render } from '../renderer/renderer'; import { WorkHours } from '../models/work-hours'; import { TimeScale } from '../models/time-scale'; import { QuickInfoTemplates } from '../models/quick-info-templates'; import { HeaderRows } from '../models/header-rows'; import { Crud } from '../actions/crud'; import { WorkCellInteraction } from '../actions/work-cells'; import { EventSettings } from '../models/event-settings'; import { Group } from '../models/group'; import { Resources } from '../models/resources'; import { Gregorian, Islamic } from '../../common/calendar-util'; import { ResourceBase } from '../base/resource'; import { Timezone, timezoneData } from '../timezone/timezone'; import * as events from '../base/constant'; import * as cls from '../base/css-constant'; import * as util from '../base/util'; import { ToolbarItem } from '../models/toolbar'; /** * Represents the Schedule component that displays a list of events scheduled against specific date and timings, * thus helping us to plan and manage it properly. * ```html * <div id="schedule"></div> * ``` * ```typescript * <script> * var scheduleObj = new Schedule(); * scheduleObj.appendTo("#schedule"); * </script> * ``` */ var Schedule = /** @class */ (function (_super) { __extends(Schedule, _super); /** * Constructor for creating the Schedule widget * * @param {ScheduleModel} options Accepts the schedule model properties to initiate the rendering * @param {string | HTMLElement} element Accepts the DOM element reference */ function Schedule(options, element) { var _this = _super.call(this, options, element) || this; _this.adaptiveGroupIndex = 0; return _this; } /** * Core method that initializes the control rendering. * * @returns {void} * @private */ Schedule.prototype.render = function () { var addClasses = []; var removeClasses = []; addClasses.push(cls.ROOT); if (this.enableRtl) { addClasses.push(cls.RTL); } else { removeClasses.push(cls.RTL); } if (this.isAdaptive) { addClasses.push(cls.DEVICE_CLASS); } else { removeClasses.push(cls.DEVICE_CLASS); } if (this.enableAdaptiveUI) { addClasses.push(cls.ADAPTIVE_CLASS); } else { removeClasses.push(cls.ADAPTIVE_CLASS); } if (this.allowMultiDrag) { addClasses.push(cls.MULTI_DRAG); } else { removeClasses.push(cls.MULTI_DRAG); } if (this.cssClass) { var cssClass = this.cssClass.split(' '); for (var _i = 0, cssClass_1 = cssClass; _i < cssClass_1.length; _i++) { var cls_1 = cssClass_1[_i]; addClasses.push(cls_1); } } classList(this.element, addClasses, removeClasses); this.validateDate(); createSpinner({ target: this.element }); this.scrollModule = new Scroll(this); this.scrollModule.setWidth(); this.scrollModule.setHeight(); this.renderModule = new Render(this); this.eventBase = new EventBase(this); this.workCellAction = new WorkCellInteraction(this); if (this.allowKeyboardInteraction) { this.keyboardInteractionModule = new KeyboardInteraction(this); } this.inlineModule = new InlineEdit(this); this.initializeDataModule(); this.renderTableContainer(); this.activeViewOptions = this.getActiveViewOptions(); this.initializeResources(); this.wireEvents(); }; Schedule.prototype.renderTableContainer = function () { if (!this.element.querySelector('.' + cls.TABLE_CONTAINER_CLASS)) { this.element.appendChild(this.createElement('div', { className: cls.TABLE_CONTAINER_CLASS })); } }; Schedule.prototype.getEventTemplateName = function (resIndex) { var templateName = 'eventTemplate_' + resIndex; if (this.activeEventTemplates.indexOf(templateName) < 0) { this.activeEventTemplates.push(templateName); } return templateName; }; /** * Method to get element width * * @param {HTMLElement} element Accepts the DOM element * @returns {number} Returns the width of the given element * @private */ Schedule.prototype.getElementWidth = function (element) { return util.getElementWidth(element, this.uiStateValues.isTransformed); }; /** * Method to get element height * * @param {HTMLElement} element Accepts the DOM element * @returns {number} Returns the Height of the given element * @private */ Schedule.prototype.getElementHeight = function (element) { return util.getElementHeight(element, this.uiStateValues.isTransformed); }; /** * Method to get height from element * * @param {Element} element Accepts the DOM element * @param {string} elementClass Accepts the element class * @returns {number} Returns the height of the element * @private */ Schedule.prototype.getElementHeightFromClass = function (element, elementClass) { return util.getElementHeightFromClass(element, elementClass, this.uiStateValues.isTransformed); }; /** * Method to render react templates * * @param {Function} callback - Specifies the callBack method * @returns {void} * @private */ Schedule.prototype.renderTemplates = function (callback) { if (this.isReact) { this.renderReactTemplates(callback); } else if (callback) { callback(); } }; /** * Method to reset react templates * * @param {string[]} templates Accepts the template ID * @returns {void} * @private */ Schedule.prototype.resetTemplates = function (templates) { if (this.isAngular || this.isReact) { this.clearTemplate(templates); } }; /** * This method renders untrusted strings and scripts securely by sanitizing them first. * * @param {string} value - A string value representing the HTML string value to be sanitized. * @param {HTMLElement} element - An HTML element to which the sanitized or unsanitized HTML string will be assigned. * @returns {void} * @private */ Schedule.prototype.sanitize = function (value, element) { if (this.enableHtmlSanitizer) { element.innerText = SanitizeHtmlHelper.sanitize(value); } else { element.innerHTML = value; } }; Schedule.prototype.initializeResources = function (isSetModel) { if (isSetModel === void 0) { isSetModel = false; } if (this.resources.length > 0) { this.resourceBase = new ResourceBase(this); this.resourceBase.bindResourcesData(isSetModel); } else { this.resourceBase = null; this.resourceCollection = []; this.renderElements(isSetModel); } }; Schedule.prototype.destroyEditorWindow = function () { if (this.eventWindow) { this.eventWindow.destroy(); this.eventWindow = null; } this.eventWindow = new EventWindow(this); }; /** * Method to render the layout elements * * @param {boolean} isLayoutOnly Accepts the boolean value to render layout or not * @returns {void} * @private */ Schedule.prototype.renderElements = function (isLayoutOnly) { if (isLayoutOnly) { this.initializeView(this.currentView); this.eventWindow.refresh(); return; } this.destroyHeaderModule(); if (this.showHeaderBar) { this.headerModule = new HeaderRenderer(this); } this.renderTableContainer(); this.uiStateValues.isTransformed = Math.round(this.element.getBoundingClientRect().width) !== this.element.offsetWidth; if (Browser.isDevice || Browser.isTouch) { this.scheduleTouchModule = new ScheduleTouch(this); } this.initializeView(this.currentView); this.destroyPopups(); if (!this.isPrinting) { this.initializePopups(); } }; Schedule.prototype.validateDate = function (selectedDate) { if (selectedDate === void 0) { selectedDate = this.selectedDate; } // persist the selected date value var date = selectedDate instanceof Date ? new Date(selectedDate.getTime()) : new Date(selectedDate); var minDate = isNullOrUndefined(this.minDate) ? new Date(1900, 0, 1) : this.minDate instanceof Date ? new Date(this.minDate.getTime()) : new Date(this.minDate); var maxDate = isNullOrUndefined(this.maxDate) ? new Date(2099, 11, 31) : this.maxDate instanceof Date ? new Date(this.maxDate.getTime()) : new Date(this.maxDate); if (minDate <= maxDate) { if (date < minDate) { date = minDate; } if (date > maxDate) { date = maxDate; } this.setProperties({ selectedDate: new Date('' + date), minDate: new Date('' + minDate), maxDate: new Date('' + maxDate) }, true); if (this.eventWindow) { this.eventWindow.updateMinMaxDateToEditor(); } } else { throw Error('minDate should be equal or less than maxDate'); } }; Schedule.prototype.getViewIndex = function (viewName) { for (var item = 0; item < this.viewCollections.length; item++) { var checkIndex = this.viewCollections[parseInt(item.toString(), 10)].option; if (checkIndex === viewName) { return item; } } return -1; }; Schedule.prototype.setViewOptions = function (isModuleLoad) { if (isModuleLoad === void 0) { isModuleLoad = false; } if (isNullOrUndefined(this.views) || this.views.length === 0) { return; } this.viewOptions = {}; this.viewCollections = []; var viewName; var selectedView; var prevIndex = this.viewIndex; var count = 0; this.viewIndex = -1; for (var _i = 0, _a = this.views; _i < _a.length; _i++) { var view = _a[_i]; var isOptions = (typeof view === 'string') ? false : true; if (typeof view === 'string') { viewName = view; if (this.currentView === viewName) { selectedView = viewName; this.viewIndex = count; } } else { viewName = view.option; if (view.isSelected) { selectedView = viewName; this.viewIndex = count; } } var obj = extend({ option: viewName }, isOptions ? view : {}); var fieldViewName = viewName.charAt(0).toLowerCase() + viewName.slice(1); obj.cellHeaderTemplateName = obj.cellHeaderTemplate ? obj.option : ''; obj.dateHeaderTemplateName = obj.dateHeaderTemplate ? obj.option : ''; obj.dateRangeTemplateName = obj.dateRangeTemplate ? obj.option : ''; obj.cellTemplateName = obj.cellTemplate ? obj.option : ''; obj.dayHeaderTemplateName = obj.dayHeaderTemplate ? obj.option : ''; obj.monthHeaderTemplateName = obj.monthHeaderTemplate ? obj.option : ''; obj.resourceHeaderTemplateName = obj.resourceHeaderTemplate ? obj.option : ''; obj.headerIndentTemplateName = obj.headerIndentTemplate ? obj.option : ''; obj.eventTemplateName = obj.eventTemplate ? obj.option : ''; if (!isNullOrUndefined(obj.firstDayOfWeek) && obj.firstDayOfWeek === 0) { delete obj.firstDayOfWeek; } if (!isNullOrUndefined(obj.interval) && obj.interval === 1) { delete obj.interval; } this.viewCollections.push(obj); if (isNullOrUndefined(this.viewOptions["" + fieldViewName])) { this.viewOptions["" + fieldViewName] = [obj]; } else { this.viewOptions["" + fieldViewName].push(obj); } count++; } if (!isModuleLoad && selectedView) { this.setProperties({ currentView: selectedView }, true); } if (this.viewIndex === -1) { var currentIndex = this.getViewIndex(this.currentView); this.viewIndex = ((typeof this.views[0] !== 'string') && (!isNullOrUndefined(prevIndex) && prevIndex !== -1)) ? prevIndex : (currentIndex === -1) ? 0 : currentIndex; } }; Schedule.prototype.getActiveViewOptions = function () { var timeScale = { enable: this.timeScale.enable, interval: this.timeScale.interval, slotCount: this.timeScale.slotCount, majorSlotTemplate: this.timeScale.majorSlotTemplate, minorSlotTemplate: this.timeScale.minorSlotTemplate }; var isYearView = this.viewCollections[this.viewIndex].option.indexOf('Year') > -1; var group = { byDate: isYearView ? false : this.group.byDate, byGroupID: this.group.byGroupID, allowGroupEdit: this.group.allowGroupEdit, resources: isNullOrUndefined(this.group.resources) ? [] : this.group.resources, headerTooltipTemplate: this.group.headerTooltipTemplate, enableCompactView: this.group.enableCompactView, hideNonWorkingDays: ['Day', 'Week', 'WorkWeek', 'Month'].indexOf(this.currentView) > -1 ? this.group.hideNonWorkingDays : false }; var workDays = this.viewCollections[this.viewIndex].workDays ? [] : this.workDays; var scheduleOptions = { dateFormat: this.dateFormat, endHour: this.endHour, isSelected: false, option: null, readonly: this.readonly, startHour: this.startHour, allowVirtualScrolling: false, allowOverlap: this.allowOverlap, overscanCount: this.overscanCount, cellHeaderTemplate: this.cellHeaderTemplate, dayHeaderTemplate: this.dayHeaderTemplate, monthHeaderTemplate: this.monthHeaderTemplate, cellTemplate: this.cellTemplate, eventTemplate: this.eventSettings.template, dateHeaderTemplate: this.dateHeaderTemplate, dateRangeTemplate: this.dateRangeTemplate, resourceHeaderTemplate: this.resourceHeaderTemplate, headerIndentTemplate: this.headerIndentTemplate, firstMonthOfYear: this.firstMonthOfYear, firstDayOfWeek: this.firstDayOfWeek, workDays: workDays, monthsCount: this.monthsCount, showWeekend: this.showWeekend, showWeekNumber: this.showWeekNumber, displayName: null, interval: 1, timeScale: timeScale, timeFormat: this.internalTimeFormat, group: group, headerRows: this.headerRows, orientation: 'Horizontal', numberOfWeeks: 0, displayDate: null, enableLazyLoading: false }; var viewOptions = this.viewCollections[this.viewIndex]; var viewsData = extend(scheduleOptions, viewOptions, undefined, true); if (this.firstDayOfWeek !== 0 && viewOptions.firstDayOfWeek && this.firstDayOfWeek !== viewOptions.firstDayOfWeek) { viewsData.firstDayOfWeek = this.firstDayOfWeek; } if (viewsData.displayDate) { viewsData.displayDate = viewsData.displayDate instanceof Date ? new Date(viewsData.displayDate.getTime()) : new Date(viewsData.displayDate); } if (viewsData.enableLazyLoading && !isNullOrUndefined(viewsData.group.resources) && viewsData.group.resources.length > 0 && (['Agenda', 'MonthAgenda', 'Year', 'TimelineYear'].indexOf(viewsData.option) === -1 || (viewsData.option === 'TimelineYear' && viewsData.orientation === 'Vertical'))) { viewsData.allowVirtualScrolling = true; } return viewsData; }; Schedule.prototype.initializeDataModule = function () { this.eventFields = { id: this.eventSettings.fields.id, isBlock: this.eventSettings.fields.isBlock, subject: this.eventSettings.fields.subject.name, startTime: this.eventSettings.fields.startTime.name, endTime: this.eventSettings.fields.endTime.name, startTimezone: this.eventSettings.fields.startTimezone.name, endTimezone: this.eventSettings.fields.endTimezone.name, location: this.eventSettings.fields.location.name, description: this.eventSettings.fields.description.name, isAllDay: this.eventSettings.fields.isAllDay.name, recurrenceID: this.eventSettings.fields.recurrenceID.name, recurrenceRule: this.eventSettings.fields.recurrenceRule.name, recurrenceException: this.eventSettings.fields.recurrenceException.name, isReadonly: this.eventSettings.fields.isReadonly, followingID: this.eventSettings.fields.followingID }; this.setEditorTitles(); this.dataModule = new Data(this, this.eventSettings.dataSource, this.eventSettings.query); this.crudModule = new Crud(this); }; Schedule.prototype.setEditorTitles = function () { this.editorTitles = { subject: this.eventSettings.fields.subject.title || this.localeObj.getConstant('title'), startTime: this.eventSettings.fields.startTime.title || this.localeObj.getConstant('start'), endTime: this.eventSettings.fields.endTime.title || this.localeObj.getConstant('end'), isAllDay: this.eventSettings.fields.isAllDay.title || this.localeObj.getConstant('allDay'), startTimezone: this.eventSettings.fields.startTimezone.title || this.localeObj.getConstant('startTimezone'), endTimezone: this.eventSettings.fields.endTimezone.title || this.localeObj.getConstant('endTimezone'), location: this.eventSettings.fields.location.title || this.localeObj.getConstant('location'), description: this.eventSettings.fields.description.title || this.localeObj.getConstant('description'), recurrenceRule: this.eventSettings.fields.recurrenceRule.title || this.localeObj.getConstant('repeat') }; }; Schedule.prototype.initializeView = function (viewName) { this.showSpinner(); this.activeViewOptions = this.getActiveViewOptions(); if (this.resourceBase) { this.resourceBase.setResourceCollection(); } this.initializeTemplates(); this.renderModule.render(viewName); }; Schedule.prototype.initializeTemplates = function () { this.cellHeaderTemplateFn = this.templateParser(this.activeViewOptions.cellHeaderTemplate); this.dayHeaderTemplateFn = this.templateParser(this.activeViewOptions.dayHeaderTemplate); this.monthHeaderTemplateFn = this.templateParser(this.activeViewOptions.monthHeaderTemplate); this.cellTemplateFn = this.templateParser(this.activeViewOptions.cellTemplate); this.dateHeaderTemplateFn = this.templateParser(this.activeViewOptions.dateHeaderTemplate); this.dateRangeTemplateFn = this.templateParser(this.activeViewOptions.dateRangeTemplate); this.majorSlotTemplateFn = this.templateParser(this.activeViewOptions.timeScale.majorSlotTemplate); this.minorSlotTemplateFn = this.templateParser(this.activeViewOptions.timeScale.minorSlotTemplate); this.appointmentTemplateFn = this.templateParser(this.activeViewOptions.eventTemplate); this.resourceHeaderTemplateFn = this.templateParser(this.activeViewOptions.resourceHeaderTemplate); this.headerIndentTemplateFn = this.templateParser(this.activeViewOptions.headerIndentTemplate); this.headerTooltipTemplateFn = this.templateParser(this.activeViewOptions.group.headerTooltipTemplate); this.eventTooltipTemplateFn = this.templateParser(this.eventSettings.tooltipTemplate); this.editorTemplateFn = this.templateParser(this.editorTemplate); this.editorHeaderTemplateFn = this.templateParser(this.editorHeaderTemplate); this.editorFooterTemplateFn = this.templateParser(this.editorFooterTemplate); this.quickInfoTemplatesHeaderFn = this.templateParser(this.quickInfoTemplates.header); this.quickInfoTemplatesContentFn = this.templateParser(this.quickInfoTemplates.content); this.quickInfoTemplatesFooterFn = this.templateParser(this.quickInfoTemplates.footer); }; Schedule.prototype.initializePopups = function () { this.eventWindow = new EventWindow(this); this.quickPopup = new QuickPopups(this); }; /** * Method to get day names * * @param {string} type Accepts the day name * @returns {string[]} Returns the collection of day names * @private */ Schedule.prototype.getDayNames = function (type) { var culShortNames = []; var cldrObj; var nameSpace = ''; if (isNullOrUndefined(this.locale) || this.locale === 'en' || this.locale === 'en-US') { nameSpace = 'days.stand-alone.'; cldrObj = (getValue(nameSpace + type, getDefaultDateObject(this.getCalendarMode()))); } else { nameSpace = 'main.' + '' + this.locale + '.dates.calendars.' + this.getCalendarMode() + '.days.format.' + type; cldrObj = (getValue(nameSpace, cldrData)); } for (var _i = 0, _a = Object.keys(cldrObj); _i < _a.length; _i++) { var obj = _a[_i]; culShortNames.push(getValue(obj, cldrObj)); } return culShortNames; }; Schedule.prototype.setCldrTimeFormat = function () { if (!isNullOrUndefined(this.timeFormat)) { this.internalTimeFormat = this.timeFormat; return; } if (isNullOrUndefined(this.locale) || this.locale === 'en' || this.locale === 'en-US') { this.internalTimeFormat = (getValue('timeFormats.short', getDefaultDateObject(this.getCalendarMode()))); } else { this.internalTimeFormat = (getValue('main.' + '' + this.locale + '.dates.calendars.' + this.getCalendarMode() + '.timeFormats.short', cldrData)); } }; /** * Method to get calendar mode * * @returns {string} Returns the calendar mode * @private */ Schedule.prototype.getCalendarMode = function () { return !isNullOrUndefined(this.calendarMode) ? this.calendarMode.toLowerCase() : 'gregorian'; }; /** * Method to get time in string * * @param {Date} date Accepts the date object * @returns {string} Returns the time in string * @private */ Schedule.prototype.getTimeString = function (date) { var time = this.globalize.formatDate(date, { format: this.activeViewOptions.timeFormat, type: 'time', calendar: this.getCalendarMode() }); return time.toLocaleUpperCase(); }; /** * Method to get date object * * @param {Date} date Accepts the date object * @returns {Date} Returns the date object * @private */ Schedule.prototype.getDateTime = function (date) { return date instanceof Date ? new Date(date.getTime()) : new Date(date); }; Schedule.prototype.setCalendarMode = function () { if (this.calendarMode === 'Islamic') { this.calendarUtil = new Islamic(); } else { this.calendarUtil = new Gregorian(); } }; /** * Method to change the current view * * @param {View} view Accepts the view name * @param {Event} event Accepts the event object * @param {boolean} muteOnChange Accepts the value to enable or disable mute on change * @param {number} index Accepts the index value * @returns {void} * @private */ Schedule.prototype.changeView = function (view, event, muteOnChange, index) { var _this = this; if (isNullOrUndefined(index)) { index = this.getViewIndex(view); } if (!muteOnChange && index === this.viewIndex && this.currentView === view || index < 0) { return; } var previousView = this.activeViewOptions ? this.activeViewOptions.option : this.currentView; var args = { requestType: 'viewNavigate', cancel: false, event: event }; this.trigger(events.actionBegin, args, function (actionArgs) { if (!actionArgs.cancel) { var navArgs = { action: 'view', cancel: false, currentDate: _this.selectedDate, previousView: previousView, currentView: view, viewIndex: index }; _this.trigger(events.navigating, navArgs, function (navigationArgs) { if (!navigationArgs.cancel) { var isVertical = ['Day', 'Week', 'WorkWeek'].indexOf(view) > -1 && ['Day', 'Week', 'WorkWeek'].indexOf(previousView) < 0; _this.uiStateValues.isInitial = isVertical || view.indexOf('Timeline') > -1 || view.indexOf('Year') > -1; _this.uiStateValues.top = view.indexOf('Timeline') > -1 && previousView.indexOf('Timeline') < 0 ? 0 : _this.uiStateValues.top; _this.viewIndex = navigationArgs.viewIndex; _this.setProperties({ currentView: view }, true); if (_this.headerModule) { _this.headerModule.updateActiveView(); _this.headerModule.setCalendarDate(_this.selectedDate); _this.headerModule.setCalendarView(); } _this.initializeView(_this.currentView); _this.animateLayout(); args = { requestType: 'viewNavigate', cancel: false, event: event }; _this.trigger(events.actionComplete, args); } else { _this.currentView = previousView; } }); } else { _this.currentView = previousView; } }); }; /** * Method to change the view date * * @param {Date} selectedDate Accepts the selected date * @param {Event} event Accepts the event object * @returns {void} * @private */ Schedule.prototype.changeDate = function (selectedDate, event) { var _this = this; var args = { requestType: 'dateNavigate', cancel: false, event: event }; this.trigger(events.actionBegin, args, function (actionArgs) { if (!actionArgs.cancel) { var navArgs = { action: 'date', cancel: false, previousDate: _this.selectedDate, currentDate: selectedDate }; _this.trigger(events.navigating, navArgs, function (navigationArgs) { if (!navigationArgs.cancel) { _this.uiStateValues.isInitial = _this.activeView.isTimelineView() && _this.currentView !== 'TimelineYear'; _this.validateDate(navigationArgs.currentDate); if (_this.headerModule) { _this.headerModule.setCalendarDate(navigationArgs.currentDate); } if (_this.currentView === 'MonthAgenda' && _this.monthAgendaModule) { _this.monthAgendaModule.monthAgendaDate = new Date('' + _this.selectedDate); } _this.initializeView(_this.currentView); _this.animateLayout(); args = { requestType: 'dateNavigate', cancel: false, event: event }; _this.trigger(events.actionComplete, args); } }); } }); }; /** * Method to validate min and max date * * @param {Date} date Accepts the date object * @returns {boolean} Returns the boolean result to validate the min and max date * @private */ Schedule.prototype.isMinMaxDate = function (date) { if (date === void 0) { date = this.selectedDate; } var maxDate = isNullOrUndefined(this.maxDate) ? new Date(2099, 11, 31) : this.maxDate; var minDate = isNullOrUndefined(this.minDate) ? new Date(1900, 0, 1) : this.minDate; return ((date.getTime() >= minDate.getTime()) && (date.getTime() <= maxDate.getTime())); }; /** * Method to validate the selected date * * @param {Date} date Accepts the date object * @returns {boolean} Returns the boolean value for given date is selected date or not * @private */ Schedule.prototype.isSelectedDate = function (date) { return date.setHours(0, 0, 0, 0) === new Date('' + this.selectedDate).setHours(0, 0, 0, 0); }; /** * Method to get the current time * * @param {Date} date Accepts the date object * @returns {Date} Returns the date object after performing the timezone conversion * @private */ Schedule.prototype.getCurrentTime = function (date) { if (date === void 0) { date = new Date(); } if (this.timezone) { return this.tzModule.convert(date, this.tzModule.getLocalTimezoneName(), this.timezone); } return date; }; /** Method to get navigate view * * @returns {View} Return the navigate view name * @private */ Schedule.prototype.getNavigateView = function () { if (this.activeView.isTimelineView()) { return this.currentView === 'TimelineMonth' || this.currentView === 'TimelineYear' ? 'TimelineDay' : 'Agenda'; } return 'Day'; }; Schedule.prototype.animateLayout = function () { if (!this.activeView.element) { return; } new Animation({ duration: 600, name: 'FadeIn', timingFunction: 'easeIn' }).animate(this.activeView.element); }; /** * To provide the array of modules needed for control rendering * * @returns {ModuleDeclaration[]} Returns the declared modules * @private */ Schedule.prototype.requiredModules = function () { var modules = []; this.setViewOptions(true); for (var _i = 0, _a = Object.keys(this.viewOptions); _i < _a.length; _i++) { var view = _a[_i]; view = (view === 'timelineDay' || view === 'timelineWeek' || view === 'timelineWorkWeek') ? 'timelineViews' : view; modules.push({ member: view, args: [this] }); } if (this.allowDragAndDrop) { modules.push({ member: 'dragAndDrop', args: [this] }); } if (this.allowResizing) { modules.push({ member: 'resize', args: [this] }); } modules.push({ member: 'excelExport', args: [this] }); modules.push({ member: 'iCalendarExport', args: [this] }); modules.push({ member: 'iCalendarImport', args: [this] }); modules.push({ member: 'print', args: [this] }); return modules; }; /** * Initializes the values of private members. * * @returns {void} * @private */ Schedule.prototype.preRender = function () { this.isAdaptive = Browser.isDevice || util.isIPadDevice(); this.globalize = new Internationalization(this.locale); this.tzModule = new Timezone(); if (this && isNullOrUndefined(this.uiStateValues) || !(this.enablePersistence)) { this.uiStateValues = { expand: false, isInitial: true, left: 0, top: 0, isGroupAdaptive: false, isIgnoreOccurrence: false, groupIndex: this.adaptiveGroupIndex, action: false, isBlock: false, isCustomMonth: true, isPreventTimezone: false, isTransformed: false }; } this.currentTimezoneDate = this.getCurrentTime(); this.activeCellsData = { startTime: new Date(this.currentTimezoneDate), endTime: new Date(this.currentTimezoneDate), isAllDay: false }; this.activeEventData = { event: undefined, element: undefined }; this.getDefaultLocale(); this.localeObj = new L10n(this.getModuleName(), this.defaultLocale, this.locale); this.setCldrTimeFormat(); this.setCalendarMode(); this.eventsData = []; this.eventsProcessed = []; this.blockData = []; this.blockProcessed = []; this.resourceCollection = []; this.currentAction = null; this.selectedElements = []; this.activeEventTemplates = []; this.setViewOptions(); }; Schedule.prototype.getDefaultLocale = function () { this.defaultLocale = { day: 'Day', week: 'Week', workWeek: 'Work Week', month: 'Month', year: 'Year', agenda: 'Agenda', weekAgenda: 'Week Agenda', workWeekAgenda: 'Work Week Agenda', monthAgenda: 'Month Agenda', today: 'Today', noEvents: 'No events', emptyContainer: 'There are no events scheduled on this day.', allDay: 'All day', start: 'Start', end: 'End', more: 'more', close: 'Close', cancel: 'Cancel', noTitle: '(No Title)', delete: 'Delete', deleteEvent: 'Delete Event', deleteMultipleEvent: 'Delete Multiple Events', selectedItems: 'Items selected', deleteSeries: 'Entire Series', edit: 'Edit', editSeries: 'Entire Series', editEvent: 'Edit Event', createEvent: 'Create', subject: 'Subject', addTitle: 'Add title', moreDetails: 'More Details', moreEvents: 'More Events', save: 'Save', editContent: 'How would you like to change the appointment in the series?', deleteContent: 'Are you sure you want to delete this event?', deleteMultipleContent: 'Are you sure you want to delete the selected events?', newEvent: 'New Event', title: 'Title', location: 'Location', description: 'Description', timezone: 'Timezone', startTimezone: 'Start Timezone', endTimezone: 'End Timezone', repeat: 'Repeat', saveButton: 'Save', cancelButton: 'Cancel', deleteButton: 'Delete', recurrence: 'Recurrence', wrongPattern: 'The recurrence pattern is not valid.', seriesChangeAlert: 'Do you want to cancel the changes made to specific ' + 'instances of this series and match it to the whole series again?', createError: 'The duration of the event must be shorter than how frequently it occurs. ' + 'Shorten the duration, or change the recurrence pattern in the recurrence event editor.', sameDayAlert: 'Two occurrences of the same event cannot occur on the same day.', occurenceAlert: 'Cannot reschedule an occurrence of the recurring appointment if it skips over ' + 'a later occurrence of the same appointment.', editRecurrence: 'Edit Recurrence', recurringEvent: 'Recurring Event', repeats: 'Repeats', alert: 'Alert', startEndError: 'The selected end date occurs before the start date.', invalidDateError: 'The entered date value is invalid.', blockAlert: 'Events cannot be scheduled within the blocked time range.', overlapAlert: 'Events cannot be scheduled during the chosen time as it overlaps with another event.', ok: 'Ok', yes: 'Yes', no: 'No', of: 'of', occurrence: 'Occurrence', series: 'Series', previous: 'Previous', next: 'Next', timelineDay: 'Timeline Day', timelineWeek: 'Timeline Week', timelineWorkWeek: 'Timeline Work Week', timelineMonth: 'Timeline Month', timelineYear: 'Timeline Year', editFollowingEvent: 'Following Events', deleteTitle: 'Delete Event', editTitle: 'Edit Event', beginFrom: 'Begin From', endAt: 'Ends At', expandAllDaySection: 'Expand-all-day-section', collapseAllDaySection: 'Collapse-all-day-section', searchTimezone: 'Search Timezone', noRecords: 'No records found' }; }; Schedule.prototype.wireEvents = function () { EventHandler.add(window, 'resize', this.onScheduleResize, this); EventHandler.add(window, 'orientationchange', this.onScheduleResize, this); EventHandler.add(document, Browser.touchStartEvent, this.onDocumentClick, this); if (this.allowClipboard) { EventHandler.add(document, 'paste', this.onDocumentPaste, this); } }; /** * Method to remove selected class * * @returns {void} * @private */ Schedule.prototype.removeSelectedClass = function () { var selectedCells = this.getSelectedCells(); for (var _i = 0, selectedCells_1 = selectedCells; _i < selectedCells_1.length; _i++) { var cell = selectedCells_1[_i]; cell.removeAttribute('tabindex'); } removeClass(selectedCells, cls.SELECTED_CELL_CLASS); if (this.keyboardInteractionModule && this.keyboardInteractionModule.selectedCells.length > 0) { this.keyboardInteractionModule.selectedCells = []; } }; /** * Method to add selected class * * @param {HTMLTableCellElement[]} cells Accepts the collection of elements * @param {HTMLTableCellElement} focusCell Accepts the focus element * @param {boolean} isPreventScroll Accepts the boolean value to prevent scroll * @returns {void} * @private */ Schedule.prototype.addSelectedClass = function (cells, focusCell, isPreventScroll) { addClass(cells, cls.SELECTED_CELL_CLASS); if (focusCell) { focusCell.setAttribute('tabindex', '0'); focusCell.focus({ preventScroll: isPreventScroll || false }); } }; /** * Method to select cell * * @param {HTMLElement | HTMLTableCellElement} element Accepts the select element * @returns {void} * @private */ Schedule.prototype.selectCell = function (element) { this.removeSelectedClass(); this.addSelectedClass([element], element); }; /** * Method to get all day row element * * @returns {Element} Returns the all day row element * @private */ Schedule.prototype.getAllDayRow = function () { return this.element.querySelector('.' + cls.ALLDAY_ROW_CLASS); }; /** * Method to get content table element * * @returns {HTMLElement} Returns the content table element * @private */ Schedule.prototype.getContentTable = function () { return this.activeView.element.querySelector('.' + cls.CONTENT_TABLE_CLASS + ' tbody'); }; /** * Method to get all content table rows * * @returns {HTMLElement[]} Returns the content table rows * @private */ Schedule.prototype.getTableRows = function () { return [].slice.call(this.element.querySelectorAll('.' + cls.CONTENT_TABLE_CLASS + ' tbody tr:not(.' + cls.HIDDEN_CLASS + ')')); }; /** * Method to get work cell elements * * @returns {Element[]} Returns the all work cell elements * @private */ Schedule.prototype.getWorkCellElements = function () { return [].slice.call(this.element.querySelectorAll('.' + cls.WORK_CELLS_CLASS)); }; /** * Method to get the index from date collection * * @param {Date[]} collection Accepts the collections of date * @param {Date} date Accepts the date object * @returns {number} Returns the index compared date with date collections * @private */ Schedule.prototype.getIndexOfDate = function (collection, date) { return collection.map(Number).indexOf(+date); }; /** * Method to find all day cell * * @param {Element} td Accepts the DOM Element * @returns {boolean} Returns the boolean value * @private */ Schedule.prototype.isAllDayCell = function (td) { if (['Month', 'TimelineMonth', 'TimelineYear', 'MonthAgenda'].indexOf(this.currentView) > -1 || td.classList.contains(cls.ALLDAY_CELLS_CLASS) || td.classList.contains(cls.HEADER_CELLS_CLASS) || !this.activeViewOptions.timeScale.enable) { return true; } if (this.activeView.isTimelineView() && this.activeViewOptions.headerRows.length > 0 && this.activeViewOptions.headerRows.slice(-1)[0].option !== 'Hour') { return true; } return false; }; /** * Method to get date from element * * @param {Element} td Accepts the DOM element * @returns {Date} Returns the date object * @private */ Schedule.prototype.getDateFromElement = function (td) { var dateString; if (!isNullOrUndefined(td)) { dateString = td.getAttribute('data-date'); } if (!isNullOrUndefined(dateString)) { var dateInMS = parseInt(dateString, 10); var date = new Date(dateInMS); return date; } return undefined; }; /** * Method to get target element from given selector * * @param {string} selector Accepts the element selector * @param {number} left Accepts the pageX value * @param {number} top Accepts the pageY value * @returns {Element[]} Returns the collection of elements based on the given selector * @private */ Schedule.prototype.getTargetElement = function (selector, left, top) { var element = document.elementFromPoint(left, top); var targetElement; if (element) { targetElement = element.closest(selector); } return (targetElement) ? [targetElement] : null; }; /** * Method to process cell header template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getCellHeaderTemplate = function () { return this.cellHeaderTemplateFn; }; /** * Method to process cell header template in year view. * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getDayHeaderTemplate = function () { return this.dayHeaderTemplateFn; }; /** * Method to process cell header template in year view. * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getMonthHeaderTemplate = function () { return this.monthHeaderTemplateFn; }; /** * Method to process cell template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getCellTemplate = function () { return this.cellTemplateFn; }; /** * Method to process date header template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getDateHeaderTemplate = function () { return this.dateHeaderTemplateFn; }; /** * Method to process date range template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getDateRangeTemplate = function () { return this.dateRangeTemplateFn; }; /** * Method to process major slot template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getMajorSlotTemplate = function () { return this.majorSlotTemplateFn; }; /** * Method to process minor slot template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getMinorSlotTemplate = function () { return this.minorSlotTemplateFn; }; /** * Method to process appointment template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getAppointmentTemplate = function () { return this.appointmentTemplateFn; }; /** * Method to process appointment tooltip template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getEventTooltipTemplate = function () { return this.eventTooltipTemplateFn; }; /** * Method to process header tooltip template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getHeaderTooltipTemplate = function () { return this.headerTooltipTemplateFn; }; /** * Method to process editor template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getEditorTemplate = function () { return this.editorTemplateFn; }; /** * Method to process editor header template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getEditorHeaderTemplate = function () { return this.editorHeaderTemplateFn; }; /** * Method to process editor footer template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getEditorFooterTemplate = function () { return this.editorFooterTemplateFn; }; /** * Method to process quick info header template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getQuickInfoTemplatesHeader = function () { return this.quickInfoTemplatesHeaderFn; }; /** * Method to process quick info content template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getQuickInfoTemplatesContent = function () { return this.quickInfoTemplatesContentFn; }; /** * Method to process quick info footer template * * @returns {CallbackFunction} Returns the callback function * @private */ Schedule.prototype.getQuickInfoTemplatesFooter = function () { return this.quickInfoTe