@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
JavaScript
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;
}