UNPKG

@progress/kendo-ui

Version:

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

1,270 lines (1,037 loc) 192 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(1291); /***/ }), /***/ 3: /***/ (function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }), /***/ 1010: /***/ (function(module, exports) { module.exports = require("./kendo.dropdownlist"); /***/ }), /***/ 1012: /***/ (function(module, exports) { module.exports = require("./kendo.multiselect"); /***/ }), /***/ 1143: /***/ (function(module, exports) { module.exports = require("./kendo.window"); /***/ }), /***/ 1193: /***/ (function(module, exports) { module.exports = require("./kendo.pdf"); /***/ }), /***/ 1197: /***/ (function(module, exports) { module.exports = require("./kendo.datetimepicker"); /***/ }), /***/ 1198: /***/ (function(module, exports) { module.exports = require("./kendo.editable"); /***/ }), /***/ 1208: /***/ (function(module, exports) { module.exports = require("./kendo.pane"); /***/ }), /***/ 1291: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1010), __webpack_require__(1198), __webpack_require__(1012), __webpack_require__(1143), __webpack_require__(1197), __webpack_require__(1293), __webpack_require__(1294), __webpack_require__(1292), __webpack_require__(1295), __webpack_require__(1296), __webpack_require__(1297), __webpack_require__(1298), __webpack_require__(1208), __webpack_require__(1193), __webpack_require__(1299) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); })(function(){ var __meta__ = { // jshint ignore:line id: "scheduler", name: "Scheduler", category: "web", description: "The Scheduler is an event calendar.", depends: [ "dropdownlist", "editable", "multiselect", "window", "datepicker", "datetimepicker", "scheduler.recurrence", "scheduler.view" ], features: [ { id: "scheduler-dayview", name: "Scheduler Day View", description: "Scheduler Day View", depends: [ "scheduler.dayview" ] }, { id: "scheduler-agendaview", name: "Scheduler Agenda View", description: "Scheduler Agenda View", depends: [ "scheduler.agendaview" ] }, { id: "scheduler-monthview", name: "Scheduler Month View", description: "Scheduler Month View", depends: [ "scheduler.monthview" ] }, { id: "scheduler-timelineview", name: "Scheduler Timeline View", description: "Scheduler Timeline View", depends: [ "scheduler.timelineview" ] }, { id: "scheduler-mobile", name: "Scheduler adaptive rendering", description: "Support for adaptive rendering", depends: [ "dialog", "pane", "switch" ] }, { id: "scheduler-pdf-export", name: "PDF export", description: "Export the scheduler events as PDF", depends: [ "pdf", "drawing" ] }, { id: "scheduler-timezones", name: "Timezones", description: "Allow selecting timezones different than Etc/UTC", depends: [ "timezones" ] }] }; /*jshint eqnull: true */ (function($, undefined) { var kendo = window.kendo, date = kendo.date, MS_PER_DAY = date.MS_PER_DAY, getDate = date.getDate, getMilliseconds = kendo.date.getMilliseconds, recurrence = kendo.recurrence, keys = $.extend({F10: 121}, kendo.keys), ui = kendo.ui, Widget = ui.Widget, DataBoundWidget = ui.DataBoundWidget, STRING = "string", Popup = ui.Popup, Calendar = ui.Calendar, DataSource = kendo.data.DataSource, isPlainObject = $.isPlainObject, extend = $.extend, proxy = $.proxy, toString = Object.prototype.toString, isArray = $.isArray, NS = ".kendoScheduler", CLICK = "click", MOUSEDOWN = "mousedown", TOUCHSTART = kendo.support.pointers ? "pointerdown" : "touchstart", TOUCHMOVE = kendo.support.pointers ? "pointermove" : "touchmove", TOUCHEND = kendo.support.pointers ? "pointerup" : "touchend", MOUSEMOVE = kendo.support.mousemove, CHANGE = "change", PROGRESS = "progress", ERROR = "error", CANCEL = "cancel", REMOVE = "remove", RESET = "resetSeries", SAVE = "save", ADD = "add", EDIT = "edit", FOCUSEDSTATE = "k-state-focused", EXPANDEDSTATE = "k-state-expanded", VIEWSSELECTOR = ".k-scheduler-views", INVERSECOLORCLASS = "k-event-inverse", valueStartEndBoundRegex = /(?:value:start|value:end)(?:,|$)/, TODAY = getDate(new Date()), EXCEPTION_SEPARATOR = ",", OLD_EXCEPTION_SEPARATOR_REGEXP = /\;/g, RECURRENCE_EXCEPTION = "recurrenceException", DELETECONFIRM = "Are you sure you want to delete this event?", DELETERECURRING = "Do you want to delete only this event occurrence or the whole series?", EDITRECURRING = "Do you want to edit only this event occurrence or the whole series?", DELETERECURRINGCONFIRM = "Are you sure you want to delete this event occurrence?", RESETSERIESCONFIRM = "Are you sure you want to reset the whole series?", DELETESERIESCONFIRM = "Are you sure you want to delete the whole series?", COMMANDBUTTONTMPL = '<a class="k-button #=className#" #=attr# href="\\#">#=text#</a>', VIEWBUTTONTEMPLATE = kendo.template('<li class="k-current-view" data-#=ns#name="#=view#"><a role="button" href="\\#" class="k-link">${views[view].title}</a></li>'), TOOLBARTEMPLATE = kendo.template('<div class="k-floatwrap k-header k-scheduler-toolbar">' + '# if (pdf) { #' + '<ul class="k-reset k-scheduler-tools">' + '<li><a role="button" href="\\#" class="k-button k-pdf"><span class="k-icon k-i-file-pdf"></span>${messages.pdf}</a></li>' + '</ul>' + '# } #' + '<ul class="k-reset k-scheduler-navigation">' + '<li class="k-state-default k-header k-nav-today"><a role="button" href="\\#" class="k-link" title="${messages.today}">${messages.today}</a></li>' + '<li class="k-state-default k-header k-nav-prev"><a role="button" href="\\#" class="k-link" title="${messages.previous}" aria-label="${messages.previous}"><span class="k-icon k-i-arrow-60-left" style="pointer-events: none"></span></a></li>' + '<li class="k-state-default k-header k-nav-next"><a role="button" href="\\#" class="k-link" title="${messages.next}" aria-label="${messages.next}"><span class="k-icon k-i-arrow-60-right" style="pointer-events: none"></span></a></li>' + '<li class="k-state-default k-nav-current">' + '<a role="button" href="\\#" class="k-link">' + '<span class="k-icon k-i-calendar"></span>' + '<span class="k-sm-date-format" data-#=ns#bind="text: formattedShortDate"></span>' + '<span class="k-lg-date-format" data-#=ns#bind="text: formattedDate"></span>' + '</a>' + '</li>' + '</ul>' + '#if(viewsCount === 1){#' + '<a role="button" data-#=ns#name="#=view#" href="\\#" class="k-link k-scheduler-refresh">' + '<span class="k-icon k-i-reload"></span>' + '</a>' + '#}else{#' + '<ul class="k-reset k-header k-scheduler-views">' + '#for(var view in views){#' + '<li class="k-state-default k-view-#= view.toLowerCase() #" data-#=ns#name="#=view#"><a role="button" href="\\#" class="k-link">${views[view].title}</a></li>' + '#}#' + '</ul>' + '#}#' + '</div>'), MOBILETOOLBARTEMPLATE = kendo.template('<div class="k-header k-scheduler-toolbar">' + '<ul class="k-reset k-scheduler-tools">' + '# if (pdf) { #' + '<li><a role="button" href="\\#" class="k-button k-pdf"><span class="k-icon k-i-file-pdf"></span></a></li>' + '# } #' + '<li><a role="button" href="\\#" class="k-button k-nav-calendar"><span class="k-icon k-i-calendar"></span></a></li>' + "# if (editable) { #" + '<li><a role="button" href="\\#" class="k-button k-create-event"><span class="k-icon k-i-plus"></span></a></li>' + "# } #" + '</ul>' + '#if(viewsCount === 1){#' + '<a role="button" data-#=ns#name="#=view#" href="\\#" class="k-link k-scheduler-refresh">' + '<span class="k-icon k-i-reload"></span>' + '</a>' + '#}else{#' + '<select class="k-scheduler-mobile-views">' + '#for(var view in views){#' + '<option class="k-state-default k-view-#= view.toLowerCase() #" value="#=view#">${views[view].title}</option>' + '#}#' + '</select>' + '#}#' + '</div>'+ '<div class="k-header k-scheduler-toolbar">' + '<ul class="k-reset k-header k-scheduler-navigation">' + '<li class="k-state-default k-nav-prev"><a role="button" href="\\#" class="k-link"><span class="k-icon k-i-arrow-chevron-left"></span></a></li>' + '<li class="k-state-default k-nav-current">' + '<span class="k-m-date-format" data-#=ns#bind="text: formattedMobileDate"></span>' + '<span class="k-y-date-format" data-#=ns#bind="text: formattedYear"></span>' + '</li>' + '<li class="k-state-default k-nav-next"><a role="button" href="\\#" class="k-link"><span class="k-icon k-i-arrow-chevron-right"></span></a></li>' + '</ul>' + '</div>'), MOBILEDATERANGEEDITOR = function(container, options) { var attr = { name: options.field, title: options.title }; var isAllDay = options.model.isAllDay; var dateTimeValidate = kendo.attr("validate") + "='" + (!isAllDay) + "'"; var dateValidate = kendo.attr("validate") + "='" + isAllDay + "'"; appendTimezoneAttr(attr, options); appendValidDateValidator(attr, options); appendDateCompareValidator(attr, options); $('<input type="datetime-local" required ' + kendo.attr("type") + '="datetime-local" ' + kendo.attr("bind") + '="value:' + options.field +', invisible:isAllDay" ' + dateTimeValidate + '/>') .attr(attr) .appendTo(container); $('<input type="date" required ' + kendo.attr("type") + '="date" ' + kendo.attr("bind") + '="value:' + options.field +',visible:isAllDay" ' + dateValidate + '/>') .attr(attr).appendTo(container); $('<span ' + kendo.attr("for") + '="' + options.field + '" class="k-invalid-msg"/>').hide().appendTo(container); }, DATERANGEEDITOR = function(container, options) { var attr = { name: options.field, title: options.title }, isAllDay = options.model.isAllDay, dateTimeValidate = kendo.attr("validate") + "='" + (!isAllDay) + "' ", dateValidate = kendo.attr("validate") + "='" + isAllDay + "' "; appendTimezoneAttr(attr, options); appendValidDateValidator(attr, options); appendDateCompareValidator(attr, options); $('<input type="text" required ' + kendo.attr("type") + '="date"' + ' ' + kendo.attr("role") + '="datetimepicker" ' + kendo.attr("bind") + '="value:' + options.field +',invisible:isAllDay" ' + dateTimeValidate + '/>') .attr(attr).appendTo(container); $('<input type="text" required ' + kendo.attr("type") + '="date"' + ' ' + kendo.attr("role") + '="datepicker" ' + kendo.attr("bind") + '="value:' + options.field +',visible:isAllDay" ' + dateValidate + '/>') .attr(attr).appendTo(container); $('<span ' + kendo.attr("bind") + '="text: ' + options.field + 'Timezone"></span>').appendTo(container); if (options.field === "end") { $('<span ' + kendo.attr("bind") + '="text: startTimezone, invisible: endTimezone"></span>').appendTo(container); } $('<span ' + kendo.attr("for") + '="' + options.field + '" class="k-invalid-msg"/>').hide().appendTo(container); }, RECURRENCEEDITOR = function(container, options) { $('<div ' + kendo.attr("bind") + '="value:' + options.field +'" />') .attr({ name: options.field }) .appendTo(container) .kendoRecurrenceEditor({ start: options.model.start, timezone: options.timezone, messages: options.messages }); }, MOBILERECURRENCEEDITOR = function(container, options) { $('<div ' + kendo.attr("bind") + '="value:' + options.field +'" />') .attr({ name: options.field }) .appendTo(container) .kendoMobileRecurrenceEditor({ start: options.model.start, timezone: options.timezone, messages: options.messages, pane: options.pane, value: options.model[options.field] }); }, MOBILEISALLDAYEDITOR = function (container, options) { $('<input type="checkbox" data-role="switch"' + kendo.attr("bind") + '="value:' + options.field +'" />').appendTo(container); }, MOBILETIMEZONEPOPUP = function(container, options) { var text = timezoneButtonText(options.model, options.messages.noTimezone); $('<span class="k-timezone-label"></span>').text(text).appendTo(container); $('<span class="k-icon k-i-arrow-chevron-right"></span>').appendTo(container); container.closest("li.k-item label").click(options.click); }, TIMEZONEPOPUP = function(container, options) { $('<a href="#" class="k-button" data-bind="invisible:isAllDay">' + options.messages.timezoneEditorButton + '</a>').click(options.click).appendTo(container); }, MOBILETIMEZONEEDITOR = function(container, options) { $('<div class="k-mobiletimezoneeditor" ' + kendo.attr("bind") + '="value:' + options.field +'" />') .attr({ name: options.field }) .appendTo(container) .kendoMobileTimezoneEditor({ optionLabel: options.noTimezone }); }, TIMEZONEEDITOR = function(container, options) { var visible = options.visible || options.visible === undefined; $('<div ' + kendo.attr("bind") + '="value:' + options.field +'" />') .attr({ name: options.field }) .toggle(visible) .appendTo(container) .kendoTimezoneEditor({ optionLabel: options.noTimezone, title: options.title }); }; function timezoneButtonText(model, message) { message = message || ""; if (model.startTimezone) { message = model.startTimezone; if (model.endTimezone) { message += " | " + model.endTimezone; } } return message; } function appendTimezoneAttr(attrs, options) { var timezone = options.timezone; if (timezone) { attrs[kendo.attr("timezone")] = timezone; } } function appendValidDateValidator(attrs, options) { var validationRules = options.model.fields[options.field].validation; if (validationRules) { var validDateRule = validationRules.validDateValidator; if (validDateRule && isPlainObject(validDateRule) && validDateRule.message) { attrs[kendo.attr("validDate-msg")] = validDateRule.message; } } } function appendDateCompareValidator(attrs, options) { var validationRules = options.model.fields[options.field].validation; if (validationRules) { var dateCompareRule = validationRules.dateCompare; if (dateCompareRule && isPlainObject(dateCompareRule) && dateCompareRule.message) { attrs[kendo.attr("dateCompare-msg")] = dateCompareRule.message; } } } function wrapDataAccess(originalFunction, timezone) { return function(data) { data = originalFunction(data); convertData(data, "apply", timezone); return data || []; }; } function wrapDataSerialization(originalFunction, timezone) { return function(data) { if (data) { if (toString.call(data) !== "[object Array]" && !(data instanceof kendo.data.ObservableArray)) { data = [data]; } } convertData(data, "remove", timezone, true); data = originalFunction(data); return data || []; }; } function convertData(data, method, timezone, removeUid) { var event, idx, length; data = data || []; for (idx = 0, length = data.length; idx < length; idx++) { event = data[idx]; if (removeUid) { if (event.startTimezone || event.endTimezone) { if (timezone) { event.start = kendo.timezone.convert(event.start, event.startTimezone || event.endTimezone, timezone); event.end = kendo.timezone.convert(event.end, event.endTimezone || event.startTimezone, timezone); event.start = kendo.timezone[method](event.start, timezone); event.end = kendo.timezone[method](event.end, timezone); } else { event.start = kendo.timezone[method](event.start, event.startTimezone || event.endTimezone); event.end = kendo.timezone[method](event.end, event.endTimezone || event.startTimezone); } } else if (timezone) { event.start = kendo.timezone[method](event.start, timezone); event.end = kendo.timezone[method](event.end, timezone); } } else { if (event.startTimezone || event.endTimezone) { event.start = kendo.timezone[method](event.start, event.startTimezone || event.endTimezone); event.end = kendo.timezone[method](event.end, event.endTimezone || event.startTimezone); if (timezone) { event.start = kendo.timezone.convert(event.start, event.startTimezone || event.endTimezone, timezone); event.end = kendo.timezone.convert(event.end, event.endTimezone || event.startTimezone, timezone); } } else if (timezone) { event.start = kendo.timezone[method](event.start, timezone); event.end = kendo.timezone[method](event.end, timezone); } } if (removeUid) { delete event.uid; } } return data; } function getOccurrenceByUid(data, uid) { var length = data.length, idx = 0, event; for (; idx < length; idx++) { event = data[idx]; if (event.uid === uid) { return event; } } } var SchedulerDataReader = kendo.Class.extend({ init: function(schema, reader) { var timezone = schema.timezone; this.reader = reader; if (reader.model) { this.model = reader.model; } this.timezone = timezone; this.data = wrapDataAccess($.proxy(this.data, this), timezone); this.serialize = wrapDataSerialization($.proxy(this.serialize, this), timezone); }, errors: function(data) { return this.reader.errors(data); }, parse: function(data) { return this.reader.parse(data); }, data: function(data) { return this.reader.data(data); }, total: function(data) { return this.reader.total(data); }, groups: function(data) { return this.reader.groups(data); }, aggregates: function(data) { return this.reader.aggregates(data); }, serialize: function(data) { return this.reader.serialize(data); } }); function applyZone(date, fromZone, toZone) { if (toZone) { date = kendo.timezone.convert(date, fromZone, toZone); } else { date = kendo.timezone.remove(date, fromZone); } return date; } function validDateValidator(input) { if ((input.filter("[name=start]").length && input.filter("[title=Start]").length) || (input.filter("[name=end]").length && input.filter("[title=End]").length)) { var date; var picker = kendo.widgetInstance(input, kendo.ui); if (picker) { date = kendo.parseDate(input.val(), picker.options.format); return !!date && picker.value(); } else { date = kendo.parseDate(input.val()); return !!date; } } return true; } function dateCompareValidator(input) { if (input.filter("[name=end]").length) { var container = input.closest(".k-scheduler-edit-form"); var startInput = container.find("[name=start]:visible"); var endInput = container.find("[name=end]:visible"); if (endInput[0] && startInput[0]) { var start, end; var startPicker = kendo.widgetInstance(startInput, kendo.ui); var endPicker = kendo.widgetInstance(endInput, kendo.ui); var editable = container.data("kendoEditable"); var model = editable ? editable.options.model : null; if (startPicker && endPicker) { start = startPicker.value(); end = endPicker.value(); } else { start = kendo.parseDate(startInput.val()); end = kendo.parseDate(endInput.val()); } if (start && end) { if (model) { var timezone = startInput.attr(kendo.attr("timezone")); var startTimezone = model.startTimezone; var endTimezone = model.endTimezone; startTimezone = startTimezone || endTimezone; endTimezone = endTimezone || startTimezone; if (startTimezone) { start = applyZone(start, startTimezone, timezone); end = applyZone(end, endTimezone, timezone); } } return start <= end; } } } return true; } var SchedulerEvent = kendo.data.Model.define({ init: function(value) { var that = this; kendo.data.Model.fn.init.call(that, value); that._defaultId = that.defaults[that.idField]; }, _time: function(field) { var date = this[field]; var fieldTime = "_" + field + "Time"; if (this[fieldTime]) { return this[fieldTime] - kendo.date.toUtcTime(kendo.date.getDate(date)); } return getMilliseconds(date); }, _date: function(field) { var fieldTime = "_" + field + "Time"; if (this[fieldTime]) { return this[fieldTime] - this._time(field); } return kendo.date.getDate(this[field]); }, clone: function(options, updateUid) { var uid = this.uid, event = new this.constructor($.extend({}, this.toJSON(), options)); if (!updateUid) { event.uid = uid; } return event; }, duration: function() { var end = this.end; var start = this.start; var offset = (end.getTimezoneOffset() - start.getTimezoneOffset()) * kendo.date.MS_PER_MINUTE; return end - start - offset; }, expand: function(start, end, zone) { return recurrence ? recurrence.expand(this, start, end, zone) : [this]; }, update: function(eventInfo) { for (var field in eventInfo) { this.set(field, eventInfo[field]); } if (this._startTime) { this.set("_startTime", kendo.date.toUtcTime(this.start)); } if (this._endTime) { this.set("_endTime", kendo.date.toUtcTime(this.end)); } }, isMultiDay: function() { return this.isAllDay || this.duration() >= kendo.date.MS_PER_DAY; }, isException: function() { return !this.isNew() && this.recurrenceId; }, isOccurrence: function() { return this.isNew() && this.recurrenceId; }, isRecurring: function() { return !!(this.recurrenceRule || this.recurrenceId); }, isRecurrenceHead: function() { return !!(this.id && this.recurrenceRule); }, toOccurrence: function(options) { options = $.extend(options, { recurrenceException: null, recurrenceRule: null, recurrenceId: this.id || this.recurrenceId }); options[this.idField] = this.defaults[this.idField]; return this.clone(options, true); }, toJSON: function() { var obj = kendo.data.Model.fn.toJSON.call(this); obj.uid = this.uid; delete obj._startTime; delete obj._endTime; return obj; }, shouldSerialize: function(field) { return kendo.data.Model.fn.shouldSerialize.call(this, field) && field !== "_defaultId"; }, set: function(key, value) { var isAllDay = this.isAllDay || false; kendo.data.Model.fn.set.call(this, key, value); if (key == "isAllDay" && value != isAllDay) { var start = kendo.date.getDate(this.start); var end = new Date(this.end); var milliseconds = kendo.date.getMilliseconds(end); if (milliseconds === 0 && value) { milliseconds = MS_PER_DAY; } this.set("start", start); if (value === true) { kendo.date.setTime(end, -milliseconds); if (end < start) { end = start; } } else { kendo.date.setTime(end, MS_PER_DAY - milliseconds); } this.set("end", end); } }, id: "id", fields: { id: { type: "number" }, title: { defaultValue: "", type: "string" }, start: { type: "date", validation: { required: true, validDate: { value: validDateValidator } } }, startTimezone: { type: "string" }, end: { type: "date", validation: { required: true, validDate: { value: validDateValidator }, dateCompare: { value: dateCompareValidator } } }, endTimezone: { type: "string" }, recurrenceRule: { defaultValue: "", type: "string" }, recurrenceException: { defaultValue: "", type: "string" }, isAllDay: { type: "boolean", defaultValue: false }, description: { type: "string" } } }); var SchedulerDataSource = DataSource.extend({ init: function(options) { DataSource.fn.init.call(this, extend(true, {}, { schema: { modelBase: SchedulerEvent, model: SchedulerEvent } }, options)); this.reader = new SchedulerDataReader(this.options.schema, this.reader); }, expand: function(start, end) { var data = this.view(), filter = {}, endOffset; if (start && end) { endOffset = end.getTimezoneOffset(); end = new Date(end.getTime() + MS_PER_DAY - 1); if(end.getTimezoneOffset() !== endOffset){ end = kendo.timezone.apply(end, endOffset); } filter = { logic: "or", filters: [ { logic: "and", filters: [ { field: "start", operator: "gte", value: start }, { field: "end", operator: "gte", value: start }, { field: "start", operator: "lte", value: end } ] }, { logic: "and", filters: [ { field: "start", operator: "lte", value: new Date(start.getTime() + MS_PER_DAY - 1) }, { field: "end", operator: "gte", value: start } ] } ] }; data = new kendo.data.Query(expandAll(data, start, end, this.reader.timezone)).filter(filter).toArray(); } return data; }, cancelChanges: function(model) { if (model && model.isOccurrence()) { this._removeExceptionDate(model); } DataSource.fn.cancelChanges.call(this, model); }, insert: function(index, model) { if (!model) { return; } if (!(model instanceof SchedulerEvent)) { var eventInfo = model; model = this._createNewModel(); model.accept(eventInfo); } if ((!this._pushCreated && model.isRecurrenceHead()) || model.recurrenceId) { model = model.recurrenceId ? model : model.toOccurrence(); this._addExceptionDate(model); } return DataSource.fn.insert.call(this, index, model); }, pushCreate: function(items) { this._pushCreated = true; DataSource.fn.pushCreate.call(this, items); this._pushCreated = false; }, remove: function(model) { if (model.isRecurrenceHead()) { this._removeExceptions(model); } else if (model.isRecurring()) { this._addExceptionDate(model); } return DataSource.fn.remove.call(this, model); }, _removeExceptions: function(model) { var data = this.data().slice(0), item = data.shift(), id = model.id; while(item) { if (item.recurrenceId === id) { DataSource.fn.remove.call(this, item); } item = data.shift(); } model.set(RECURRENCE_EXCEPTION, ""); }, _removeExceptionDate: function(model) { if (model.recurrenceId) { var head = this.get(model.recurrenceId); if (head) { var start = model.defaults.start; var replaceRegExp = new RegExp("(\\" + EXCEPTION_SEPARATOR + "?)" + recurrence.toExceptionString(start, this.reader.timezone)); var recurrenceException = (head.recurrenceException || "").replace(OLD_EXCEPTION_SEPARATOR_REGEXP, EXCEPTION_SEPARATOR).replace(/\,$/, ""); if(replaceRegExp.test(recurrenceException)){ head.set(RECURRENCE_EXCEPTION, recurrenceException.replace(replaceRegExp, "")); }else{ start = model.start; replaceRegExp = new RegExp("(\\" + EXCEPTION_SEPARATOR + "?)" + recurrence.toExceptionString(start, this.reader.timezone)); head.set(RECURRENCE_EXCEPTION, recurrenceException.replace(replaceRegExp, "")); } } } }, _addExceptionDate: function(model) { var start = model.start; var zone = this.reader.timezone; var head = this.get(model.recurrenceId); var recurrenceException = (head.recurrenceException || "").replace(OLD_EXCEPTION_SEPARATOR_REGEXP, EXCEPTION_SEPARATOR).replace(/\,$/, ""); if (!recurrence.isException(recurrenceException, start, zone)) { var newException = recurrence.toExceptionString(start, zone); model.defaults.start = start; head.set(RECURRENCE_EXCEPTION, recurrenceException + (recurrenceException && newException ? EXCEPTION_SEPARATOR : "") + newException); } } }); function expandAll(events, start, end, zone) { var length = events.length, data = [], idx = 0; for (; idx < length; idx++) { data = data.concat(events[idx].expand(start, end, zone)); } return data; } SchedulerDataSource.create = function(options) { if (isArray(options) || options instanceof kendo.data.ObservableArray) { options = { data: options }; } var dataSource = options || {}, data = dataSource.data; dataSource.data = data; if (!(dataSource instanceof SchedulerDataSource) && dataSource instanceof kendo.data.DataSource) { throw new Error("Incorrect DataSource type. Only SchedulerDataSource instances are supported"); } return dataSource instanceof SchedulerDataSource ? dataSource : new SchedulerDataSource(dataSource); }; extend(true, kendo.data, { SchedulerDataSource: SchedulerDataSource, SchedulerDataReader: SchedulerDataReader, SchedulerEvent: SchedulerEvent }); var defaultCommands = { update: { text: "Save", className: "k-primary k-scheduler-update" }, canceledit: { text: "Cancel", className: "k-scheduler-cancel" }, destroy: { text: "Delete", imageClass: "k-i-close", className: "k-primary k-scheduler-delete", iconClass: "k-icon" } }; function trimOptions(options) { delete options.name; delete options.prefix; delete options.remove; delete options.edit; delete options.add; delete options.navigate; return options; } /* function fieldType(field) { field = field != null ? field : ""; return field.type || $.type(field) || "string"; } */ function createValidationAttributes(model, field) { var modelField = (model.fields || model)[field]; var specialRules = ["url", "email", "number", "date", "boolean"]; var validation = modelField ? modelField.validation : {}; // var type = fieldType(modelField); var datatype = kendo.attr("type"); var inArray = $.inArray; var ruleName; var rule; var attr = {}; for (ruleName in validation) { rule = validation[ruleName]; if (inArray(ruleName, specialRules) >= 0) { attr[datatype] = ruleName; } else if (!kendo.isFunction(rule)) { attr[ruleName] = isPlainObject(rule) ? (rule.value || ruleName) : rule; } attr[kendo.attr(ruleName + "-msg")] = rule.message; } return attr; } function dropDownResourceEditor(resource, model) { var attr = createValidationAttributes(model, resource.field); return function(container) { $(kendo.format('<select data-{0}bind="value:{1}" title="' + model.title + '">', kendo.ns, resource.field)) .appendTo(container) .attr(attr) .kendoDropDownList({ dataTextField: resource.dataTextField, dataValueField: resource.dataValueField, dataSource: resource.dataSource, valuePrimitive: resource.valuePrimitive, optionLabel: "None", template: kendo.format('<span class="k-scheduler-mark" style="background-color:#= data.{0}?{0}:"none" #"></span>#={1}#', resource.dataColorField, resource.dataTextField) }); }; } function dropDownResourceEditorMobile(resource, model) { var attr = createValidationAttributes(model, resource.field); return function(container) { var options = ""; var view = resource.dataSource.view(); for (var idx = 0, length = view.length; idx < length; idx++) { options += kendo.format('<option value="{0}">{1}</option>', kendo.getter(resource.dataValueField)(view[idx]), kendo.getter(resource.dataTextField)(view[idx]) ); } $(kendo.format('<select data-{0}bind="value:{1}">{2}</select>', kendo.ns, resource.field, options, resource.valuePrimitive )) .appendTo(container) .attr(attr); }; } function descriptionEditor(options) { var attr = createValidationAttributes(options.model, options.field); return function(container, model) { $('<textarea name="description" class="k-textbox" title="' + model.title + '"/>').attr(attr) .appendTo(container); }; } function multiSelectResourceEditor(resource, model) { var attr = createValidationAttributes(model, resource.field); return function(container) { $(kendo.format('<select data-{0}bind="value:{1}">', kendo.ns, resource.field)) .appendTo(container) .attr(attr) .kendoMultiSelect({ dataTextField: resource.dataTextField, dataValueField: resource.dataValueField, dataSource: resource.dataSource, valuePrimitive: resource.valuePrimitive, itemTemplate: kendo.format('<span class="k-scheduler-mark" style="background-color:#= data.{0}?{0}:"none" #"></span>#={1}#', resource.dataColorField, resource.dataTextField), tagTemplate: kendo.format('<span class="k-scheduler-mark" style="background-color:#= data.{0}?{0}:"none" #"></span>#={1}#', resource.dataColorField, resource.dataTextField) }); }; } function multiSelectResourceEditorMobile(resource, model) { var attr = createValidationAttributes(model, resource.field); return function(container) { var options = ""; var view = resource.dataSource.view(); for (var idx = 0, length = view.length; idx < length; idx++) { options += kendo.format('<option value="{0}">{1}</option>', kendo.getter(resource.dataValueField)(view[idx]), kendo.getter(resource.dataTextField)(view[idx]) ); } $(kendo.format('<select data-{0}bind="value:{1}" multiple="multiple" data-{0}value-primitive="{3}">{2}</select>', kendo.ns, resource.field, options, resource.valuePrimitive )) .appendTo(container) .attr(attr); }; } function moveEventRange(event, distance) { var duration = event.end.getTime() - event.start.getTime(); var start = new Date(event.start.getTime()); kendo.date.setTime(start, distance); var end = new Date(start.getTime()); kendo.date.setTime(end, duration, true); return { start: start, end: end }; } var editors = { mobile: { dateRange: MOBILEDATERANGEEDITOR, timezonePopUp: MOBILETIMEZONEPOPUP, timezone: MOBILETIMEZONEEDITOR, recurrence: MOBILERECURRENCEEDITOR, description: descriptionEditor, multipleResources: multiSelectResourceEditorMobile, resources: dropDownResourceEditorMobile, isAllDay: MOBILEISALLDAYEDITOR }, desktop: { dateRange: DATERANGEEDITOR, timezonePopUp: TIMEZONEPOPUP, timezone: TIMEZONEEDITOR, recurrence: RECURRENCEEDITOR, description: descriptionEditor, multipleResources: multiSelectResourceEditor, resources: dropDownResourceEditor } }; var Editor = kendo.Observable.extend({ init: function(element, options) { kendo.Observable.fn.init.call(this); this.element = element; this.options = extend(true, {}, this.options, options); this.createButton = this.options.createButton; this.toggleDateValidationHandler = proxy(this._toggleDateValidation, this); }, _toggleDateValidation: function(e) { if (e.field == "isAllDay") { var container = this.container, isAllDay = this.editable.options.model.isAllDay, bindAttribute = kendo.attr("bind"), element, isDateTimeInput, shouldValidate; container.find("[" + bindAttribute+ "*=end],[" + bindAttribute + "*=start]").each(function() { element = $(this); if (valueStartEndBoundRegex.test(element.attr(bindAttribute))) { isDateTimeInput = element.is("[" + kendo.attr("role") + "=datetimepicker],[type*=datetime]"); shouldValidate = isAllDay !== isDateTimeInput; element.attr(kendo.attr("validate"), shouldValidate); } }); } }, fields: function(editors, model) { var that = this; var messages = that.options.messages; var timezone = that.options.timezone; var click = function(e) { e.preventDefault(); that._initTimezoneEditor(model, this); }; var fields = [ { field: "title", title: messages.editor.title /*, format: field.format, editor: field.editor, values: field.values*/ }, { field: "start", title: messages.editor.start, editor: editors.dateRange, timezone: timezone }, { field: "end", title: messages.editor.end, editor: editors.dateRange, timezone: timezone }, { field: "isAllDay", title: messages.editor.allDayEvent, editor: editors.isAllDay } ]; if (kendo.timezone.windows_zones) { fields.push({ field: "timezone", title: messages.editor.timezone, editor: editors.timezonePopUp, click: click, messages: messages.editor, model: model }); fields.push({ field: "startTimezone", title: messages.editor.startTimezone, editor: editors.timezone, noTimezone: messages.editor.noTimezone }); fields.push({ field: "endTimezone", title: messages.editor.endTimezone, editor: editors.timezone, noTimezone: messages.editor.noTimezone }); } if (!model.recurrenceId) { fields.push({ field: "recurrenceRule", title: messages.editor.repeat, editor: editors.recurrence, timezone: timezone, messages: messages.recurrenceEditor, pane: this.pane }); } if ("description" in model) { fields.push({ field: "description", title: messages.editor.description, editor: editors.description({model: model, field: "description"}) }); } for (var resourceIndex = 0; resourceIndex < this.options.resources.length; resourceIndex++) { var resource = this.options.resources[resourceIndex]; fields.push({ field: resource.field, title: resource.title, editor: resource.multiple? editors.multipleResources(resource, model) : editors.resources(resource, model) }); } return fields; }, end: function() { return this.editable.end(); }, _buildDesktopEditTemplate: function(model, fields, editableFields) { var messages = this.options.messages; var settings = extend({}, kendo.Template, this.options.templateSettings); var paramName = settings.paramName; var html = ""; for (var idx = 0, length = fields.length; idx < length; idx++) { var field = fields[idx]; if (field.field === "startTimezone") { html += '<div class="k-popup-edit-form k-scheduler-edit-form k-scheduler-timezones" style="display:none">'; html += '<div class="k-edit-form-container">'; html += '<div class="k-edit-label"></div>'; html += '<div class="k-edit-field"><label class="k-check"><input class="k-timezone-toggle" type="checkbox" />' + messages.editor.separateTimezones + '</label></div>'; } html += '<div class="k-edit-label"><label for="' + field.field + '">' + (field.title || field.field || "") + '</label></div>'; if ((!model.editable || model.editable(field.field))) { editableFields.push(field); html += '<div ' + kendo.attr("container-for") + '="' + field.field + '" class="k-edit-field"></div>'; } else { var tmpl = "#:"; if (field.field) { field = kendo.expr(field.field, paramName);