tui-calendar
Version:
TOAST UI Calendar
336 lines (277 loc) • 9.9 kB
JavaScript
/**
* @fileoverview Handler module for WeekdayInWeek view's creation actions.
* @author NHN FE Development Lab <dl_javascript@nhn.com>
*/
'use strict';
var util = require('tui-code-snippet');
var config = require('../../config');
var datetime = require('../../common/datetime');
var common = require('../../common/common');
var domutil = require('../../common/domutil');
var domevent = require('../../common/domevent');
var dayGridCore = require('./core');
var DayGridCreationGuide = require('./creationGuide');
var TZDate = require('../../common/timezone').Date;
var CLICK_DELAY = 300;
/**
* @constructor
* @implements {Handler}
* @mixes dayGridCore
* @mixes CutomEvents
* @param {Drag} [dragHandler] - Drag handler instance.
* @param {DayGrid} [view] - DayGrid view instance.
* @param {Base} [controller] - Base controller instance.
* @param {Options} [options] - calendar Options
*/
function DayGridCreation(dragHandler, view, controller, options) {
/**
* Drag handler instance.
* @type {Drag}
*/
this.dragHandler = dragHandler;
/**
* view instance.
* @type {DayGrid}
*/
this.view = view;
/**
* Base controller instance.
* @type {Base}
*/
this.controller = controller;
/**
* @type {function}
*/
this.getScheduleDataFunc = null;
/**
* @type {DayGridCreationGuide}
*/
this.guide = new DayGridCreationGuide(this);
/**
* @type {boolean}
*/
this._requestOnClick = false;
/**
* @type {boolean}
*/
this._disableDblClick = options.disableDblClick;
/**
* @type {boolean}
*/
this._disableClick = options.disableClick;
dragHandler.on('dragStart', this._onDragStart, this);
dragHandler.on('click', this._onClick, this);
if (this._disableDblClick) {
CLICK_DELAY = 0;
} else {
domevent.on(view.container, 'dblclick', this._onDblClick, this);
}
}
/**
* Destroy method
*/
DayGridCreation.prototype.destroy = function() {
this.guide.destroy();
this.dragHandler.off(this);
if (this.view && this.view.container) {
domevent.off(this.view.container, 'dblclick', this._onDblClick, this);
}
this.dragHandler = this.view = this.controller = this.getScheduleDataFunc = null;
};
/**
* Check dragstart target is expected conditions for this handler.
* @param {HTMLElement} target - dragstart event handler's target element.
* @returns {boolean|WeekdayInWeek} return WeekdayInWeek view instance when satiate condition.
*/
DayGridCreation.prototype.checkExpectedCondition = function(target) {
var cssClass = domutil.getClass(target).trim();
var excludeTarget = true;
var matches, schedulesElement;
if (domutil.closest(target, config.classname('.weekday-exceed-in-week'))
|| domutil.closest(target, config.classname('.weekday-collapse-btn'))
) {
return false;
}
if (domutil.closest(target, config.classname('.weekday-schedule-block'), excludeTarget)) {
return false;
}
schedulesElement = domutil.closest(target, config.classname('.weekday-schedules'));
if (!schedulesElement && cssClass !== config.classname('weekday-schedules')) {
return false;
}
target = schedulesElement ? schedulesElement.parentNode : target.parentNode;
cssClass = domutil.getClass(target);
matches = cssClass.match(config.daygrid.getViewIDRegExp);
if (!matches || matches.length < 2) {
return false;
}
return util.pick(this.view.children.items, matches[1]);
};
/**
* Request schedule model creation to controller by custom schedules.
* @fires {DayGridCreation#beforeCreateSchedule}
* @param {object} scheduleData - schedule data from DayGridCreation module.
*/
DayGridCreation.prototype._createSchedule = function(scheduleData) {
var dateRange = scheduleData.range,
startXIndex = scheduleData.dragStartXIndex,
xIndex = scheduleData.xIndex,
start, end;
// when inverse start, end then change it.
if (xIndex < startXIndex) {
startXIndex = xIndex + startXIndex;
xIndex = startXIndex - xIndex;
startXIndex = startXIndex - xIndex;
}
start = new TZDate(dateRange[startXIndex]);
end = datetime.end(dateRange[xIndex]);
/**
* @event {DayGridCreation#beforeCreateSchedule}
* @type {object}
* @property {string} category - schedule category
* @property {boolean} isAllDay - whether schedule is fired in view area?
* @property {Date} start - select start time
* @property {Date} end - select end time
* @property {DayGridCreationGuide} guide - DayGridCreationGuide instance
* @property {string} triggerEventName - event name
*/
this.fire('beforeCreateSchedule', {
category: this.view.options.viewName,
isAllDay: true,
start: start,
end: end,
guide: this.guide,
triggerEventName: scheduleData.triggerEvent
});
};
/**
* DragStart event handler method.
* @emits DayGridCreation#dragstart
* @param {object} dragStartEventData - Drag#dragStart event handler schedule data.
*/
DayGridCreation.prototype._onDragStart = function(dragStartEventData) {
var target = dragStartEventData.target,
result = this.checkExpectedCondition(target),
getScheduleDataFunc,
scheduleData;
if (!result) {
return;
}
this.dragHandler.on({
drag: this._onDrag,
dragEnd: this._onDragEnd
}, this);
getScheduleDataFunc = this._retriveScheduleData(this.view, dragStartEventData.originEvent);
this.getScheduleDataFunc = getScheduleDataFunc;
scheduleData = getScheduleDataFunc(dragStartEventData.originEvent);
/**
* @event DayGridCreation#dragstart
* @type {object}
* @property {DayGridView} relatedView - view instance.
* @property {number} datesInRange - date count of this view.
* @property {number} dragStartXIndex - index number of dragstart grid index.
* @property {number} xIndex - index number of mouse positions.
*/
this.fire('dragstart', scheduleData);
};
/**
* Drag event handler method.
* @emits DayGridCreation#drag
* @param {object} dragEventData - Drag#drag event handler scheduledata.
*/
DayGridCreation.prototype._onDrag = function(dragEventData) {
var getScheduleDataFunc = this.getScheduleDataFunc,
scheduleData;
if (!getScheduleDataFunc) {
return;
}
scheduleData = getScheduleDataFunc(dragEventData.originEvent);
/**
* @event DayGridCreation#drag
* @type {object}
* @property {DayGridView} relatedView - view instance.
* @property {number} datesInRange - date count of this view.
* @property {number} dragStartXIndex - index number of dragstart grid index.
* @property {number} xIndex - index number of mouse positions.
*/
this.fire('drag', scheduleData);
};
/**
* DragEnd event hander method.
* @emits DayGridCreation#dragend
* @param {object} dragEndEventData - Drag#dragEnd event handler data.
* @param {string} [overrideEventName] - override emitted event name when supplied.
*/
DayGridCreation.prototype._onDragEnd = function(dragEndEventData, overrideEventName) {
var getScheduleDataFunc = this.getScheduleDataFunc;
var scheduleData;
if (!getScheduleDataFunc) {
return;
}
this.dragHandler.off({
drag: this._onDrag,
dragEnd: this._onDragEnd
}, this);
scheduleData = getScheduleDataFunc(dragEndEventData.originEvent);
this._createSchedule(scheduleData);
/**
* @event DayGridCreation#dragend
* @type {object}
* @property {DayGridView} relatedView - view instance.
* @property {number} datesInRange - date count of this view.
* @property {number} dragStartXIndex - index number of dragstart grid index.
* @property {number} xIndex - index number of mouse positions.
*/
this.fire(overrideEventName || 'dragend', scheduleData);
this.getScheduleDataFunc = null;
};
/**
* Click event handler method.
* @emits DayGridCreation#click
* @param {object} clickEventData - Drag#click event handler data.
*/
DayGridCreation.prototype._onClick = function(clickEventData) {
var self = this;
var getScheduleDataFunc, scheduleData;
if (!this.checkExpectedCondition(clickEventData.target) || this._disableClick) {
return;
}
getScheduleDataFunc = this._retriveScheduleData(this.view, clickEventData.originEvent);
scheduleData = getScheduleDataFunc(clickEventData.originEvent);
this._requestOnClick = true;
setTimeout(function() {
if (self._requestOnClick) {
self.fire('click', scheduleData);
self._createSchedule(scheduleData);
}
self._requestOnClick = false;
}, CLICK_DELAY);
};
/**
* Dblclick event handler method.
* @emits DayGridCreation#click
* @param {object} clickEventData - Drag#Click event handler data.
*/
DayGridCreation.prototype._onDblClick = function(clickEventData) {
var getScheduleDataFunc, scheduleData;
if (!this.checkExpectedCondition(clickEventData.target)) {
return;
}
getScheduleDataFunc = this._retriveScheduleData(this.view, clickEventData);
scheduleData = getScheduleDataFunc(clickEventData);
this.fire('click', scheduleData);
this._createSchedule(scheduleData);
this._requestOnClick = false;
};
/**
* Invoke creation click
* @param {Schedule} schedule - schedule instance
*/
DayGridCreation.prototype.invokeCreationClick = function(schedule) {
var scheduleData = this._retriveScheduleDataFromDate(this.view, schedule.start);
this.fire('click', scheduleData);
this._createSchedule(scheduleData);
};
common.mixin(dayGridCore, DayGridCreation);
util.CustomEvents.mixin(DayGridCreation);
module.exports = DayGridCreation;