UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,530 lines (1,200 loc) 107 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); require('./kendo.core.js'); require('./kendo.toolbar.js'); require('./kendo.licensing.js'); require('@progress/kendo-licensing'); require('./kendo.splitbutton.js'); require('./kendo.html.button.js'); require('./kendo.html.base.js'); require('./kendo.icons.js'); require('./kendo.html.icon.js'); require('@progress/kendo-svg-icons'); require('./kendo.button.menu.js'); require('./kendo.popup.js'); require('./kendo.dropdownbutton.js'); require('./kendo.buttongroup.js'); require('./kendo.togglebutton.js'); require('./kendo.button.js'); require('./kendo.badge.js'); require('./kendo.menu.js'); require('./kendo.data.js'); require('./kendo.data.odata.js'); require('./kendo.data.xml.js'); const __meta__ = { id: "scheduler.view", name: "Scheduler View", category: "web", description: "The Scheduler Common View", depends: [ "core", "toolbar" ], hidden: true }; kendo.ui.scheduler = {}; (function($) { var kendo = window.kendo, ui = kendo.ui, getDate = kendo.date.getDate, Widget = ui.Widget, outerHeight = kendo._outerHeight, keys = kendo.keys, NS = ".kendoSchedulerView", INVERSE_COLOR_CLASS = "k-event-inverse", ONGOING_CLASS = "k-event-ongoing", MIN_HORIZONTAL_SCROLL_SIZE = 1024, math = Math, SPACE = " ", DOT = "."; function levels(values, key) { var result = []; function collect(depth, values) { values = values[key]; if (values) { var level = result[depth] = result[depth] || []; for (var idx = 0; idx < values.length; idx++) { level.push(values[idx]); collect(depth + 1, values[idx]); } } } collect(0, values); return result; } function table(tableRows, className) { if (!tableRows.length) { return ""; } return '<table role="presentation" class="' + kendo.trim('k-scheduler-table ' + (className || "")) + '">' + '<tr>' + tableRows.join("</tr><tr>") + '</tr>' + '</table>'; } function allDayTable(tableRows, className) { if (!tableRows.length) { return ""; } return `<div ${kendo.attr("style-position")}="relative">${table(tableRows, className)}</div>`; } function timesHeader(columnLevelCount, allDaySlot, rowCount) { var tableRows = []; if (rowCount > 0) { for (var idx = 0; idx < columnLevelCount; idx++) { tableRows.push("<th class='k-scheduler-cell'>&#8203;</th>"); } } if (allDaySlot) { tableRows.push('<th class="k-scheduler-times-all-day k-scheduler-cell">' + allDaySlot.text + '</th>'); } if (rowCount < 1) { return $(); } return $('<div class="k-scheduler-times">' + table(tableRows) + '</div>'); } function content() { return $( '<div class="k-scheduler-content">' + '<table role="presentation" class="k-scheduler-table"></table>' + '</div>' ); } var HINT = '<div class="k-marquee k-scheduler-marquee">' + '<div class="k-marquee-color"></div>' + '<div class="k-marquee-text">' + '<div class="k-label-top"></div>' + '<div class="k-label-bottom"></div>' + '</div>' + '</div>'; var ResourceView = kendo.Class.extend({ init: function(index, isRtl, enforceAllDaySlot) { this._index = index; this._timeSlotCollections = []; this._daySlotCollections = []; this._isRtl = isRtl; this._enforceAllDaySlot = enforceAllDaySlot; }, addTimeSlotCollection: function(startDate, endDate) { return this._addCollection(startDate, endDate, this._timeSlotCollections); }, addDaySlotCollection: function(startDate, endDate) { return this._addCollection(startDate, endDate, this._daySlotCollections); }, _addCollection: function(startDate, endDate, collections) { var collection = new SlotCollection(startDate, endDate, this._index, collections.length); collections.push(collection); return collection; }, timeSlotCollectionCount: function() { return this._timeSlotCollections.length; }, daySlotCollectionCount: function() { return this._daySlotCollections.length; }, _refreshSlotCollections: function() { var slotCollections = [this._timeSlotCollections || [], this._daySlotCollections || []]; for (var slotCollectionIndex = 0; slotCollectionIndex < slotCollections.length; slotCollectionIndex++) { var collections = slotCollections[slotCollectionIndex]; for (var collectionIndex = 0; collectionIndex < collections.length; collectionIndex++) { var collection = collections[collectionIndex]; collection.refresh(); } } }, daySlotByPosition: function(x, y, byDate) { return this._slotByPosition(x, y, this._daySlotCollections, byDate); }, timeSlotByPosition: function(x, y, byDate) { return this._slotByPosition(x, y, this._timeSlotCollections, byDate); }, _slotByPosition: function(x, y, collections, byDate) { for (var collectionIndex = 0; collectionIndex < collections.length; collectionIndex++) { var collection = collections[collectionIndex]; for (var slotIndex = 0; slotIndex < collection.count(); slotIndex++) { var slot = collection.at(slotIndex); var width = slot.offsetWidth; var height = slot.offsetHeight; var nextSlot; var horizontalEnd = slot.offsetLeft + width; var verticalEnd = slot.offsetTop + height; if (!byDate) { nextSlot = collection.at(slotIndex + 1); } if (nextSlot) { if (nextSlot.offsetLeft != slot.offsetLeft) { if (this._isRtl) { horizontalEnd = slot.offsetLeft + (slot.offsetLeft - nextSlot.offsetLeft); } else { horizontalEnd = nextSlot.offsetLeft; } } else { verticalEnd = nextSlot.offsetTop; } } if (x >= slot.offsetLeft && x < horizontalEnd && y >= slot.offsetTop && y < verticalEnd) { return slot; } } } }, refresh: function() { var collectionIndex; for (collectionIndex = 0; collectionIndex < this._daySlotCollections.length; collectionIndex++) { this._daySlotCollections[collectionIndex].refresh(); } for (collectionIndex = 0; collectionIndex < this._timeSlotCollections.length; collectionIndex++) { this._timeSlotCollections[collectionIndex].refresh(); } }, timeSlotRanges: function(startTime, endTime) { var collections = this._timeSlotCollections; var start = this._startSlot(startTime, collections); var firstIndex, lastIndex; if (!start.inRange && startTime >= start.slot.end) { firstIndex = start.slot.collectionIndex + 1; start = null; } var end = start; if (startTime < endTime) { end = this._endSlot(endTime, collections); } if (end && !end.inRange && endTime <= end.slot.start) { lastIndex = end.slot.collectionIndex; if (endTime === end.slot.start && ((start && lastIndex > start.slot.collectionIndex) || (lastIndex > firstIndex))) { lastIndex -= 1; } end = null; } if (start === null && end === null) { if (endTime - startTime < kendo.date.MS_PER_DAY) { return []; } else { start = { inRange: true, slot: collections[firstIndex].first() }; end = { inRange: true, slot: collections[lastIndex].last() }; } } if (start === null) { if (end.slot.end <= startTime) { return []; } start = { inRange: true, slot: (collections[firstIndex] || collections[end.slot.collectionIndex]).first() }; } if (end === null) { if (start.slot.start >= endTime) { return []; } end = { inRange: true, slot: (collections[lastIndex] || collections[start.slot.collectionIndex]).last() }; } return this._continuousRange(TimeSlotRange, collections, start, end); }, daySlotRanges: function(startTime, endTime, isAllDay) { var collections = this._daySlotCollections; var start = this._startSlot(startTime, collections, isAllDay); if (!start.inRange && startTime >= start.slot.end) { start = null; } var end = start; if (startTime < endTime) { end = this._endSlot(endTime, collections, isAllDay); } if (end && !end.inRange && endTime <= end.slot.start) { end = null; } if (start === null && end === null) { return []; } if (start === null) { if (end.slot.end <= startTime) { return []; } do { startTime += kendo.date.MS_PER_DAY; start = this._startSlot(startTime, collections, isAllDay); } while (!start.inRange && startTime >= start.slot.end); } if (end === null) { if (start.slot.start >= endTime) { return []; } do { endTime -= kendo.date.MS_PER_DAY; end = this._endSlot(endTime, collections, isAllDay); } while (!end.inRange && endTime <= end.slot.start); } return this._continuousRange(DaySlotRange, collections, start, end); }, _continuousRange: function(range, collections, start, end) { var startSlot = start.slot; var endSlot = end.slot; var startIndex = startSlot.collectionIndex; var endIndex = endSlot.collectionIndex; var ranges = []; for (var collectionIndex = startIndex; collectionIndex <= endIndex; collectionIndex++) { var collection = collections[collectionIndex]; var first = collection.first(); var last = collection.last(); var head = false; var tail = false; if (collectionIndex == startIndex) { tail = !start.inRange; } if (collectionIndex == endIndex) { head = !end.inRange; } if (first.start < startSlot.start) { first = startSlot; } if (last.start > endSlot.start) { last = endSlot; } if (startIndex < endIndex) { if (collectionIndex == startIndex) { head = true; } else if (collectionIndex == endIndex) { tail = true; } else { head = tail = true; } } ranges.push(new range({ start: first, end: last, collection: collection, head: head, tail: tail })); } return ranges; }, slotRanges: function(event, isDay) { var startTime = event._startTime || kendo.date.toUtcTime(event.start); var endTime = event._endTime || kendo.date.toUtcTime(event.end); if (isDay === undefined) { if (this._enforceAllDaySlot) { isDay = event.isMultiDay(); } else { isDay = event.isAllDay; } } if (isDay) { return this.daySlotRanges(startTime, endTime, event.isAllDay); } return this.timeSlotRanges(startTime, endTime); }, ranges: function(startTime, endTime, isDay, isAllDay) { if (typeof startTime != "number") { startTime = kendo.date.toUtcTime(startTime); } if (typeof endTime != "number") { endTime = kendo.date.toUtcTime(endTime); } if (isDay) { return this.daySlotRanges(startTime, endTime, isAllDay); } return this.timeSlotRanges(startTime, endTime); }, _startCollection: function(date, collections) { for (var collectionIndex = 0; collectionIndex < collections.length; collectionIndex++) { var collection = collections[collectionIndex]; if (collection.startInRange(date)) { return collection; } } return null; }, _endCollection: function(date, collections, isAllDay) { for (var collectionIndex = 0; collectionIndex < collections.length; collectionIndex++) { var collection = collections[collectionIndex]; if (collection.endInRange(date, isAllDay)) { return collection; } } return null; }, _getCollections: function(isDay) { return isDay ? this._daySlotCollections : this._timeSlotCollections; }, continuousSlot: function(slot, reverse) { var pad = reverse ? -1 : 1; var collections = this._getCollections(slot.isDaySlot); var collection = collections[slot.collectionIndex + pad]; return collection ? collection[reverse ? "last" : "first"]() : undefined; }, firstSlot: function() { var collections = this._getCollections(this.daySlotCollectionCount()); return collections[0].first(); }, lastSlot: function() { var collections = this._getCollections(this.daySlotCollectionCount()); return collections[collections.length - 1].last(); }, upSlot: function(slot, keepCollection, groupByDateVertically) { var that = this; var moveToDaySlot = function(isDaySlot, collectionIndex, index) { var isFirstCell = index === 0; if (!keepCollection && !isDaySlot && isFirstCell && that.daySlotCollectionCount()) { return that._daySlotCollections[0].at(collectionIndex); } }; if (!this.timeSlotCollectionCount()) { keepCollection = true; } return this._verticalSlot(slot, -1, moveToDaySlot, groupByDateVertically); }, downSlot: function(slot, keepCollection, groupByDateVertically) { var that = this; var moveToTimeSlot = function(isDaySlot, collectionIndex, index) { if (!keepCollection && isDaySlot && that.timeSlotCollectionCount()) { return that._timeSlotCollections[index].at(0); } }; if (!this.timeSlotCollectionCount()) { keepCollection = true; } return this._verticalSlot(slot, 1, moveToTimeSlot, groupByDateVertically); }, leftSlot: function(slot, groupByDateVertically) { return this._horizontalSlot(slot, -1, groupByDateVertically); }, rightSlot: function(slot, groupByDateVertically) { return this._horizontalSlot(slot, 1, groupByDateVertically); }, _horizontalSlot: function(slot, step, groupByDateVertically) { var index = slot.index; var isDaySlot = slot.isDaySlot; var collectionIndex = slot.collectionIndex; var collections = this._getCollections(isDaySlot); isDaySlot = groupByDateVertically ? false : isDaySlot; if (isDaySlot) { index += step; } else { collectionIndex += step; } var collection = collections[collectionIndex]; return collection ? collection.at(index) : undefined; }, _verticalSlot: function(slot, step, swapCollection, groupByDateVertically) { var index = slot.index; var isDaySlot = slot.isDaySlot; var collectionIndex = slot.collectionIndex; var collections = this._getCollections(isDaySlot); slot = swapCollection(isDaySlot, collectionIndex, index); if (slot) { return slot; } isDaySlot = groupByDateVertically ? false : isDaySlot; if (isDaySlot) { collectionIndex += step; } else { index += step; } var collection = collections[collectionIndex]; return collection ? collection.at(index) : undefined; }, _collection: function(index, multiday) { var collections = multiday ? this._daySlotCollections : this._timeSlotCollections; return collections[index]; }, _startSlot: function(time, collections, isAllDay) { var collection = this._startCollection(time, collections); var inRange = true; var index = 0; if (!collection) { collection = collections[index]; while (index < collections.length - 1 && collection._start < time) { index++; collection = collections[index]; } inRange = false; } var slot = collection.slotByStartDate(time, isAllDay); if (!slot) { slot = collection.first(); inRange = false; } return { slot: slot, inRange: inRange }; }, _endSlot: function(time, collections, isAllDay) { var collection = this._endCollection(time, collections, isAllDay); var inRange = true; var index = collections.length - 1; if (!collection) { collection = collections[index]; while (index > 0 && collection._start > time) { index--; collection = collections[index]; } inRange = false; } var slot = collection.slotByEndDate(time, isAllDay); if (!slot) { if (time <= collection.first().start) { slot = collection.first(); } else { slot = collection.last(); } inRange = false; } return { slot: slot, inRange: inRange }; }, getSlotCollection: function(index, isDay) { return this[isDay ? "getDaySlotCollection" : "getTimeSlotCollection"](index); }, getTimeSlotCollection: function(index) { return this._timeSlotCollections[index]; }, getDaySlotCollection: function(index) { return this._daySlotCollections[index]; } }); var SlotRange = kendo.Class.extend({ init: function(options) { $.extend(this, options); }, innerHeight: function() { var collection = this.collection; var startIndex = this.start.index; var endIndex = this.end.index; var result = 0; for (var slotIndex = startIndex; slotIndex <= endIndex; slotIndex++) { result += collection.at(slotIndex).offsetHeight; } return result; }, events: function() { return this.collection.events(); }, addEvent: function(event) { this.events().push(event); }, startSlot: function() { if (this.start.offsetLeft > this.end.offsetLeft) { return this.end; } return this.start; }, endSlot: function() { if (this.start.offsetLeft > this.end.offsetLeft) { return this.start; } return this.end; } }); var TimeSlotRange = SlotRange.extend({ innerHeight: function() { var collection = this.collection; var startIndex = this.start.index; var endIndex = this.end.index; var result = 0; for (var slotIndex = startIndex; slotIndex <= endIndex; slotIndex++) { result += collection.at(slotIndex).offsetHeight; } return result; }, outerRect: function(start, end, snap) { return this._rect("offset", start, end, snap); }, _rect: function(property, start, end, snap) { var top; var bottom; var left; var right; var startSlot = this.start; var endSlot = this.end; var isRtl = kendo.support.isRtl(startSlot.element); if (typeof start != "number") { start = kendo.date.toUtcTime(start); } if (typeof end != "number") { end = kendo.date.toUtcTime(end); } if (snap) { top = startSlot.offsetTop; bottom = endSlot.offsetTop + endSlot[property + "Height"]; if (isRtl) { left = endSlot.offsetLeft; right = startSlot.offsetLeft + startSlot[property + "Width"]; } else { left = startSlot.offsetLeft; right = endSlot.offsetLeft + endSlot[property + "Width"]; } } else { var startOffset = start - startSlot.start; if (startOffset < 0) { startOffset = 0; } var startSlotDuration = startSlot.end - startSlot.start; top = startSlot.offsetTop + startSlot[property + "Height"] * startOffset / startSlotDuration; var endOffset = endSlot.end - end; if (endOffset < 0) { endOffset = 0; } var endSlotDuration = endSlot.end - endSlot.start; bottom = endSlot.offsetTop + endSlot[property + "Height"] - endSlot[property + "Height"] * endOffset / endSlotDuration; if (isRtl) { left = Math.round(endSlot.offsetLeft + endSlot[property + "Width"] * endOffset / endSlotDuration); right = Math.round(startSlot.offsetLeft + startSlot[property + "Width"] - startSlot[property + "Width"] * startOffset / startSlotDuration); } else { left = Math.round(startSlot.offsetLeft + startSlot[property + "Width"] * startOffset / startSlotDuration); right = Math.round(endSlot.offsetLeft + endSlot[property + "Width"] - endSlot[property + "Width"] * endOffset / endSlotDuration); } } return { top: top, bottom: bottom, //first column has no left border left: left === 0 ? left : left + 1, right: right }; }, innerRect: function(start, end, snap) { return this._rect("client", start, end, snap); } }); var DaySlotRange = SlotRange.extend({ innerWidth: function() { var collection = this.collection; var startIndex = this.start.index; var endIndex = this.end.index; var result = 0; var width = startIndex !== endIndex ? "offsetWidth" : "clientWidth"; for (var slotIndex = startIndex; slotIndex <= endIndex; slotIndex++) { result += collection.at(slotIndex)[width]; } return result; } }); var SlotCollection = kendo.Class.extend({ init: function(startDate, endDate, groupIndex, collectionIndex) { this._slots = []; this._events = []; this._start = kendo.date.toUtcTime(startDate); this._end = kendo.date.toUtcTime(endDate); this._groupIndex = groupIndex; this._collectionIndex = collectionIndex; }, refresh: function() { for (var slotIndex = 0; slotIndex < this._slots.length; slotIndex++) { this._slots[slotIndex].refresh(); } }, startInRange: function(date) { return this._start <= date && date < this._end; }, endInRange: function(date, isAllDay) { var end = isAllDay ? date < this._end : date <= this._end; return this._start <= date && end; }, slotByStartDate: function(date) { var time = date; if (typeof time != "number") { time = kendo.date.toUtcTime(date); } for (var slotIndex = 0; slotIndex < this._slots.length; slotIndex++) { var slot = this._slots[slotIndex]; if (slot.startInRange(time)) { return slot; } } return null; }, slotByEndDate: function(date, allday) { var time = date; if (typeof time != "number") { time = kendo.date.toUtcTime(date); } if (allday) { return this.slotByStartDate(date, false); } for (var slotIndex = 0; slotIndex < this._slots.length; slotIndex++) { var slot = this._slots[slotIndex]; if (slot.endInRange(time)) { return slot; } } return null; }, count: function() { return this._slots.length; }, events: function() { return this._events; }, addTimeSlot: function(element, start, end, isHorizontal) { var slot = new TimeSlot(element, start, end, this._groupIndex, this._collectionIndex, this._slots.length, isHorizontal); this._slots.push(slot); }, addDaySlot: function(element, start, end, eventCount) { var slot = new DaySlot(element, start, end, this._groupIndex, this._collectionIndex, this._slots.length, eventCount); this._slots.push(slot); }, first: function() { return this._slots[0]; }, last: function() { return this._slots[this._slots.length - 1]; }, at: function(index) { return this._slots[index]; } }); var Slot = kendo.Class.extend({ init: function(element, start, end, groupIndex, collectionIndex, index) { this.element = element; this.clientWidth = element.clientWidth; this.clientHeight = element.clientHeight; this.offsetWidth = element.offsetWidth; this.offsetHeight = element.offsetHeight; this.offsetTop = element.offsetTop; this.offsetLeft = element.offsetLeft; this.start = start; this.end = end; this.element = element; this.groupIndex = groupIndex; this.collectionIndex = collectionIndex; this.index = index; this.isDaySlot = false; }, refresh: function() { var element = this.element; this.clientWidth = element.clientWidth; this.clientHeight = element.clientHeight; this.offsetWidth = element.offsetWidth; this.offsetHeight = element.offsetHeight; this.offsetTop = element.offsetTop; this.offsetLeft = element.offsetLeft; }, startDate: function() { return kendo.timezone.toLocalDate(this.start); }, endDate: function() { return kendo.timezone.toLocalDate(this.end); }, startInRange: function(date) { return this.start <= date && date < this.end; }, endInRange: function(date) { return this.start < date && date <= this.end; }, startOffset: function() { return this.start; }, endOffset: function() { return this.end; } }); var TimeSlot = Slot.extend({ init: function(element, start, end, groupIndex, collectionIndex, index, isHorizontal) { Slot.fn.init.apply(this, arguments); this.isHorizontal = isHorizontal ? true : false; }, offsetX: function(rtl, offset) { if (rtl) { return this.offsetLeft + offset; } else { return this.offsetLeft + offset; } }, startInRange: function(date) { return this.start <= date && date < this.end; }, endInRange: function(date) { return this.start < date && date <= this.end; }, startOffset: function(x, y, snap) { if (snap) { return this.start; } var offset = $(this.element).offset(); var duration = this.end - this.start; var difference; var time; if (this.isHorizontal) { //need update var isRtl = kendo.support.isRtl(this.element); difference = x - offset.left; time = Math.floor(duration * ( difference / this.offsetWidth)); if (isRtl) { return this.start + duration - time; } } else { difference = y - offset.top; time = Math.floor(duration * ( difference / this.offsetHeight)); } return this.start + time; }, endOffset: function(x, y, snap) { if (snap) { return this.end; } var offset = $(this.element).offset(); var duration = this.end - this.start; var difference; var time; if (this.isHorizontal) { //need update var isRtl = kendo.support.isRtl(this.element); difference = x - offset.left; time = Math.floor(duration * ( difference / this.offsetWidth)); if (isRtl) { return this.start + duration - time; } } else { difference = y - offset.top; time = Math.floor(duration * ( difference / this.offsetHeight)); } return this.start + time; } }); var DaySlot = Slot.extend({ init: function(element, start, end, groupIndex, collectionIndex, index, eventCount) { Slot.fn.init.apply(this, arguments); this.eventCount = eventCount; this.isDaySlot = true; if (this.element.children.length) { var firstChild = this.element.children[0]; this.firstChildHeight = firstChild.offsetHeight; this.firstChildTop = firstChild.offsetTop; } else { this.firstChildHeight = 3; this.firstChildTop = 0; } }, startDate: function() { var date = new Date(this.start); return kendo.timezone.apply(date, "Etc/UTC"); }, endDate: function() { var date = new Date(this.end); return kendo.timezone.apply(date, "Etc/UTC"); }, startInRange: function(date) { return this.start <= date && date < this.end; }, endInRange: function(date) { return this.start < date && date <= this.end; } }); kendo.ui.SchedulerView = Widget.extend({ init: function(element, options) { Widget.fn.init.call(this, element, $.extend({}, this.options, options)); this._normalizeOptions(); this._initDefaultTools(); this._scrollbar = kendo.support.scrollbar(); this._isRtl = kendo.support.isRtl(element); this._resizeHint = $(); this._moveHint = $(); this._cellId = kendo.guid(); this._resourcesForGroups(); this._selectedSlots = []; this.element.attr("role", "application"); }, options: { messages: { ariaEventLabel: { on: "on", at: "at", to: "to", allDay: "(all day)", prefix: "" } } }, visibleEndDate: function() { return this.endDate(); }, _initDefaultTools: function() { this._defaultTools = { todayMobile: { type: "button", fillMode: "flat", text: this.options.messages.today, click: this._footerTodayClickHandler.bind(this), attributes: { class: "k-scheduler-today" } }, fulldayDesktop: { type: "button", icon: "clock", text: this.options.showWorkHours ? this.options.messages.showFullDay : this.options.messages.showWorkDay, click: this.toggleFullDay ? this.toggleFullDay.bind(this) : $.noop, attributes: { class: "k-scheduler-fullday" } }, fulldayMobile: { type: "button", fillMode: "flat", text: this.options.showWorkHours ? this.options.messages.showFullDay : this.options.messages.showWorkDay, click: this.toggleFullDay ? this.toggleFullDay.bind(this) : $.noop, attributes: { class: "k-scheduler-fullday" } } }; }, _normalizeOptions: function() { var options = this.options; if (options.startTime) { options.startTime.setMilliseconds(0); } if (options.endTime) { options.endTime.setMilliseconds(0); } if (options.workDayStart) { options.workDayStart.setMilliseconds(0); } if (options.workDayEnd) { options.workDayEnd.setMilliseconds(0); } }, _isMobile: function() { var options = this.options; return (options.mobile === true && kendo.support.mobileOS) || options.mobile === "phone" || options.mobile === "tablet"; }, _addResourceView: function() { var resourceView = new ResourceView(this.groups.length, this._isRtl, this.options.enforceAllDaySlot); this.groups.push(resourceView); return resourceView; }, _refreshResourceViews: function() { var groups = this.groups; if (groups) { for (var i = 0; i < groups.length; i++) { groups[i]._refreshSlotCollections(); } } }, dateForTitle: function() { return kendo.format(this.options.selectedDateFormat, this.startDate(), this.endDate()); }, shortDateForTitle: function() { return kendo.format(this.options.selectedShortDateFormat, this.startDate(), this.endDate()); }, mobileDateForTitle: function() { return kendo.format(this.options.selectedMobileDateFormat || this.options.selectedShortDateFormat, this.startDate(), this.endDate()); }, _changeGroup: function(selection, previous) { var method = previous ? "prevGroupSlot" : "nextGroupSlot"; var slot = this[method](selection.start, selection.groupIndex, selection.isAllDay); if (slot) { selection.groupIndex += previous ? -1 : 1; } if (this._isGroupedByDate() && !slot) { selection.groupIndex = previous ? this.groups.length - 1 : 0; } return slot; }, _changeDate: function(selection, slot, previous) { var group = this.groups[selection.groupIndex]; var collections, index; if (previous) { collections = group._getCollections(false); index = group.daySlotCollectionCount() ? slot.index - 1 : slot.collectionIndex - 1; if (index >= 0) { return collections[index]._slots[collections[index]._slots.length - 1]; } } else { collections = group._getCollections(group.daySlotCollectionCount()); index = group.daySlotCollectionCount() ? 0 : slot.collectionIndex + 1; var slotIndex = group.daySlotCollectionCount() ? slot.collectionIndex + 1 : 0; if (collections[index] && collections[index]._slots[slotIndex]) { return collections[index]._slots[slotIndex]; } } }, _changeGroupContinuously: function() { return null; }, _changeViewPeriod: function() { return false; }, _isInRange: function(newStart, newEnd) { if (!newStart || !newEnd || !this.options.min || !this.options.max) { return false; } return getDate(newStart) <= getDate(this.options.min) || getDate(newEnd) >= getDate(this.options.max); }, _horizontalSlots: function(selection, ranges, multiple, reverse) { var method = reverse ? "leftSlot" : "rightSlot"; var horizontalRange = { startSlot: ranges[0].start, endSlot: ranges[ranges.length - 1].end }; var group = this.groups[selection.groupIndex]; var isVertical = this._isVerticallyGrouped(); if (!multiple) { var slot = this._normalizeHorizontalSelection(selection, ranges, reverse); if (slot) { horizontalRange.startSlot = horizontalRange.endSlot = slot; } } if (this._isGroupedByDate() && !multiple) { var tempSlot = this._changeGroup(selection, reverse); if (!tempSlot) { horizontalRange = this._getNextHorizontalRange(group, method, horizontalRange); } else { horizontalRange.startSlot = horizontalRange.endSlot = tempSlot; } } else { horizontalRange.startSlot = group[method](horizontalRange.startSlot); horizontalRange.endSlot = group[method](horizontalRange.endSlot); if (!multiple && !isVertical && (!horizontalRange.startSlot || !horizontalRange.endSlot)) { horizontalRange.startSlot = horizontalRange.endSlot = this._changeGroup(selection, reverse); } } var continuousSlot; if ((!horizontalRange.startSlot || !horizontalRange.endSlot) && !this._isGroupedByDate()) { continuousSlot = this._continuousSlot(selection, ranges, reverse); continuousSlot = this._changeGroupContinuously(selection, continuousSlot, multiple, reverse); if (continuousSlot) { horizontalRange.startSlot = horizontalRange.endSlot = continuousSlot; } } return horizontalRange; }, _getNextHorizontalRange: function(group, method, horizontalRange) { if (!this._isVerticallyGrouped()) { horizontalRange.startSlot = group[method](horizontalRange.startSlot); horizontalRange.endSlot = group[method](horizontalRange.endSlot); } return horizontalRange; }, _verticalSlots: function(selection, ranges, multiple, reverse) { var group = this.groups[selection.groupIndex]; var slot; var verticalRange = { startSlot: ranges[0].start, endSlot: ranges[ranges.length - 1].end }; if (!multiple) { slot = this._normalizeVerticalSelection(selection, ranges, reverse); if (slot) { verticalRange.startSlot = verticalRange.endSlot = slot; } } var method = reverse ? "upSlot" : "downSlot"; verticalRange = this._getNextVerticalRange(group, method, verticalRange, multiple); if (!multiple && this._isVerticallyGrouped() && (!verticalRange.startSlot || !verticalRange.endSlot)) { if (this._isGroupedByDate()) { verticalRange.startSlot = verticalRange.endSlot = this._changeDate(selection, slot, reverse); } else { verticalRange.startSlot = verticalRange.endSlot = this._changeGroup(selection, reverse); } } return verticalRange; }, _getNextVerticalRange: function(group, method, verticalRange, multiple) { verticalRange.startSlot = group[method](verticalRange.startSlot, multiple); verticalRange.endSlot = group[method](verticalRange.endSlot, multiple); return verticalRange; }, _normalizeHorizontalSelection: function() { return null; }, _normalizeVerticalSelection: function(selection, ranges, reverse) { var slot; if (reverse) { slot = ranges[0].start; } else { slot = ranges[ranges.length - 1].end; } return slot; }, _continuousSlot: function() { return null; }, _footerTodayClickHandler: function(e) { e.preventDefault(); var that = this; var options = that.options; var timezone = that.options.timezone; var action = "today"; var currentDate = new Date(); var date; if (timezone) { var timezoneOffset = kendo.timezone.offset(currentDate, timezone); date = kendo.timezone.convert(currentDate, currentDate.getTimezoneOffset(), timezoneOffset); } else { date = currentDate; } that.trigger("navigate", { view: that.name || options.name, action: action, date: date }); }, _footerItems: function() { var that = this, items = [], options = this.options; if (that._isMobile()) { items.push({ type: "button", fillMode: "flat", text: options.messages.today, click: that._footerTodayClickHandler.bind(that), attributes: { class: "k-scheduler-today" } }); } return items; }, _footer: function() { if (this.options.footer === false) { return; } var that = this, items = that._footerItems(); if (items.length > 0) { var html = $('<div class="k-scheduler-footer">'); that.footer = html.appendTo(that.element); that.footer.kendoToolBar({ resizable: false, items: items }); } }, constrainSelection: function(selection) { var group = this.groups[0]; var slot; if (!this.inRange(selection)) { slot = group.firstSlot(); selection.isAllDay = slot.isDaySlot; selection.start = slot.startDate(); selection.end = slot.endDate(); } else { if (!group.daySlotCollectionCount()) { selection.isAllDay = false; } else if (!group.timeSlotCollectionCount()) { selection.isAllDay = true; } } if (!this.groups[selection.groupIndex]) { selection.groupIndex = 0; } }, move: function(selection, key, shift) { var handled = false; var group = this.groups[selection.groupIndex]; var verticalByDate = this._isGroupedByDate() && this._isVerticallyGrouped(); if (!group.timeSlotCollectionCount()) { selection.isAllDay = true; } var ranges = group.ranges(selection.start, selection.end, selection.isAllDay, false); var startSlot, endSlot, reverse, slots; if (key === keys.DOWN || key === keys.UP) { handled = true; reverse = key === keys.UP; this._updateDirection(selection, ranges, shift, reverse, true); slots = this._verticalSlots(selection, ranges, shift, reverse); if (!slots.startSlot && !shift && this._changeViewPeriod(selection, reverse, !verticalByDate)) { return handled; } } else if (key === keys.LEFT || key === keys.RIGHT) { handled = true; reverse = key === keys.LEFT; this._updateDirection(selection, ranges, shift, reverse, false); slots = this._horizontalSlots(selection, ranges, shift, reverse); if (!slots.startSlot && !shift && this._changeViewPeriod(selection, reverse, verticalByDate)) { return handled; } } if (handled) { startSlot = slots.startSlot; endSlot = slots.endSlot; if (shift) { var backward = selection.backward; if (backward && startSlot) { selection.start = startSlot.startDate(); } else if (!backward && endSlot) { selection.end = endSlot.endDate(); } } else if (startSlot && endSlot) { selection.isAllDay = startSlot.isDaySlot; selection.start = startSlot.startDate(); selection.end = endSlot.endDate(); } selection.events = []; } return handled; }, moveToEventInGroup: function(group, slot, selectedEvents, prev) { var events = group._continuousEvents || []; var event; var pad = prev ? -1 : 1; var length = events.length; var idx = prev ? length - 1 : 0; var i, lastSelected; if (selectedEvents.length) { lastSelected = selectedEvents[selectedEvents.length - 1]; if (prev) { for (i = 0; i < events.length; i++) { if (events[i].uid === lastSelected) { idx = i + pad; } } } else { for (i = events.length - 1; i > -1; i--) { if (events[i].uid === lastSelected) { idx = i + pad; } } } }