UNPKG

tui-calendar

Version:
353 lines (290 loc) 8.78 kB
/** * @fileoverview Creation handler for month view * @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 array = require('../../common/array'); var domutil = require('../../common/domutil'); var domevent = require('../../common/domevent'); var getMousePosDate = require('./core'); var Guide = require('./creationGuide'); var TZDate = require('../../common/timezone').Date; var CLICK_DELAY = 300; /** * @constructor * @param {Drag} dragHandler - Drag handler instance. * @param {Month} monthView - Month view instance. * @param {Base} baseController - Base controller instance. * @param {Options} [options] - calendar Options */ function MonthCreation(dragHandler, monthView, baseController, options) { /** * @type {Drag} */ this.dragHandler = dragHandler; /** * @type {Month} */ this.monthView = monthView; /** * @type {Base} */ this.baseController = baseController; /** * @type {function} */ this.getScheduleData = null; /** * Cache for dragging session * @type {object} */ this._cache = null; /** * @type {MonthCreationGuide} */ this.guide = new Guide(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(monthView.container, 'dblclick', this._onDblClick, this); } } /** * Destructor */ MonthCreation.prototype.destroy = function() { this.dragHandler.off(this); this.guide.destroy(); if (this.monthView && this.monthView.container) { domevent.off(this.monthView.container, 'dblclick', this._onDblClick, this); } this.dragHandler = this.monthView = this.baseController = this.getScheduleData = this._cache = this.guide = null; }; /** * Fire before create schedule * @fires {MonthCreation#beforeCreateSchedule} * @param {object} eventData - cache data from single dragging session */ MonthCreation.prototype._createSchedule = function(eventData) { /** * @event {MonthCreation#beforeCreateSchedule} * @type {object} * @property {boolean} isAllDay - whether schedule is fired in allday view area? * @property {Date} start - select start time * @property {Date} end - select end time * @property {TimeCreationGuide} guide - TimeCreationGuide instance * @property {string} triggerEventName - event name */ this.fire('beforeCreateSchedule', { isAllDay: eventData.isAllDay, start: eventData.start, end: eventData.end, guide: this.guide.guide, triggerEventName: eventData.triggerEvent }); }; /** * DragStart event handler * @fires {MonthCreation#monthCreationDragstart} * @param {object} dragStartEvent - dragStart event data */ MonthCreation.prototype._onDragStart = function(dragStartEvent) { var eventData; if (!isElementWeekdayGrid(dragStartEvent.target)) { return; } this.dragHandler.on({ drag: this._onDrag, dragEnd: this._onDragEnd }, this); this.getScheduleData = getMousePosDate(this.monthView); eventData = this.getScheduleData(dragStartEvent.originEvent); this._cache = { start: new TZDate(eventData.date) }; /** * @event {MonthCreation#monthCreationDragstart} * @type {object} * @property {number} x - x index * @property {number} y - y index * @property {Date} date - drag date */ this.fire('monthCreationDragstart', eventData); }; /** * Drag event handler * @fires {MonthCreation#monthCreationDrag} * @param {object} dragEvent - drag event data */ MonthCreation.prototype._onDrag = function(dragEvent) { var eventData; if (!this.getScheduleData) { return; } eventData = this.getScheduleData(dragEvent.originEvent); if (!eventData) { return; } /** * @event {MonthCreation#monthCreationDrag} * @type {object} * @property {number} x - x index * @property {number} y - y index * @property {Date} date - drag date */ this.fire('monthCreationDrag', eventData); }; /** * DragEnd event handler * @fires {MonthCreation#monthCreationDragend} * @param {object} dragEndEvent - drag end event data */ MonthCreation.prototype._onDragEnd = function(dragEndEvent) { var cache = this._cache; var eventData; var times; this.dragHandler.off({ drag: this._onDrag, dragEnd: this._onDragEnd }, this); if (!this.getScheduleData) { return; } eventData = this.getScheduleData(dragEndEvent.originEvent); if (eventData) { cache.end = new TZDate(eventData.date); cache.isAllDay = true; times = [ cache.start, cache.end ].sort(array.compare.num.asc); cache.start = new TZDate(times[0]); cache.end = datetime.end(times[1]); this._createSchedule(cache); } /** * @event {MonthCreation#monthCreationDragend} * @type {object} * @property {number} x - x index * @property {number} y - y index * @property {Date} date - drag date */ this.fire('monthCreationDragend', eventData); this.getScheduleData = this._cache = null; }; /** * Dblclick event handler * @fires {MonthCreation#monthCreationDragstart} * @param {MouseEvent} e - Native MouseEvent */ MonthCreation.prototype._onDblClick = function(e) { var eventData, range; if (!isElementWeekdayGrid(e.target)) { return; } eventData = getMousePosDate(this.monthView)(e); this.fire('monthCreationClick', eventData); range = this._adjustStartAndEndTime(new TZDate(eventData.date), new TZDate(eventData.date)); this._createSchedule({ start: range.start, end: range.end, isAllDay: false, triggerEvent: eventData.triggerEvent }); this._requestOnClick = false; }; /** * Click event handler * @fires {MonthCreation#monthCreationDragstart} * @param {MouseEvent} e - Native MouseEvent */ MonthCreation.prototype._onClick = function(e) { var self = this; var eventData, range; if (!isElementWeekdayGrid(e.target) || this._disableClick) { return; } eventData = getMousePosDate(this.monthView)(e.originEvent); this._requestOnClick = true; setTimeout(function() { if (self._requestOnClick) { self.fire('monthCreationClick', eventData); range = self._adjustStartAndEndTime(new TZDate(eventData.date), new TZDate(eventData.date)); self._createSchedule({ start: range.start, end: range.end, isAllDay: false, triggerEvent: eventData.triggerEvent }); } self._requestOnClick = false; }, CLICK_DELAY); }; /** * Adjust time to our o'clock * @param {TZDate} start - start time * @param {TZDate} end - end time * @returns {Object} start and end */ MonthCreation.prototype._adjustStartAndEndTime = function(start, end) { var now = new TZDate(); var hours = now.getHours(); var minutes = now.getMinutes(); // adjust start to less time. Adjusting had been greater time in monthly view when clicking grid if (minutes <= 30) { minutes = 0; } else { minutes = 30; } start.setHours(hours, minutes, 0, 0); end.setHours(hours + 1, minutes, 0, 0); return { start: start, end: end }; }; /** * Invoke creation click * @param {Schedule} schedule - schedule instance */ MonthCreation.prototype.invokeCreationClick = function(schedule) { var eventData = { model: schedule }; this.fire('monthCreationClick', eventData); this._createSchedule({ start: schedule.start, end: schedule.end, isAllDay: schedule.isAllDay, triggerEvent: 'manual' }); }; /** * Returns whether the given element is Weekday-Schedule. * @param {HTMLElement} el - target element * @returns {boolean} */ function isElementWeekdayGrid(el) { return domutil.closest(el, config.classname('.weekday-grid')) && !domutil.closest(el, config.classname('.weekday-exceed-in-month')); } util.CustomEvents.mixin(MonthCreation); module.exports = MonthCreation;