UNPKG

@progress/kendo-ui

Version:

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

1,330 lines (1,093 loc) 95.7 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__(1257); /***/ }), /***/ 3: /***/ (function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }), /***/ 1059: /***/ (function(module, exports) { module.exports = require("./kendo.data"); /***/ }), /***/ 1194: /***/ (function(module, exports) { module.exports = require("./kendo.resizable"); /***/ }), /***/ 1257: /***/ (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__(1059), __webpack_require__(1194), __webpack_require__(1258), __webpack_require__(1259), __webpack_require__(1260), __webpack_require__(1261), __webpack_require__(1262), __webpack_require__(1263)], __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: "gantt", name: "Gantt", category: "web", description: "The Gantt component.", depends: [ "data", "resizable", "switch", "gantt.data", "gantt.editors", "gantt.list", "gantt.timeline", "pdf" ] }; (function($, undefined) { var kendo = window.kendo, keys = $.extend({F10: 121}, kendo.keys), supportsMedia = "matchMedia" in window, mobileOS = kendo.support.mobileOS, Widget = kendo.ui.Widget, ObservableObject = kendo.data.ObservableObject, ObservableArray = kendo.data.ObservableArray, Query = kendo.data.Query, isArray = $.isArray, inArray = $.inArray, isFunction = kendo.isFunction, proxy = $.proxy, extend = $.extend, isPlainObject = $.isPlainObject, outerWidth = kendo._outerWidth, outerHeight = kendo._outerHeight, defaultIndicatorWidth = 3, NS = ".kendoGantt", PERCENTAGE_FORMAT = "p0", TABINDEX = "tabIndex", CLICK = "click", STRING = "string", ARIA_DESCENDANT = "aria-activedescendant", ARIA_LABEL = "aria-label", ACTIVE_CELL = "gantt_active_cell", DOT = ".", TASK_DELETE_CONFIRM = "Are you sure you want to delete this task?", DEPENDENCY_DELETE_CONFIRM = "Are you sure you want to delete this dependency?", TOGGLE_BUTTON_TEMPLATE = kendo.template('<button class="#=styles.buttonToggle#" type="button" '+ ARIA_LABEL + '="Toggle"><span class="#=styles.iconToggle#"></span></button>'), BUTTON_TEMPLATE = '<button class="#=styles.button# #=className#" type="button" '+ '#if (action) {#' + 'data-action="#=action#"' + '#}#' + '><span class="#=iconClass#"></span><span class="k-button-text">#=text#</span></button>', COMMAND_BUTTON_TEMPLATE = '<a class="#=className#" #=attr# href="\\#">#=text#</a>', VIEWS_DROPDOWN_TEMPLATE = kendo.template('<select class="k-dropdown #= styles.viewsDropdown #">' + '#for(var view in views){#' + '<option value="#=view#">#=views[view].title#</option>' + '#}#' + '</select>'), HEADER_VIEWS_TEMPLATE = kendo.template('<div class="#=styles.viewsWrapper#">' + '<span class="k-button-group #=styles.views#">' + '#for(var view in views){#' + '<button type="button" class="#=styles.button# #=styles.viewButton#-#= view.toLowerCase() #" data-#=ns#name="#=view#"><span class="k-button-text">#=views[view].title#</span></button>' + '#}#' + '</span>' + '</div>'); var ganttStyles = { wrapper: "k-widget k-gantt", plannedTasks: "k-gantt-planned", rowHeight: "k-gantt-rowheight", content: "k-gantt-content", listWrapper: "k-gantt-treelist", list: "k-gantt-treelist", timelineWrapper: "k-gantt-timeline", timeline: "k-gantt-timeline", splitBarWrapper: "k-splitbar k-state-default k-splitbar-horizontal k-splitbar-draggable-horizontal", splitBar: "k-splitbar", splitBarHover: "k-splitbar-horizontal-hover", popupWrapper: "k-list-container", popupList: "k-list k-reset", resizeHandle: "k-resize-handle", icon: "k-icon", item: "k-item", line: "k-gantt-line", buttonDelete: "k-gantt-delete", buttonCancel: "k-gantt-cancel", buttonSave: "k-gantt-update", buttonToggle: "k-gantt-toggle", primary: "k-primary", hovered: "k-state-hover", selected: "k-state-selected", focused: "k-state-focused", gridHeader: "k-grid-header", gridHeaderWrap: "k-grid-header-wrap", gridContent: "k-grid-content", tasks: "k-gantt-tasks", popup: { form: "k-popup-edit-form", editForm: "k-gantt-edit-form", formContainer: "k-edit-form-container", resourcesFormContainer: "k-resources-form-container", message: "k-popup-message", buttonsContainer: "k-edit-buttons k-state-default", button: "k-button", editField: "k-edit-field", editLabel: "k-edit-label", resourcesField: "k-gantt-resources" }, toolbar: { headerWrapper: "k-gantt-header k-toolbar k-gantt-toolbar", footerWrapper: "k-gantt-footer k-toolbar k-gantt-toolbar", toolbar: "k-gantt-toolbar", views: "k-gantt-views", viewsWrapper: "k-gantt-views-wrapper", viewsDropdown: "k-views-dropdown", button: "k-button k-button-icontext", buttonToggle: "k-button k-button-icon k-gantt-toggle", iconPlus: "k-icon k-i-plus", iconPdf: "k-icon k-i-file-pdf", iconToggle: "k-icon k-i-layout-1-by-4", viewButtonDefault: "k-state-default", viewButton: "k-view", link: "k-link", pdfButton: "k-gantt-pdf", appendButton: "k-gantt-create" } }; function selector(uid) { return "[" + kendo.attr("uid") + (uid ? "='" + uid + "']" : "]"); } function trimOptions(options) { delete options.name; delete options.prefix; delete options.remove; delete options.edit; delete options.add; delete options.navigate; return options; } function focusTable(table, direct) { var wrapper = table.parents('[' + kendo.attr("role") + '="gantt"]'); var scrollPositions = []; var parents = scrollableParents(wrapper); table.attr(TABINDEX, 0); if (direct) { parents.each(function(index, parent) { scrollPositions[index] = $(parent).scrollTop(); }); } try { //The setActive method does not cause the document to scroll to the active object in the current page table[0].setActive(); } catch (e) { table[0].focus(); } if (direct) { parents.each(function(index, parent) { $(parent).scrollTop(scrollPositions[index]); }); } } function scrollableParents(element) { return $(element).parentsUntil("body") .filter(function(index, element) { var computedStyle = kendo.getComputedStyles(element, ["overflow"]); return computedStyle.overflow != "visible"; }) .add(window); } var defaultCommands; var Gantt = Widget.extend({ init: function(element, options, events) { if (isArray(options)) { options = { dataSource: options }; } defaultCommands = { append: { text: "Add Task", action: "add", className: Gantt.styles.toolbar.appendButton, iconClass: Gantt.styles.toolbar.iconPlus }, pdf: { text: "Export to PDF", className: Gantt.styles.toolbar.pdfButton, iconClass: Gantt.styles.toolbar.iconPdf } }; Widget.fn.init.call(this, element, options); if (events) { this._events = events; } this._wrapper(); this._resources(); if (!this.options.views || !this.options.views.length) { this.options.views = ["day", "week", "month"]; } this._timeline(); this._toolbar(); this._footer(); this._adjustDimensions(); // Prevent extra refresh from setting the view this._preventRefresh = true; this.view(this.timeline._selectedViewName); this._preventRefresh = false; this._dataSource(); this._assignments(); this._dropDowns(); this._list(); this._dependencies(); this._resizable(); this._scrollable(); this._dataBind(); this._attachEvents(); this._createEditor(); kendo.notify(this); }, events: [ "dataBinding", "dataBound", "add", "edit", "remove", "cancel", "save", "change", "navigate", "moveStart", "move", "moveEnd", "resizeStart", "resize", "resizeEnd", "columnHide", "columnReorder", "columnResize", "columnShow", "togglePlannedTasks" ], options: { name: "Gantt", autoBind: true, navigatable: false, selectable: true, editable: true, resizable: false, columnResizeHandleWidth: defaultIndicatorWidth, columns: [], views: [], dataSource: {}, dependencies: {}, resources: {}, assignments: {}, taskTemplate: null, messages: { save: "Save", cancel: "Cancel", destroy: "Delete", deleteTaskConfirmation: TASK_DELETE_CONFIRM, deleteDependencyConfirmation: DEPENDENCY_DELETE_CONFIRM, deleteTaskWindowTitle: "Delete task", deleteDependencyWindowTitle: "Delete dependency", views: { day: "Day", week: "Week", month: "Month", year: "Year", start: "Start", end: "End" }, actions: { append: "Add Task", addChild: "Add Child", insertBefore: "Add Above", insertAfter: "Add Below", pdf: "Export to PDF" }, editor: { editorTitle: "Task", resourcesEditorTitle: "Resources", title: "Title", start: "Start", end: "End", plannedStart: "Planned Start", plannedEnd: "Planned End", percentComplete: "Complete", resources: "Resources", assignButton: "Assign", resourcesHeader: "Resources", unitsHeader: "Units" }, plannedTasks: { switchText: "Planned Tasks", offsetTooltipAdvanced: "Met deadline earlier", offsetTooltipDelay: "Delay", seconds: "seconds", minutes: "minutes", hours: "hours", days: "days" } }, showWorkHours: true, showWorkDays: true, toolbar: null, workDayStart: new Date(1980, 1, 1, 8, 0, 0), workDayEnd: new Date(1980, 1, 1, 17, 0, 0), workWeekStart: 1, workWeekEnd: 5, hourSpan: 1, snap: true, height: 600, listWidth: "30%", rowHeight: null, showPlannedTasks: false }, select: function(value) { var list = this.list; if (!value) { return list.select(); } if (typeof value === STRING) { value = list.content.find(value); } list.select(value); this.list.element.find("table[role=treegrid]").focus(); return; }, clearSelection: function() { this.list.clearSelection(); }, destroy: function() { Widget.fn.destroy.call(this); if (this.dataSource) { this.dataSource.unbind("change", this._refreshHandler); this.dataSource.unbind("progress", this._progressHandler); this.dataSource.unbind("error", this._errorHandler); } if (this.dependencies) { this.dependencies.unbind("change", this._dependencyRefreshHandler); this.dependencies.unbind("error", this._dependencyErrorHandler); } if (this.timeline) { this.timeline.unbind(); this.timeline.destroy(); } if (this.list) { this.list.unbind(); this.list.destroy(); } if (this.footerDropDown) { this.footerDropDown.destroy(); } if (this.headerDropDown) { this.headerDropDown.destroy(); } if (this._editor) { this._editor.destroy(); } if (this._resizeDraggable) { this._resizeDraggable.destroy(); } this.toolbar.off(NS); if (supportsMedia) { this._mediaQuery.removeListener(this._mediaQueryHandler); this._mediaQuery = null; } $(window).off("resize" + NS, this._resizeHandler); $(this.wrapper).off(NS); this.toolbar = null; this.footer = null; kendo.destroy(this.element); }, setOptions: function(options) { var newOptions = kendo.deepExtend({}, this.options, options); var events = this._events; if (!options.views) { var selectedView = this.view().name; newOptions.views = $.map(this.options.views, function(view) { var isSettings = isPlainObject(view); var name = isSettings ? ((typeof view.type !== "string") ? view.title : view.type) : view; if (selectedView === name) { if (isSettings) { view.selected = true; } else { view = { type: name, selected: true }; } } else if (isSettings) { view.selected = false; } return view; }); } if (!options.dataSource) { newOptions.dataSource = this.dataSource; } if (!options.dependencies) { newOptions.dependencies = this.dependencies; } if (!options.resources) { newOptions.resources = this.resources; } if (!options.assignments) { newOptions.assignments = this.assignments; } this.destroy(); this.element.empty(); this.options = null; this.init(this.element, newOptions, events); Widget.fn._setEvents.call(this, newOptions); }, _attachEvents: function() { this._resizeHandler = proxy(this.resize, this, false); $(window).on("resize" + NS, this._resizeHandler); if (supportsMedia && this._mediaQuery.matches === true) { this._mediaQueryHandler({ matches: true }); } }, _wrapper: function() { var ganttStyles = Gantt.styles; var splitBarHandleClassName = [ganttStyles.icon, ganttStyles.resizeHandle].join(" "); var options = this.options; var height = options.height; var width = options.width; this.wrapper = this.element.addClass(ganttStyles.wrapper); this.layout = $("<div class='" + ganttStyles.content + "' />").appendTo(this.wrapper) .append("<div class='" + ganttStyles.listWrapper + "'><div></div></div>") .append("<div class='" + ganttStyles.splitBarWrapper + "'><div class='" + splitBarHandleClassName + "'></div></div>") .append("<div class='" + ganttStyles.timelineWrapper + "'><div></div></div>"); if(options.showPlannedTasks) { this.wrapper.addClass(ganttStyles.plannedTasks); } if (height) { this.wrapper.css("height", height); } if (width) { this.wrapper.css("width", width); } if (options.rowHeight) { this.wrapper.addClass(ganttStyles.rowHeight); } this.treelistWrapper = this.wrapper.find(DOT + ganttStyles.list); this.splitbar = this.wrapper.find(DOT + ganttStyles.splitBar); this.timelineWrapper = this.wrapper.find(DOT + ganttStyles.timeline); this.treelistWrapper.css("width", options.listWidth); this.timelineWrapper.css("width", this.wrapper.width() - this.treelistWrapper.outerWidth() - this.splitbar.outerWidth() ); }, _toolbar: function() { var that = this; var ganttStyles = Gantt.styles; var viewsSelector = DOT + ganttStyles.toolbar.views + " > button"; var viewsDropdownSelector = DOT + ganttStyles.toolbar.viewsDropdown; var pdfSelector = DOT + ganttStyles.toolbar.pdfButton; var toggleSelector = DOT + ganttStyles.buttonToggle; var contentSelector = DOT + ganttStyles.gridContent; var splitbar = that.splitbar; var treelist = that.treelistWrapper; var timeline = that.timelineWrapper; var actions = this.options.toolbar; var toolbar; var views; var toggleButton; var mediaQueryHandler = function(e) { if (e.matches) { treelist.addClass("k-hidden"); splitbar.addClass("k-hidden"); treelist.width("100%"); } else { treelist.removeClass("k-hidden"); splitbar.removeClass("k-hidden"); timeline.removeClass("k-hidden"); treelist.width(treelist.outerWidth()); that.refresh(); timeline .find(contentSelector) .scrollTop(that.scrollTop); } that._resize(); }; if (!isFunction(actions)) { actions = (typeof actions === STRING ? actions : this._actions(actions)); actions = proxy(kendo.template(actions), this); } toggleButton = $(TOGGLE_BUTTON_TEMPLATE({ styles: ganttStyles.toolbar })); views = $(HEADER_VIEWS_TEMPLATE({ ns: kendo.ns, views: this.timeline.views, styles: ganttStyles.toolbar })); toolbar = $("<div class='" + ganttStyles.toolbar.headerWrapper + "'>") .append(toggleButton) .append(actions({})) .append("<span class='k-spacer k-toolbar-spacer' />") .append(views); if (views.find("button").length > 1) { views.prepend(VIEWS_DROPDOWN_TEMPLATE({ ns: kendo.ns, views: this.timeline.views, styles: ganttStyles.toolbar })); } if(this.toggeSwitchWrap) { this.toggeSwitchWrap.insertBefore(views); } this.wrapper.prepend(toolbar); this.toolbar = toolbar; if (supportsMedia) { this._mediaQueryHandler = proxy(mediaQueryHandler, this); this._mediaQuery = window.matchMedia("(max-width: 480px)"); this._mediaQuery.addListener(this._mediaQueryHandler); } toolbar .on("change" + NS, viewsDropdownSelector, function() { var list = that.list; var name = $(this).val(); if (list.editable && list.editable.trigger("validate")) { return; } if (!that.trigger("navigate", { view: name })) { that.view(name); } that.toolbar.find(DOT + ganttStyles.focused).removeClass(ganttStyles.focused); }) .on(CLICK + NS, viewsSelector, function(e) { e.preventDefault(); var list = that.list; var name = $(this).attr(kendo.attr("name")); if (list.editor && !list.editor.end()) { return; } if (!that.trigger("navigate", { view: name })) { that.view(name); } that.toolbar.find(DOT + ganttStyles.focused).removeClass(ganttStyles.focused); }) .on("keydown" + NS, viewsSelector, function(e) { var views = $(DOT + ganttStyles.toolbar.views).children(":not(.k-current-view)"); var focusedViewIndex = views.index((that._focusedView && that._focusedView[0]) || views.closest(DOT + ganttStyles.selected)[0]); if (e.keyCode === keys.RIGHT) { $(that.toolbar.find(DOT + ganttStyles.focused)).removeClass(ganttStyles.focused); that._focusedView = focusedViewIndex + 1 === views.length ? $(views[0]) : $(views[focusedViewIndex + 1]); that._focusedView.focus().addClass(ganttStyles.focused); e.preventDefault(); } else if (e.keyCode === keys.LEFT) { $(that.toolbar.find(DOT + ganttStyles.focused)).removeClass(ganttStyles.focused); that._focusedView = focusedViewIndex === 0 ? $(views[views.length - 1]) : $(views[focusedViewIndex - 1]); that._focusedView.focus().addClass(ganttStyles.focused); e.preventDefault(); } else if ((e.keyCode === keys.ENTER || e.keyCode === keys.SPACEBAR) && that._focusedView) { that.view(that._focusedView.text().toLowerCase()); e.preventDefault(); } else if (e.keyCode >= 49 && e.keyCode <= 57) { that.view(that.timeline._viewByIndex(e.keyCode - 49)); } }) .on(CLICK + NS, pdfSelector, function(e) { e.preventDefault(); that.saveAsPDF(); }) .on(CLICK + NS, toggleSelector, function(e) { e.preventDefault(); if (treelist.is(":visible")) { treelist.addClass("k-hidden"); timeline.removeClass("k-hidden"); that.refresh(); timeline .find(contentSelector) .scrollTop(that.scrollTop); } else { treelist.removeClass("k-hidden"); timeline.addClass("k-hidden"); treelist .find(contentSelector) .scrollTop(that.scrollTop); } that._resize(); }); this.wrapper .on("focusout" + NS, function(e) { if (!$(e.relatedTarget).closest(DOT + ganttStyles.toolbar.toolbar).length) { that.toolbar.find(DOT + ganttStyles.focused).removeClass(ganttStyles.focused); } if (!$(e.relatedTarget).closest(DOT + ganttStyles.toolbar.views).length) { that.toolbar.find(DOT + ganttStyles.toolbar.views).removeClass(ganttStyles.toolbar.expanded); } }); }, _actions: function() { var options = this.options; var editable = options.editable; var actions = options.toolbar; var html = ""; var action; if (!isArray(actions)) { if (editable && editable.create !== false) { actions = ["append"]; } else { return html; } } for (var i = 0, length = actions.length; i < length; i++) { action = actions[i]; if(action === "plannedTasks" || action.name === "plannedTasks") { this._createPlannedTasksSwitch(); continue; } html += this._createButton(action); } return html; }, _footer: function() { var editable = this.options.editable; if (!editable || editable.create === false) { return; } var ganttStyles = Gantt.styles.toolbar; var messages = this.options.messages.actions; var button = $(kendo.template(BUTTON_TEMPLATE)(extend(true, { styles: ganttStyles }, defaultCommands.append, { text: messages.append }))); var footer = $("<div class='" + ganttStyles.footerWrapper + "'>").append(button); this.wrapper.append(footer); this.footer = footer; }, _createButton: function(command) { var template = command.template || BUTTON_TEMPLATE; var messages = this.options.messages.actions; var commandName = typeof command === STRING ? command : command.name || command.text; var className = defaultCommands[commandName] ? defaultCommands[commandName].className : "k-gantt-" + (commandName || "").replace(/\s/g, ""); var options = { iconClass: "", action: "", text: commandName, className: className, styles: Gantt.styles.toolbar }; if (!commandName && !(isPlainObject(command) && command.template)) { throw new Error("Custom commands should have name specified"); } options = extend(true, options, defaultCommands[commandName], { text: messages[commandName] }); if (isPlainObject(command)) { if (command.className && inArray(options.className, command.className.split(" ")) < 0) { command.className += " " + options.className; } options = extend(true, options, command); } return kendo.template(template)(options); }, _adjustDimensions: function() { var element = this.element; var toolbarHeight = outerHeight(this.toolbar); var footerHeight = this.footer ? outerHeight(this.footer) : 0; var totalHeight = element.height(); var totalWidth = element.width(); var splitBarWidth = this.splitbar.is(":visible") ? outerWidth(this.splitbar) : 0; var treeListWidth = this.treelistWrapper.is(":visible") ? outerWidth(this.treelistWrapper) : 0; var timelineWidth = totalWidth - ( treeListWidth + splitBarWidth ); this.layout.children().height(totalHeight - (toolbarHeight + footerHeight)); this.timelineWrapper.width(timelineWidth); if (totalWidth < (treeListWidth + splitBarWidth)) { this.treelistWrapper.width(totalWidth - splitBarWidth); } }, _scrollTo: function(value) { var view = this.timeline.view(); var list = this.list; var attr = kendo.attr("uid"); var id = typeof value === "string" ? value : value.closest("tr" + selector()).attr(attr); var action; var scrollTarget; var scrollIntoView = function() { if (scrollTarget.length !== 0) { action(); } }; if (view.content.is(":visible")) { scrollTarget = view.content.find(selector(id)); action = function() { view._scrollTo(scrollTarget); }; } else { scrollTarget = list.element.find(selector(id)); action = function() { scrollTarget.get(0).scrollIntoView(); }; } scrollIntoView(); }, _dropDowns: function() { var that = this; var actionsSelector = DOT + Gantt.styles.toolbar.appendButton; var actionMessages = this.options.messages.actions; var timeline = this.timeline; var editable = this.options.editable; var handler = function(e) { var type = e.type; var orderId; var dataSource = that.dataSource; var task = dataSource._createNewModel({}); var selected = that.dataItem(that.select()); var parent = dataSource.taskParent(selected); var firstSlot = timeline.view()._timeSlots()[0]; var target = type === "add" ? selected : parent; var editable = that.list.editor; if (editable && editable.trigger("validate")) { return; } task.set("title", "New task"); if (target) { task.set("parentId", target.get("id")); task.set("start", target.get("start")); task.set("end", target.get("end")); task.set("plannedStart", target.get("plannedStart")); task.set("plannedEnd", target.get("plannedEnd")); } else { task.set("start", firstSlot.start); task.set("end", firstSlot.end); } if (type !== "add") { orderId = selected.get("orderId"); orderId = type === "insert-before" ? orderId : orderId + 1; } that._createTask(task, orderId); }; if (!editable || editable.create === false) { return; } this.footerDropDown = new kendo.gantt.TaskDropDown(this.footer.children(actionsSelector).eq(0), { messages: { actions: actionMessages }, direction: "up", animation: { open: { effects: "slideIn:up" } }, navigatable: that.options.navigatable }); this.headerDropDown = new kendo.gantt.TaskDropDown(this.toolbar.children(actionsSelector).eq(0), { messages: { actions: actionMessages }, navigatable: that.options.navigatable }); this.footerDropDown.bind("command", handler); this.headerDropDown.bind("command", handler); }, _getListEditable: function() { var editable = false, options = this.options; if(options.editable !== false) { editable = "incell"; if(options.editable && options.editable.update === false) { editable = false; } else { if(!options.editable || options.editable.reorder !== false) { editable = { mode: "incell", move: { reorderable: true } }; } } } return editable; }, _getListOptions: function() { var options = this.options, editable = this._getListEditable(), listWrapper = this.wrapper.find(DOT + ganttStyles.list), ganttListOptions = { columns: options.columns || [], dataSource: this.dataSource, selectable: options.selectable, reorderable: options.reorderable, editable: editable, resizable: options.resizable, filterable: options.filterable, columnMenu: options.columnMenu, columnResizeHandleWidth: this.options.columnResizeHandleWidth, listWidth: outerWidth(listWrapper), resourcesField: this.resources.field, rowHeight: this.options.rowHeight }; return ganttListOptions; }, _attachResourceEditor: function(columns) { var column; for (var i = 0; i < columns.length; i++) { column = columns[i]; if (column.field === this.resources.field && typeof column.editor !== "function") { column.editor = proxy(this._createResourceEditor, this); } } }, _attachListEvents: function() { var that = this, navigatable = that.options.navigatable, toggleButtons = this.wrapper.find(DOT + ganttStyles.toolbar.toolbar + " " + DOT + ganttStyles.toolbar.appendButton), restoreFocus = function() { var element; if (navigatable && that._cachedCurrent) { element = that.list.content.find("tr").eq(that._cachedCurrent.rowIndex).find("td").eq(that._cachedCurrent.columnIndex); that._current(element); focusTable(that.list.content.find("table"), true); } delete that._cachedCurrent; }; that.list .bind("columnShow", function(e) { that.trigger("columnShow", { column: e.column }); }) .bind("columnHide", function(e) { that.trigger("columnHide", { column: e.column }); }) .bind("columnReorder", function(e) { that.trigger("columnReorder", { column: e.column, oldIndex: e.oldIndex, newIndex: e.newIndex }); }) .bind("columnResize", function(e) { that.trigger("columnResize", { column: e.column, oldWidth: e.oldWidth, newWidth: e.newWidth }); }) .bind("render", function() { that._navigatable(); }, true) .bind("beforeEdit", function(e) { that._cachedCurrent = { rowIndex: e.container.closest("tr").index(), columnIndex: e.container.index() }; if (that.trigger("edit", { task: e.model, container: e.container })) { e.preventDefault(); } }) .bind("cancel", function(e) { if (that.trigger("cancel", { task: e.model, container: e.cell })) { e.preventDefault(); return; } that._preventItemChange = true; that.list.closeCell(true); restoreFocus(); }) .bind("save", function(e) { var updatedValues = e.values; that._preventRefresh = true; if(that.updateDuration === null || that.updateDuration === undefined) { that.updateDuration = e.model.duration(); } if (updatedValues.hasOwnProperty("start")) { updatedValues.end = new Date(updatedValues.start.getTime() + that.updateDuration); } that.updatedValues = updatedValues; }) .bind("itemChange", function(e) { var updateInfo = that.updatedValues; var task = e.data; var resourcesField = that.resources.field; if(that._preventItemChange) { that._preventItemChange = false; return; } if (!that.trigger("save", { task: task, values: updateInfo })) { if(updateInfo) { that._preventRefresh = true; that.dataSource.update(task, updateInfo); if (updateInfo[resourcesField]) { that._updateAssignments(task.get("id"), updateInfo[resourcesField]); } } that._preventRefresh = false; that._requestStart(); that.dataSource.sync().then(function() { restoreFocus(); }); } else if(that.dataSource.hasChanges()) { that.dataSource.cancelChanges(); that._preventRefresh = false; that.refresh(); } that.updatedValues = null; that.updateDuration = null; }) .bind("change", function() { that.trigger("change"); var selection = that.list.select(); if (selection.length) { toggleButtons.removeAttr("data-action", "add"); that.timeline.select("[data-uid='" + selection.attr("data-uid") + "']"); } else { toggleButtons.attr("data-action", "add"); that.timeline.clearSelection(); } }) .bind("collapse", function(e) { e.preventDefault(); var row = that.list.element.find("tr[data-uid='" + e.model.uid + "']"); e.model.set("expanded", false); that._cachedCurrent = { rowIndex: row.index(), columnIndex: row.find(".k-state-focused").index() }; restoreFocus(); }) .bind("expand", function(e) { e.preventDefault(); var row = that.list.element.find("tr[data-uid='" + e.model.uid + "']"); e.model.set("expanded", true); that._cachedCurrent = { rowIndex: row.index(), columnIndex: row.find(".k-state-focused").index() }; restoreFocus(); }) .bind("dragend", function(e) { var dataSource = that.dataSource, task, updateInfo; if(e.position === "over") { updateInfo = { parentId: e.source.parentId }; dataSource.cancelChanges(); task = dataSource.get(e.source.id); if (!that.trigger("save", { task: task, values: updateInfo })) { dataSource.update(task, updateInfo); } } dataSource.sync(); }) .bind("dataBound", function() { if(that.dataSource.sort().length === 0) { that.dataSource.sort([{field: "orderId", dir: "asc"}]); } }) .bind("reorder", function(e) { that._updateTask(e.task, e.updateInfo); restoreFocus(); }); }, _list: function() { var ganttStyles = Gantt.styles, listWrapper = this.wrapper.find(DOT + ganttStyles.list), listElement = listWrapper.find("> div"), listOptions = this._getListOptions(); this._attachResourceEditor(listOptions.columns); this.list = new kendo.ui.GanttList(listElement, listOptions); this._attachListEvents(); }, _timeline: function() { var that = this; var ganttStyles = Gantt.styles; var options = trimOptions(extend(true, { resourcesField: this.resources.field }, this.options)); var element = this.wrapper.find(DOT + ganttStyles.timeline + " > div"); this.timeline = new kendo.ui.GanttTimeline(element, options); this.timeline .bind("navigate", function(e) { var viewName = e.view.replace(/\./g, "\\.").toLowerCase(); that.toolbar .find(DOT + ganttStyles.toolbar.views + " > button") .removeClass(ganttStyles.selected) .end() .find(DOT + ganttStyles.toolbar.viewButton + "-" + viewName) .addClass(ganttStyles.selected); that.toolbar .find(DOT + ganttStyles.toolbar.viewsDropdown) .val(viewName); that.refresh(); }) .bind("moveStart", function(e) { var editable = that.list.editor; if (editable && !editable.end()) { e.preventDefault(); return; } if (that.trigger("moveStart", { task: e.task })) { e.preventDefault(); } }) .bind("move", function(e) { var task = e.task; var start = e.start; var end = new Date(start.getTime() + task.duration()); if (that.trigger("move", { task: task, start: start, end: end })) { e.preventDefault(); } }) .bind("moveEnd", function(e) { var task = e.task; var start = e.start; var end = new Date(start.getTime() + task.duration()); if (!that.trigger("moveEnd", { task: task, start: start, end: end })) { that._updateTask(that.dataSource.getByUid(task.uid), { start: start, end: end }); } }) .bind("resizeStart", function(e) { var editable = that.list.editor; if (editable && !editable.end()) { e.preventDefault(); return; } if (that.trigger("resizeStart", { task: e.task })) { e.preventDefault(); } }) .bind("resize", function(e) { if (that.trigger("resize", { task: e.task, start: e.start, end: e.end })) { e.preventDefault(); } }) .bind("resizeEnd", function(e) { var task = e.task; var updateInfo = {}; if (e.resizeStart) { updateInfo.start = e.start; } else { updateInfo.end = e.end; } if (!that.trigger("resizeEnd", { task: task, start: e.start, end: e.end })) { that._updateTask(that.dataSource.getByUid(task.uid), updateInfo); } }) .bind("percentResizeStart", function(e) { var editable = that.list.editor; if (editable && !editable.end()) { e.preventDefault(); } }) .bind("percentResizeEnd", function(e) { that._updateTask(that.dataSource.getByUid(e.task.uid), { percentComplete: e.percentComplete }); }) .bind("dependencyDragStart", function(e) { var editable = that.list.editor; if (editable && !editable.end()) { e.preventDefault(); } }) .bind("dependencyDragEnd", function(e) { var dependency = that.dependencies._createNewModel({ type: e.type, predecessorId: e.predecessor.id, successorId: e.successor.id }); that._createDependency(dependency); }) .bind("select", function(e) { var editable = that.list.editor; if (editable) { editable.end(); } that.select("[data-uid='" + e.uid + "']"); }) .bind("editTask", function(e) { var editable = that.list.editor; if (editable && !editable.end()) { return; }