@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.
300 lines (299 loc) • 14.8 kB
JavaScript
import { addClass, removeClass, Touch, remove, EventHandler, Browser } from '@syncfusion/ej2-base';
import { closest, isNullOrUndefined } from '@syncfusion/ej2-base';
import * as events from '../base/constant';
import * as cls from '../base/css-constant';
import * as util from '../base/util';
/**
* `touch` module is used to handle touch interactions.
*/
var ScheduleTouch = /** @class */ (function () {
function ScheduleTouch(parent) {
this.parent = parent;
this.element = this.parent.element.querySelector('.' + cls.TABLE_CONTAINER_CLASS);
this.touchObj = new Touch(this.element, {
scroll: this.scrollHandler.bind(this),
swipe: this.swipeHandler.bind(this),
tapHold: this.tapHoldHandler.bind(this),
swipeSettings: { swipeThresholdDistance: 1 }
});
EventHandler.add(this.element, 'transitionend', this.onTransitionEnd, this);
this.touchLeftDirection = this.parent.enableRtl ? 'Right' : 'Left';
this.touchRightDirection = this.parent.enableRtl ? 'Left' : 'Right';
}
ScheduleTouch.prototype.scrollHandler = function (e) {
if (!isNullOrUndefined(this.parent.eventTooltip)) {
this.parent.eventTooltip.close();
}
var blockSwipe = !this.parent.isAdaptive && e.originalEvent && e.originalEvent.target &&
!isNullOrUndefined(closest(e.originalEvent.target, '.' + cls.APPOINTMENT_CLASS));
this.parent.uiStateValues.isTouchScroll = blockSwipe && e.originalEvent.type === 'touchmove' && !this.parent.uiStateValues.action;
if (blockSwipe || this.parent.currentView === 'Agenda' || this.parent.uiStateValues.action || !this.parent.allowSwiping ||
this.parent.uiStateValues.isTapHold) {
return;
}
this.parent.uiStateValues.isSwipeScroll = true;
if (!this.timeStampStart) {
this.timeStampStart = Date.now();
}
if (this.element.classList.contains(cls.TRANSLATE_CLASS)) {
this.onTransitionEnd();
}
if (e.scrollDirection === 'Left' || e.scrollDirection === 'Right') {
var args = { requestType: 'dateNavigate', cancel: false, event: e.originalEvent };
this.parent.trigger(events.actionBegin, args);
if (args.cancel) {
return;
}
var scrollDiv = this.element.querySelector('.' + cls.CONTENT_WRAP_CLASS);
if (scrollDiv && scrollDiv.scrollWidth > scrollDiv.clientWidth) {
return;
}
else {
this.isScrollTriggered = true;
e.originalEvent.preventDefault();
e.originalEvent.stopPropagation();
}
}
if (e.scrollDirection === this.touchLeftDirection) {
if (!this.nextPanel) {
this.renderPanel(cls.NEXT_PANEL_CLASS, 'Next');
this.nextPanel = {
element: this.parent.activeView.getPanel(),
selectedDate: new Date(this.parent.selectedDate.getTime()),
renderDates: this.parent.activeView.renderDates,
colLevels: this.parent.activeView.colLevels
};
this.setDimensions(this.nextPanel.element);
}
var x = this.parent.enableRtl ? e.distanceX : -e.distanceX;
this.element.style.transform = 'translatex(' + (this.getTranslateX(this.element) + x) + 'px)';
}
else if (e.scrollDirection === this.touchRightDirection) {
var prevWidth = 0;
if (!this.previousPanel) {
this.renderPanel(cls.PREVIOUS_PANEL_CLASS, 'Previous');
this.previousPanel = {
element: this.parent.activeView.getPanel(),
selectedDate: new Date(this.parent.selectedDate.getTime()),
renderDates: this.parent.activeView.renderDates,
colLevels: this.parent.activeView.colLevels
};
this.setDimensions(this.previousPanel.element);
prevWidth = this.previousPanel.element.offsetWidth;
}
var x = this.parent.enableRtl ? prevWidth - e.distanceX : -prevWidth + e.distanceX;
this.element.style.transform = 'translatex(' + (this.getTranslateX(this.element) + x) + 'px)';
}
};
ScheduleTouch.prototype.swipeHandler = function (e) {
if (!this.isScrollTriggered || this.parent.uiStateValues.action || !this.parent.allowSwiping ||
this.parent.uiStateValues.isTapHold) {
return;
}
this.isScrollTriggered = false;
var swipeDate = e.swipeDirection === 'Left' ?
this.parent.activeView.renderDates[0] : this.parent.activeView.renderDates.slice(-1)[0];
if ((e.swipeDirection === 'Left' && swipeDate < this.parent.maxDate) ||
(e.swipeDirection === 'Right' && swipeDate >= this.parent.minDate)) {
var time = Date.now() - this.timeStampStart;
var offsetDist = (e.distanceX * (Browser.isDevice ? 6 : 1.66));
if (offsetDist > time || (e.distanceX > (this.parent.element.offsetWidth / 2))) {
this.swapPanels(e.swipeDirection);
if (offsetDist > time && (e.distanceX > (this.parent.element.offsetWidth / 2))) {
this.element.style.transitionDuration = (((Browser.isDevice ? e.distanceX : offsetDist) / time) / 10) + 's';
}
this.confirmSwipe(e.swipeDirection);
}
else {
this.cancelSwipe();
}
var args = { requestType: 'dateNavigate', cancel: false, event: e.originalEvent };
this.parent.trigger(events.actionComplete, args);
}
else {
this.cancelSwipe();
}
this.timeStampStart = null;
};
ScheduleTouch.prototype.tapHoldHandler = function (e) {
var target = closest(e.originalEvent.target, '.' + cls.APPOINTMENT_CLASS);
if (!isNullOrUndefined(target)) {
this.parent.uiStateValues.isTapHold = true;
if (this.parent.isAdaptive) {
if (Browser.isIos) {
EventHandler.add(this.element, 'touchend', this.preventEventClick, this);
}
this.parent.quickPopup.tapHoldEventPopup(e.originalEvent);
this.triggerResizeStart(e.originalEvent);
}
else if (['Agenda', 'MonthAgenda', 'Year'].indexOf(this.parent.currentView) < 0) {
this.parent.selectedElements = [];
this.parent.eventBase.getSelectedEventElements(target);
this.triggerResizeStart(e.originalEvent);
}
}
};
ScheduleTouch.prototype.triggerResizeStart = function (e) {
if (this.parent.resizeModule && closest(e.target, '.' + cls.EVENT_RESIZE_CLASS)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.parent.resizeModule.resizeStart(e);
}
};
ScheduleTouch.prototype.preventEventClick = function (e) {
e.preventDefault();
EventHandler.remove(this.element, 'touchend', this.preventEventClick);
};
ScheduleTouch.prototype.renderPanel = function (clsName, nextPrevType) {
if (!this.currentPanel) {
this.currentPanel = {
element: this.parent.activeView.getPanel(),
selectedDate: new Date(this.parent.selectedDate.getTime()),
renderDates: this.parent.activeView.renderDates,
colLevels: this.parent.activeView.colLevels
};
this.setDimensions(this.currentPanel.element);
}
else {
this.parent.setProperties({ selectedDate: this.currentPanel.selectedDate }, true);
}
this.parent.setProperties({ selectedDate: this.parent.activeView.getNextPreviousDate(nextPrevType) }, true);
if (this.parent.headerModule) {
this.parent.headerModule.setCalendarDate(this.parent.selectedDate);
}
this.parent.activeView.getRenderDates();
this.parent.activeView.renderLayout(clsName);
};
ScheduleTouch.prototype.swapPanels = function (direction) {
if (direction === this.touchLeftDirection) {
var temp = this.nextPanel;
this.nextPanel = this.currentPanel;
this.currentPanel = temp;
}
else {
var temp = this.previousPanel;
this.previousPanel = this.currentPanel;
this.currentPanel = temp;
}
};
ScheduleTouch.prototype.confirmSwipe = function (swipeDirection) {
var _this = this;
var previousDate = swipeDirection === this.touchLeftDirection ?
this.nextPanel.selectedDate : this.previousPanel.selectedDate;
var args = {
action: 'date', cancel: false, previousDate: previousDate, currentDate: this.currentPanel.selectedDate
};
this.parent.trigger(events.navigating, args, function (navArgs) {
if (navArgs.cancel) {
_this.swapPanels(swipeDirection);
_this.cancelSwipe();
}
else {
_this.parent.activeView.setPanel(_this.currentPanel.element);
_this.parent.setProperties({ selectedDate: _this.currentPanel.selectedDate }, true);
var translateX = void 0;
if (_this.parent.enableRtl) {
translateX = swipeDirection === _this.touchLeftDirection ?
(_this.previousPanel ? _this.previousPanel.element.offsetLeft : _this.currentPanel.element.offsetWidth) : 0;
}
else {
translateX = swipeDirection === _this.touchLeftDirection ? -_this.currentPanel.element.offsetLeft : 0;
}
_this.parent.activeView.renderDates = _this.currentPanel.renderDates;
_this.parent.activeView.colLevels = _this.currentPanel.colLevels;
addClass([_this.element], cls.TRANSLATE_CLASS);
_this.element.style.transform = 'translatex(' + translateX + 'px)';
if (_this.parent.headerModule) {
_this.parent.headerModule.updateDateRange();
}
_this.parent.renderTemplates();
_this.parent.crudModule.refreshDataManager();
}
});
};
ScheduleTouch.prototype.cancelSwipe = function () {
var _this = this;
this.parent.activeView.setPanel(this.currentPanel.element);
this.parent.setProperties({ selectedDate: this.currentPanel.selectedDate }, true);
this.parent.activeView.renderDates = this.currentPanel.renderDates;
if (this.parent.activeViewOptions.group.resources.length > 0 && this.parent.resourceBase.lastResourceLevel.length > 0) {
var workDaysField_1 = this.parent.resourceBase.resourceCollection[0].workDaysField;
this.parent.resourceBase.lastResourceLevel.forEach(function (resource) {
if (workDaysField_1) {
var resourceWorkDays = resource[workDaysField_1];
var hasCustomWorkDays = Array.isArray(resourceWorkDays) &&
(!_this.parent.showWeekend || _this.parent.currentView === 'WorkWeek');
resource.renderDates = hasCustomWorkDays
? _this.calculateResourceSpecificDates(resource, workDaysField_1)
: _this.currentPanel.renderDates;
}
else {
resource.renderDates = _this.currentPanel.renderDates;
}
});
}
this.parent.activeView.colLevels = this.currentPanel.colLevels;
addClass([this.element], cls.TRANSLATE_CLASS);
var prevWidth = this.previousPanel ? this.previousPanel.element.offsetWidth : 0;
this.element.style.transform = 'translatex(' + (this.parent.enableRtl ? prevWidth : -this.currentPanel.element.offsetLeft) + 'px)';
};
ScheduleTouch.prototype.calculateResourceSpecificDates = function (resource, workDaysField) {
var resourceDates = [];
var resourceWorkDays = resource[workDaysField];
this.currentPanel.renderDates.forEach(function (date) {
if (Array.isArray(resourceWorkDays) && resourceWorkDays.indexOf(date.getDay()) !== -1) {
resourceDates.push(date);
}
});
return resourceDates;
};
ScheduleTouch.prototype.onTransitionEnd = function () {
if (!isNullOrUndefined(this.element) && !this.element.classList.contains(cls.TRANSLATE_CLASS)) {
return;
}
this.parent.uiStateValues.isSwipeScroll = false;
removeClass([this.element], cls.TRANSLATE_CLASS);
this.element.style.transitionDuration = '';
this.element.style.transform = '';
if (this.previousPanel) {
remove(this.previousPanel.element);
this.previousPanel = null;
removeClass([this.currentPanel.element], cls.PREVIOUS_PANEL_CLASS);
addClass([this.currentPanel.element], cls.CURRENT_PANEL_CLASS);
}
if (this.nextPanel) {
remove(this.nextPanel.element);
this.nextPanel = null;
removeClass([this.currentPanel.element], cls.NEXT_PANEL_CLASS);
addClass([this.currentPanel.element], cls.CURRENT_PANEL_CLASS);
}
this.currentPanel = null;
this.parent.activeView.getPanel().style.width = '';
};
ScheduleTouch.prototype.getTranslateX = function (element) {
var style = window.getComputedStyle(element);
return new WebKitCSSMatrix(style.webkitTransform).m41;
};
ScheduleTouch.prototype.setDimensions = function (element) {
element.style.width = (this.parent.element.clientWidth) + 'px';
};
ScheduleTouch.prototype.resetValues = function () {
this.currentPanel = null;
this.previousPanel = null;
this.nextPanel = null;
this.timeStampStart = null;
this.element.style.transform = '';
this.element.style.transitionDuration = '';
util.removeChildren(this.element);
removeClass([this.element], cls.TRANSLATE_CLASS);
};
ScheduleTouch.prototype.destroy = function () {
if (this.touchObj) {
this.touchObj.destroy();
this.touchObj = null;
}
EventHandler.remove(this.element, 'transitionend', this.onTransitionEnd);
this.resetValues();
};
return ScheduleTouch;
}());
export { ScheduleTouch };