@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,442 lines (1,130 loc) • 55 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__) {
__webpack_require__(1605);
module.exports = __webpack_require__(1605);
/***/ }),
/***/ 3:
/***/ (function(module, exports) {
module.exports = function() { throw new Error("define cannot be used indirect"); };
/***/ }),
/***/ 20:
/***/ (function(module, exports) {
module.exports = require("../kendo.core");
/***/ }),
/***/ 1057:
/***/ (function(module, exports) {
module.exports = require("jquery");
/***/ }),
/***/ 1605:
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(jQuery) {(function(f, define){
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(20)], __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(){
(function($, undefined) {
var kendo = window.kendo,
keys = kendo.keys,
extend = $.extend,
proxy = $.proxy,
NS = ".kendoOrgChartView",
BLUR = "blur",
CLICK = "click",
COLLAPSE = "collapse",
EXPAND = "expand",
FOCUS = "focus",
KEYDOWN = "keydown",
MENU = "menu",
SELECT = "select",
DOT = ".",
SPACE = " ",
COMMA = ",",
HASH = "#",
STRING = "string",
TABINDEX = "tabindex",
ID = "id",
UID = "uid",
PX = "px",
PLUS = "plus",
MINUS = "minus",
ARIA_OWNS = "aria-owns",
ARIA_SELECTED = "aria-selected";
var ORGCHART_STYLES = {
wrapper: "k-orgchart",
container: "k-orgchart-container",
line: "k-orgchart-line",
lineVertical: "k-orgchart-line-v",
lineHorizontal: "k-orgchart-line-h",
lineVerticalTop: "k-orgchart-line-v-top",
group: "k-orgchart-group",
groupVertical: "k-orgchart-group-v",
groupHorizontal: "k-orgchart-group-h",
nodesGroup: "k-orgchart-node-group",
nodesGroupContainer: "k-orgchart-node-group-container",
nodeContainer: "k-orgchart-node-container",
node: "k-orgchart-node",
card: "k-orgchart-card",
cardMenu: "k-orgchart-card-menu",
button: "k-orgchart-button",
focused: "k-state-focus",
plusIcon: "k-i-plus",
menuItem: "k-item",
avatarPreview: "k-orgchart-avatar-preview",
update: "k-orgchart-update",
cancel: "k-orgchart-cancel",
vstack: "k-vstack",
hstack: "k-hstack"
};
var ROOT_TEMPLATE = '<div role="tree" aria-orientation="horizontal" aria-label="#: label #" class="k-orgchart-group k-orgchart-level-1 k-pos-absolute k-hstack k-justify-content-center"></div>';
var GROUP_TEMPLATE = '<div role="group" id="#: guid #" class="k-orgchart-level-#: level # k-orgchart-group k-pos-absolute k-justify-content-around"></div>';
var NODE_GROUP_CONTAINER = '<div role="treeitem" ' +
'# if(data.hasChildren && data.guid) { #' +
'aria-owns="#: guid #" ' +
'# if(!!data.expanded) { #' +
'aria-expanded="true" ' +
'# } else { #' +
'aria-expanded="false" ' +
'# } #' +
'# } #' +
'aria-keyshortcuts="Enter" aria-level="#: level #" aria-selected="false" class="k-orgchart-node-group-container">';
var NODE_CONTAINER = '<div class="k-orgchart-node-container k-justify-content-around" style="width:100%"></div>';
var NODE_CONTAINER_GROUPED = '<div role="group" class="k-orgchart-node-container k-justify-content-around k-hstack" style="width:100%"></div>';
var ITEM_TEMPLATE = '<div class="k-orgchart-node k-vstack k-align-items-center"></div>';
var BUTTON_TEMPLATE = '<button aria-label="#: label #" tabindex="-1" class="k-orgchart-button k-button k-button-icon">' +
'<span class="k-icon k-i-#: buttonSign #"></span>' +
'</button>';
var CARD_TEMPLATE = '<div class="k-card-body k-hstack" style="border-color:#: color #">' +
'# if(!!data.avatar) { #' +
'<div class="k-avatar-circle k-avatar k-avatar-md">' +
'<div class="k-avatar-image">' +
'<img alt="#: name #" src="#: avatar #">' +
'</div>' +
'</div>' +
'# } #' +
'<div class="k-vstack k-card-title-wrap">' +
'<div class="k-card-title k-text-ellipsis">#: name #</div>' +
'# if(data.title) { #' +
'<span class="k-spacer"></span>' +
'<div class="k-card-subtitle k-text-ellipsis">#: title #</div>' +
'# } #' +
'</div>' +
'# if(editable) { #' +
'<span class="k-spacer"></span>' +
'<div class="k-card-body-actions">' +
'<button class="k-button k-flat k-button-icon k-orgchart-card-menu" role="button" aria-label="#: menuLabel #" tabindex="-1">' +
'<span class="k-icon k-i-more-vertical"></span>' +
'</button>' +
'</div>' +
'# } #' +
'</div>';
var CARD_WRAPPER = '<div role="treeitem" data-uid="#: uid #" ' +
'# if(data.hasChildren && data.guid) { #' +
'aria-owns="#: guid #" ' +
'# if(!!data.expanded) { #' +
'aria-expanded="true" ' +
'# } else { #' +
'aria-expanded="false" ' +
'# } #' +
'# } #' +
'class="k-orgchart-card k-card ' +
'# if(!!data.cssClass) { #' +
'#: data.cssClass #' +
'# } #' +
'" aria-keyshortcuts="Enter" aria-level="#: level #" aria-selected="false">' +
'</div>';
var GROUPED_CARD_WRAPPER = '<div role="treeitem" data-uid="#: uid #" aria-level="#: level #" aria-selected="false" aria-keyshortcuts="Enter" ' +
'class="k-orgchart-card k-card ' +
'# if(!!data.cssClass) { #' +
'#: data.cssClass #' +
'# } #' +
'"></div>';
var View = kendo.Observable.extend({
init: function(element, options) {
this.element = element;
this.options = options || {};
kendo.Observable.fn.init.call(this);
this._attachEvents();
},
events: [
COLLAPSE,
EXPAND,
SELECT,
MENU
],
destroy: function() {
kendo.ui.Widget.fn.destroy.call(this);
this.element.off(NS);
},
collapse: function() {
return false;
},
expand: function() {
return false;
},
jqueryGroupElement: function(group) {
if(!group) {
return;
}
var jQueryElement = this._processItem(group);
if(!jQueryElement.hasClass(ORGCHART_STYLES.nodesGroupContainer)) {
jQueryElement = jQueryElement.closest(DOT + ORGCHART_STYLES.nodesGroupContainer);
}
return jQueryElement && jQueryElement.length ? jQueryElement : null;
},
jqueryItemElement: function(item) {
if(!item) {
return;
}
var jQueryElement = this._processItem(item);
if(!jQueryElement.hasClass(ORGCHART_STYLES.card)) {
jQueryElement = jQueryElement.closest(DOT + ORGCHART_STYLES.card);
}
return jQueryElement && jQueryElement.length ? jQueryElement : null;
},
refresh: function() {
this._cacheFocused();
this._clearContent();
this._generateItemsTree();
this._calculateLevels();
this._render();
},
select: function(item) {
var $item = this._getToSelect(item),
previousSelection = this.element.find("[tabindex=0]");
if(!$item) {
return;
}
previousSelection.removeAttr(TABINDEX)
.removeClass(ORGCHART_STYLES.focused)
.attr(ARIA_SELECTED, false);
$item.attr(TABINDEX, "0")
.addClass(ORGCHART_STYLES.focused)
.trigger("focus")
.attr(ARIA_SELECTED, true);
},
_attachEvents: function() {
var itemsSelector = DOT + ORGCHART_STYLES.card + COMMA + DOT + ORGCHART_STYLES.nodesGroupContainer;
this.element.on(KEYDOWN + NS, itemsSelector, proxy(this._onKeyDown, this))
.on(CLICK + NS, itemsSelector, proxy(this._onSelect, this))
.on(CLICK + NS, DOT + ORGCHART_STYLES.button, proxy(this._onButtonClick, this))
.on(FOCUS + NS, itemsSelector, proxy(this._onFocus, this))
.on(BLUR + NS, DOT + ORGCHART_STYLES.focused, proxy(this._onBlur, this));
},
_cacheFocused: function() {
var focusableItem = this.element.find("[tabindex='0']"),
focusableDataItem = this._dataItems(focusableItem);
if(!focusableItem.length || !focusableDataItem || !focusableDataItem.length || !!this._idTabIndex) {
return;
}
this._idTabIndex = focusableDataItem[0].get(ID);
if(focusableItem.hasClass(ORGCHART_STYLES.focused)) {
this._shouldRestoreSelection = true;
} else {
this._shouldRestoreSelection = false;
}
},
_calculateDimensions: function() {
var itemElement = this.element.find(DOT + this._selector).first();
if(!this._buttonHeight) {
this._buttonHeight = this.element.find(DOT + ORGCHART_STYLES.button).first().outerHeight();
}
if(!this._spacing) {
this._spacing = this.element.find(DOT + ORGCHART_STYLES.lineVertical).first().outerHeight();
}
if(!this._itemWidth) {
this._itemWidth = this._calculateItemWidth();
}
if(!this._itemHeight) {
this._itemHeight = itemElement.outerHeight(true);
}
},
_calculateItemWidth: function() {
return false;
},
_calculateLevel: function() {
return false;
},
_calculateLevels: function() {
return false;
},
_clearContent: function() {
this.element.empty();
},
_dataItem: function(item) {
var $item = this.jqueryItemElement(item);
if(!$item || !$item.data(UID)) {
return;
}
return this.dataSource.getByUid($item.data(UID));
},
_dataItems: function() {
return false;
},
_generateItemsTree: function() {
return false;
},
_getToSelect: function() {
return false;
},
_groupIsVertical: function() {
return false;
},
_keyCollapse: function() {
return false;
},
_keyExpand: function() {
return false;
},
_keyNext: function() {
return false;
},
_keyPrev: function() {
return false;
},
_keyEnter: function() {
return false;
},
_keyEscape: function() {
return false;
},
_keyEnd: function() {
var target = this.element.find(DOT + ORGCHART_STYLES.card).last(),
previous = this.element.find("[tabindex=0]");
if(previous[0] === target[0]) {
return;
}
this.trigger(SELECT, {
item: target,
dataItems: [this._dataItem(target)]
});
},
_keyHome: function() {
var target = this.element.find(DOT + ORGCHART_STYLES.card).first(),
previous = this.element.find("[tabindex=0]");
if(previous[0] === target[0]) {
return;
}
this.trigger(SELECT, {
item: target,
dataItems: [this._dataItem(target)]
});
},
_onBlur: function() {
this.element.find(DOT + ORGCHART_STYLES.focused).removeClass(ORGCHART_STYLES.focused);
},
_onKeyDown: function(e) {
var key = e.keyCode,
focused = this.element.find("[tabindex=0]"),
isRtl = kendo.support.isRtl(this.element),
nextKey = isRtl ? [ keys.LEFT ] : [ keys.RIGHT ],
prevKey = isRtl ? [ keys.RIGHT ] : [ keys.LEFT ],
expandKey = keys.DOWN,
collapseKey = keys.UP,
groupIsVertical;
if(!focused) {
return;
}
groupIsVertical = this._groupIsVertical(focused);
if(groupIsVertical) {
nextKey.push(keys.DOWN);
prevKey.push(keys.UP);
}
if(key === keys.HOME) {
this._keyHome();
} else if(key === keys.END) {
this._keyEnd();
} else if(nextKey.indexOf(key) > -1) {
e.preventDefault();
e.stopPropagation();
this._keyNext(focused);
} else if(prevKey.indexOf(key) > -1) {
e.preventDefault();
e.stopPropagation();
this._keyPrev(focused);
} else if(key === expandKey) {
e.preventDefault();
e.stopPropagation();
this._keyExpand(focused);
} else if(key === collapseKey) {
e.preventDefault();
e.stopPropagation();
this._keyCollapse(focused);
} else if(key === keys.ENTER) {
this._keyEnter(focused);
} else if(key === keys.ESC) {
this._keyEscape(focused);
}
},
_onButtonClick: function(e) {
var that = this,
target = $(e.currentTarget),
shouldExpand = target.find(DOT + ORGCHART_STYLES.plusIcon).length > 0 ? true : false,
el = target.siblings(DOT + this._selector),
items = this._dataItems(el),
i;
if(shouldExpand) {
if(that.trigger(EXPAND, { item: el, dataItems: items })) {
return;
}
} else {
if(that.trigger(COLLAPSE, { item: el, dataItems: items })) {
return;
}
}
for(i = 0; i < items.length; i++) {
that.dataSource.toggleChildren(items[i], shouldExpand).then(proxy(this.refresh, this));
}
},
_onFocus: function() {
return false;
},
_onSelect: function() {
return false;
},
_orientation: function() {
return false;
},
_processItem: function(el) {
var jQueryElement;
// Substitute with kendo.type() when merged and taken from master
if($.type(el) === STRING) {
jQueryElement = this.element.find(el);
} else if(kendo.isElement(el)) {
jQueryElement = $(el);
} else if(el instanceof jQuery) {
jQueryElement = el;
}
return jQueryElement;
},
_render: function() {
var items = this._itemsTree,
root = $(kendo.template(ROOT_TEMPLATE)({ label: this.options.messages.label })),
wrapperContainer = this.element,
total = this._total,
widgetPadding = wrapperContainer.closest(DOT + ORGCHART_STYLES.wrapper).css("padding-left"),
totalWidth;
wrapperContainer.append(root);
this._renderGroup(root, items, 1, this._total, 0);
totalWidth = total * this._itemWidth + (total - 1) * this._spacing;
root.width(totalWidth);
wrapperContainer.width(totalWidth + Number(widgetPadding.split(PX)[0]));
this._setHeight();
this._restoreSelection();
},
_renderNode: function(cardWrapperTemplate, contentTemplate, item, level, guid) {
var messages = this.options.messages,
borderColors = this.options.cardsColors || kendo.getSeriesColors(),
node = $(ITEM_TEMPLATE),
content, cardWrapper;
cardWrapper = $(cardWrapperTemplate(extend(true, {}, item, {
menuLabel: messages.menuLabel,
level: level,
guid: guid,
editable: !!this.options.editable,
color: borderColors[level - 1] || borderColors[0]
})));
if(item.attributes) {
cardWrapper.attr(JSON.parse(JSON.stringify(item.attributes)));
}
content = $(contentTemplate(extend(true, {}, item, {
menuLabel: messages.menuLabel,
level: level,
guid: guid,
editable: !!this.options.editable,
color: borderColors[level - 1] || borderColors[0]
})));
cardWrapper.append(content);
node.append(cardWrapper);
return node;
},
_renderGroup: function() {
return false;
},
_restoreSelection: function() {
var toFocusItem, toFocus;
if(!this._idTabIndex) {
toFocus = this.element.find(DOT + this._selector).first();
toFocus.attr(TABINDEX, "0");
} else {
toFocusItem = this.dataSource.get(this._idTabIndex);
toFocus = toFocusItem ? this._getToFocus(toFocusItem) : this.element.find(DOT + this._selector).first();
toFocus.attr(TABINDEX, "0");
this._idTabIndex = null;
}
if(this._shouldRestoreSelection) {
this._shouldRestoreSelection = false;
this._preventTriggerSelect = true;
toFocus.trigger("focus");
toFocus.addClass(ORGCHART_STYLES.focused);
}
},
_setHeight: function() {
var selector = this._selector,
elements = this.element.find(DOT + ORGCHART_STYLES.button + COMMA + DOT + selector),
min = Number.MAX_VALUE, max = 0,
buttonHeight;
this._calculateDimensions();
buttonHeight = this._buttonHeight;
this.element.find(DOT + ORGCHART_STYLES.lineVerticalTop).height(this._spacing + buttonHeight / 2);
elements.each(function(i, el) {
var top = $(el).offset().top,
bottom = top + $(el).outerHeight(true);
if(top < min) {
min = top;
}
if(bottom > max) {
max = bottom;
}
});
this.element.height(max - min);
}
});
var SingleView = View.extend({
init: function(element, options) {
View.fn.init.call(this, element, options);
this._selector = ORGCHART_STYLES.card;
},
collapse: function(item) {
var $item = this.jqueryItemElement(item);
if(!$item) {
return;
}
this.dataSource.toggleChildren(this._dataItem($item), false).then(proxy(this.refresh, this));
},
expand: function(item) {
var $item = this.jqueryItemElement(item);
if(!$item) {
return;
}
this.dataSource.toggleChildren(this._dataItem($item), true).then(proxy(this.refresh, this));
},
_calculateItemWidth: function() {
return this.element.find(DOT + this._selector).first().outerWidth(true);
},
_calculateLevel: function(items, level) {
var itemsLength = items.length,
maxColumnsPerLevel = this._maxColumnsPerLevel,
nestedChildren = false,
shouldReset = false,
previousMax, i, item;
if(!maxColumnsPerLevel[level] || maxColumnsPerLevel[level] < itemsLength) {
previousMax = maxColumnsPerLevel[level];
shouldReset = true;
maxColumnsPerLevel[level] = itemsLength;
}
for(i = 0; i < itemsLength; i++) {
item = items[i];
if(item.hasChildren) {
nestedChildren = true;
if(item.expanded) {
this._calculateLevel(item.children, level + 1);
}
}
}
if(!nestedChildren && shouldReset && level > 0) {
shouldReset = false;
maxColumnsPerLevel[level] = previousMax || 1;
}
},
_calculateLevels: function() {
var items = this._itemsTree,
maxColumnsPerLevel = this._maxColumnsPerLevel = [],
total = 1,
i;
this._calculateLevel(items, 0);
for(i = 0; i < maxColumnsPerLevel.length; i++) {
total = total * maxColumnsPerLevel[i];
}
this._total = total;
},
_dataItems: function(container) {
var item = this.dataSource.getByUid(container.data(UID));
if(item) {
return [item];
} else {
return null;
}
},
_generateItemsTree: function() {
this._itemsTree = this.dataSource.itemsTree();
},
_getToFocus: function(item) {
return this.element.find("[data-uid='" + item.get(UID) + "']");
},
_getToSelect: function(el) {
return this.jqueryItemElement(el);
},
_groupIsVertical: function(focused) {
var itemGroup = focused.closest(DOT + ORGCHART_STYLES.group);
return itemGroup.hasClass(ORGCHART_STYLES.groupVertical);
},
_keyCollapse: function(focused) {
var dataItem = this._dataItem(focused),
parentUid, parentItem;
if(dataItem.expanded) {
if(!this.trigger(COLLAPSE, { item: focused, dataItems: [dataItem] })) {
this.collapse(focused);
}
} else if(dataItem.parentId) {
parentUid = this.dataSource.get(dataItem.parentId).get(UID);
parentItem = this.element.find("[data-uid='" + parentUid + "']");
this.trigger(SELECT, {
item: parentItem,
dataItems: [this._dataItem(parentItem)]
});
}
},
_keyEnter: function(focused) {
if(focused.find(DOT + ORGCHART_STYLES.cardMenu).length > 0) {
this.trigger(MENU, focused);
}
},
_keyExpand: function(focused) {
var dataItem = this._dataItem(focused),
ownedGroup = this.element.find(HASH + focused.attr(ARIA_OWNS)),
childItem;
if(!dataItem.hasChildren) {
return;
}
if(!dataItem.expanded) {
if(!this.trigger(EXPAND, { item: focused, dataItems: [dataItem] })) {
this.expand(focused);
}
} else {
childItem = ownedGroup.find(DOT + this._selector).first();
this.trigger(SELECT, {
item: childItem,
dataItems: [this._dataItem(childItem)]
});
}
},
_keyNext: function(focused) {
var dataItem = this._dataItem(focused),
next = focused.parent().next(DOT + ORGCHART_STYLES.node).find(DOT + ORGCHART_STYLES.card),
ownedGroup = this.element.find(HASH + focused.attr(ARIA_OWNS));
if(!next.length && dataItem.hasChildren && dataItem.expanded) {
next = ownedGroup.find(DOT + ORGCHART_STYLES.card).first();
}
if(next.length === 0 || next.hasClass(ORGCHART_STYLES.focused)) {
return;
}
this.trigger(SELECT, {
item: next,
dataItems: [this._dataItem(next)]
});
},
_keyPrev: function(focused) {
var dataItem = this._dataItem(focused),
prev = focused.parent().prev(DOT + ORGCHART_STYLES.node).find(DOT + ORGCHART_STYLES.card),
parentUid;
if(!prev.length && dataItem.parentId) {
parentUid = this.dataSource.get(dataItem.parentId).get(UID);
prev = this.element.find("[data-uid='" + parentUid + "']");
}
if(prev.length === 0 || prev.hasClass(ORGCHART_STYLES.focused)) {
return;
}
this.trigger(SELECT, {
item: prev,
dataItems: [this._dataItem(prev)]
});
},
_onFocus: function(e) {
var currentTarget = $(e.currentTarget),
target = $(e.target);
if(this._preventTriggerSelect) {
e.stopPropagation();
this._preventTriggerSelect = false;
return;
}
if(target.hasClass(ORGCHART_STYLES.cardMenu)) {
if(target.closest("[tabindex='0']").length > 0) {
e.stopPropagation();
return;
} else {
this._preventTriggerSelect = true;
}
}
if(!currentTarget.hasClass(ORGCHART_STYLES.card)) {
currentTarget = currentTarget.closest(DOT + ORGCHART_STYLES.card);
}
if(!currentTarget.hasClass(ORGCHART_STYLES.focused)) {
this.trigger(SELECT, {
item: currentTarget,
dataItems: [this._dataItem(currentTarget)]
});
}
},
_onSelect: function(e) {
var target = $(e.currentTarget),
item = target.hasClass(ORGCHART_STYLES.card) ? target : target.closest(DOT + ORGCHART_STYLES.card),
menuButtonTarget = $(e.target).hasClass(ORGCHART_STYLES.cardMenu) ? $(e.target) : $(e.target).closest(DOT + ORGCHART_STYLES.cardMenu);
if(menuButtonTarget.length > 0) {
return;
}
if(!target.hasClass(ORGCHART_STYLES.focused)) {
this.trigger(SELECT, {
item: item,
dataItems: [this._dataItem(item)]
});
}
},
_orientation: function(group, level, vertical) {
var vLine = $("<div>").addClass(ORGCHART_STYLES.line + SPACE + ORGCHART_STYLES.lineVertical);
if(vertical && level > 1) {
group.addClass(ORGCHART_STYLES.groupVertical + SPACE + ORGCHART_STYLES.vstack);
group.find(DOT + ORGCHART_STYLES.nodeContainer).addClass(ORGCHART_STYLES.vstack);
if(group.find(DOT + ORGCHART_STYLES.button).length === 0 || group.find(DOT + ORGCHART_STYLES.card).length === 1) {
group.find(DOT + ORGCHART_STYLES.card).before(vLine.clone());
group.find(DOT + ORGCHART_STYLES.node).first().find(DOT + ORGCHART_STYLES.lineVertical).addClass(ORGCHART_STYLES.lineVerticalTop);
} else if(level > 1) {
group.find(DOT + ORGCHART_STYLES.card).first().before(vLine.clone());
}
} else {
group.addClass(ORGCHART_STYLES.groupHorizontal + SPACE + ORGCHART_STYLES.hstack);
group.find(DOT + ORGCHART_STYLES.nodeContainer).addClass(ORGCHART_STYLES.hstack);
if(level > 1) {
group.find(DOT + ORGCHART_STYLES.card).before(vLine.clone().addClass(ORGCHART_STYLES.lineVerticalTop));
}
}
},
_renderGroup: function(group, items, level, parentColumns, parentLeft) {
var vertical = true,
nodeContainer;
nodeContainer = $(NODE_CONTAINER);
group.append(nodeContainer);
vertical = this._renderInner(nodeContainer, items, level, parentColumns, parentLeft);
this._orientation(group, level, vertical);
},
_renderInner: function(nodeContainer, items, level, parentColumns, parentLeft) {
var buttonTemplate = kendo.template(BUTTON_TEMPLATE),
cardWrapperTemplate = kendo.template(CARD_WRAPPER),
numberOfColumns = parentColumns / items.length,
vertical = true,
vLine = $("<div>").addClass(ORGCHART_STYLES.line + SPACE + ORGCHART_STYLES.lineVertical),
hLine = $("<div>").addClass(ORGCHART_STYLES.line + SPACE + ORGCHART_STYLES.lineHorizontal),
messages = this.options.messages,
i, item, guid, node, button, innerGroup, itemWidth, spacing, contentTemplate;
if(!this.options.template) {
contentTemplate = kendo.template(CARD_TEMPLATE);
} else if (typeof this.options.template === "function") {
contentTemplate = this.options.template;
} else {
contentTemplate = kendo.template(this.options.template);
}
for(i = 0; i < items.length; i++) {
item = items[i];
guid = kendo.guid();
node = this._renderNode(cardWrapperTemplate, contentTemplate, item, level, guid);
if(item.hasChildren) {
node.append(vLine.clone());
button = $(buttonTemplate({ buttonSign: item.expanded ? MINUS : PLUS, label: item.expanded ? messages.collapse : messages.expand }));
node.append(button);
}
nodeContainer.append(node);
this._calculateDimensions();
itemWidth = this._itemWidth;
spacing = this._spacing;
if(item.hasChildren) {
vertical = false;
if(item.expanded) {
innerGroup = this._renderInnerGroup(item, numberOfColumns, parentLeft, i, level, guid);
}
}
if(!!innerGroup && innerGroup.hasClass(ORGCHART_STYLES.groupHorizontal) && item.expanded && !!item.children && item.children.length > 1) {
button.after(hLine.clone().css({
width: (numberOfColumns - numberOfColumns / item.children.length) * (itemWidth + spacing) + PX,
"margin-top": this._buttonHeight / -2 + PX
}));
}
}
if(numberOfColumns > 1 && !vertical) {
nodeContainer.find(DOT + ORGCHART_STYLES.node).width((numberOfColumns - 1) * (spacing + itemWidth));
}
return vertical;
},
_renderInnerGroup: function(item, numberOfColumns, parentLeft, i, level, guid) {
var itemWidth = this._itemWidth,
spacing = this._spacing,
width = numberOfColumns * itemWidth + (numberOfColumns - 1) * spacing,
left = (i * numberOfColumns * itemWidth) + parentLeft,
groupTemplate = kendo.template(GROUP_TEMPLATE),
offsetDirection = kendo.support.isRtl(this.element) ? "right" : "left",
top = level * (this._itemHeight + this._buttonHeight + spacing) + spacing * (level - 1) - this._buttonHeight / 2,
innerGroup;
if(i > 0) {
left += (i * numberOfColumns * spacing);
}
innerGroup = $(groupTemplate({
guid: guid,
level: level + 1
}));
innerGroup.css({
width: width + PX,
top: top + PX
});
innerGroup.css(offsetDirection, left + PX);
this.element.append(innerGroup);
this._renderGroup(innerGroup, item.children, level + 1, numberOfColumns, left);
return innerGroup;
}
});
var GroupedView = View.extend({
init: function(element, options) {
View.fn.init.call(this, element, options);
this._selector = ORGCHART_STYLES.nodesGroupContainer;
},
collapse: function(group) {
var $group = this.jqueryGroupElement(group),
dataItems, i;
if(!$group) {
return;
}
dataItems = this._dataItems($group);
for(i = 0; i < dataItems.length; i++) {
this.dataSource.toggleChildren(dataItems[i], false).then(proxy(this.refresh, this));
}
},
expand: function(group) {
var $group = this.jqueryGroupElement(group),
dataItems, i;
if(!$group) {
return;
}
dataItems = this._dataItems($group);
for(i = 0; i < dataItems.length; i++) {
this.dataSource.toggleChildren(dataItems[i], true).then(proxy(this.refresh, this));
}
},
_dataItems: function(container) {
var ds = this.dataSource,
dataItems = [],
items, item, current;
if(container.hasClass(ORGCHART_STYLES.card)) {
item = ds.getByUid(container.data(UID));
if(item) {
dataItems.push(item);
}
} else if(container.hasClass(ORGCHART_STYLES.nodesGroupContainer)) {
this._groupFocused = true;
items = container.find(DOT + ORGCHART_STYLES.card);
items.each(function(i, item) {
current = ds.getByUid(item.getAttribute("data-uid"));
if(current) {
dataItems.push(current);
}
});
}
return dataItems;
},
_calculateItemWidth: function() {
var itemElement = this.element.find(DOT + this._selector).first(),
cardWidth = this.element.find(DOT + ORGCHART_STYLES.card).first().outerWidth(true),
padding = Number(itemElement.css("padding-left").split(PX)[0]),
border = Number(itemElement.css("border-left").split(PX)[0]);
return cardWidth+ 2 * padding + 2* border;
},
_calculateLevel: function(groups, level) {
var groupsLength = groups.length,
nestedChildren = false,
maxColumns = 0,
currentLength, i, group;
this._maxColumnsPerLevel[level] = this._maxColumnsPerLevel[level] || 0;
this._maxGroups[level] = this._maxGroups[level] || 0;
for(i = 0; i < groupsLength; i++) {
group = groups[i];
currentLength = group.items.length;
if (currentLength > maxColumns) {
maxColumns = currentLength;
}
group = groups[i];
if(group.hasChildren) {
nestedChildren = true;
if(group.expanded) {
this._calculateLevel(group.children, level + 1);
}
}
}
if(groupsLength > this._maxGroups[level]) {
this._maxGroups[level] = groupsLength;
}
if(!nestedChildren) {
maxColumns = 1;
}
if(maxColumns > this._maxColumnsPerLevel[level]) {
this._maxColumnsPerLevel[level] = maxColumns;
}
},
_calculateLevels: function() {
var items = this._itemsTree,
maxColumnsPerLevel = this._maxColumnsPerLevel = [],
maxGroups = this._maxGroups = [],
total = 1,
i, currentTotal;
this._calculateLevel(items, 0);
for(i = maxColumnsPerLevel.length - 1; i >= 0; i--) {
currentTotal = maxColumnsPerLevel[i] * maxGroups[i];
if(total > maxColumnsPerLevel[i]) {
total = total * maxGroups[i];
} else if(total < currentTotal) {
total = currentTotal;
}
}
this._total = total;
},
_generateItemsTree: function() {
this._itemsTree = this.dataSource.groupedItemsTree(this.options.groupField);
},
_getToFocus: function(item) {
if(!this._groupFocused) {
return this.element.find("[data-uid='" + item.get(UID) + "']");
} else {
this._groupFocused = false;
return this.element.find("[data-uid='" + item.get(UID) + "']").closest(DOT + ORGCHART_STYLES.nodesGroupContainer);
}
},
_getToSelect: function(el) {
var item = this.jqueryItemElement(el);
return item || this.jqueryGroupElement(el);
},
_groupIsVertical: function(focused) {
var itemGroup = focused.closest(DOT + ORGCHART_STYLES.nodeContainer);
return itemGroup.hasClass(ORGCHART_STYLES.vstack);
},
_keyCollapse: function(focused) {
var dataItems = [],
parentUid, expanded;
dataItems = this._dataItems(focused);
expanded = dataItems.some(function(item) {
return item.expanded;
});
if(expanded) {
if(focused.hasClass(ORGCHART_STYLES.card)) {
focused = focused.closest(DOT + ORGCHART_STYLES.nodesGroupContainer);
dataItems = this._dataItems(focused);
}
if(!this.trigger(COLLAPSE, { item: focused, dataItems: dataItems })) {
this.collapse(focused);
}
} else if(dataItems[0].parentId) {
parentUid = this.dataSource.get(dataItems[0].parentId).get(UID);
this.trigger(SELECT, {
item: this.element.find("[data-uid='" + parentUid + "']").closest(DOT + this._selector),
dataItems: dataItems
});
}
},
_keyEnter: function(focused) {
var toSelect,
dataItems = [];
if(focused.hasClass(ORGCHART_STYLES.card) && focused.find(DOT + ORGCHART_STYLES.cardMenu).length > 0) {
this.trigger(MENU, focused);
} else {
toSelect = focused.find(DOT + ORGCHART_STYLES.card).first();
dataItems = this._dataItems(toSelect);
this.trigger(SELECT, {
item: toSelect,
dataItems: dataItems
});
}
},
_keyEscape: function(focused) {
if(!focused.hasClass(ORGCHART_STYLES.card)) {
return;
}
var group = focused.closest(DOT + ORGCHART_STYLES.nodesGroupContainer),
dataItems = this._dataItems(group);
this.trigger(SELECT, {
item: group,
dataItems: dataItems
});
},
_keyExpand: function(focused) {
var ownedGroupId = focused.attr(ARIA_OWNS) || focused.closest(DOT + this._selector).attr(ARIA_OWNS),
ownedGroup = this.element.find(HASH + ownedGroupId),
dataItems = this._dataItems(focused),
hasChildren, expanded, item;
hasChildren = dataItems.some(function(item) {
return item.hasChildren;
});
if(!hasChildren) {
return;
}
expanded = dataItems.some(function(item) {
return item.expanded;
});
if(!expanded) {
if(focused.hasClass(ORGCHART_STYLES.card)) {
focused = focused.closest(DOT + ORGCHART_STYLES.nodesGroupContainer);
dataItems = this._dataItems(focused);
}
if(!this.trigger(EXPAND, { item: focused, dataItems: dataItems })) {
this.expand(focused);
}
} else {
item = ownedGroup.find(DOT + this._selector).first();
this.trigger(SELECT, {
item: item,
dataItems: this._dataItems(item)
});
}
},
_keyNext: function(focused) {
var ownedGroup = this.element.find(HASH + focused.attr(ARIA_OWNS)),
dataItems = this._dataItems(focused),
hasChildren = dataItems.some(function(item) {
return item.hasChildren;
}),
expanded = dataItems.some(function(item) {
return item.expanded;
}),
next;
if(focused.hasClass(ORGCHART_STYLES.card)) {
next = focused.parent().next(DOT + ORGCHART_STYLES.node).find(DOT + ORGCHART_STYLES.card);
} else {
next = focused.parent().next(DOT + ORGCHART_STYLES.nodesGroup).find(DOT + ORGCHART_STYLES.nodesGroupContainer);
}
if(!next.length && hasChildren && expanded) {
next = ownedGroup.find(DOT + this._selector).first();
}
if(next.length === 0) {
return;
}
this.trigger(SELECT, {
item: next,
dataItems: this._dataItems(next)
});
},
_keyPrev: function(focused) {
var dataItems = this._dataItems(focused),
parentUid, prev;
if(focused.hasClass(ORGCHART_STYLES.card)) {
prev = focused.parent().prev(DOT + ORGCHART_STYLES.node).find(DOT + ORGCHART_STYLES.card);
} else {
prev = focused.parent().prev(DOT + ORGCHART_STYLES.nodesGroup).find(DOT + ORGCHART_STYLES.nodesGroupContainer);
}
if(!prev.length && dataItems[0].parentId) {
parentUid = this.dataSource.get(dataItems[0].parentId).get(UID);
prev = this.element.find("[data-uid='" + parentUid + "']").closest(DOT + this._selector);
}
if(prev.length === 0) {
return;
}
this.trigger(SELECT, {
item: prev,
dataItems: this._dataItems(prev)
});
},
_onFocus: function(e) {
var target = $(e.target),
items, current;
if(this._preventTriggerSelect) {
e.stopPropagation();
this._preventTriggerSelect = false;
return;
}
if(target.hasClass(ORGCHART_STYLES.cardMenu)) {
if(target.closest("[tabindex='0']").length > 0) {
e.stopPropagation();
return;
} else {
this._preventTriggerSelect = true;
}
}
if(!target.hasClass(ORGCHART_STYLES.card) && !target.hasClass(ORGCHART_STYLES.nodesGroupContainer)) {
current = target.closest(DOT + ORGCHART_STYLES.card);
if(!current.length) {
current = target.closest(DOT + ORGCHART_STYLES.nodesGroupContainer);
}
target = current;
}
if(target.length === 0) {
return;
}
items = this._dataItems(target);
if(!target.hasClass(ORGCHART_STYLES.focused)) {
e.stopPropagation();
this.trigger(SELECT, {
item: target,
dataItems: items
});
}
},
_onSelect: function(e) {
var target = $(e.target),
previousSelection = this.element.find("[tabindex=0]"),
items, current;
if(!target.hasClass(ORGCHART_STYLES.card) && !target.hasClass(ORGCHART_STYLES.nodesGroupContainer)) {
current = target.closest(DOT + ORGCHART_STYLES.card);
if(!current.length) {
current = target.closest(DOT + ORGCHART_STYLES.nodesGroupContainer);
}
target = current;
}
if(target.length === 0 || previousSelection[0] === target[0]) {
return;
}
items = this._dataItems(target);
this.trigger(SELECT, {
item: target,
dataItems: items
});
},
_orientation: function(group, level, vertical) {
var vLine = $("<div>").addClass(ORGCHART_STYLES.line + SPACE + ORGCHART_STYLES.lineVertical + SPACE + ORGCHART_STYLES.lineVerticalTop);
group.addClass(ORGCHART_STYLES.hstack);
if(level > 1) {
group.find(DOT + ORGCHART_STYLES.nodesGroupContainer).before(vLine.clone());
}
if(vertical && level > 1) {
group.find(DOT + ORGCHART_STYLES.nodeContainer).removeClass(ORGCHART_STYLES.hstack);
group.find(DOT + ORGCHART_STYLES.nodeContainer).addClass(ORGCHART_STYLES.vstack);
} else {
group.addClass(ORGCHART_STYLES.groupHorizontal);
}
},
_renderChildren: function(item, index, numberOfColumns, level, nodesGroup, parentLeft, guid) {
var buttonTemplate = kendo.template(BUTTON_TEMPLATE),
groupTemplate = kendo.template(GROUP_TEMPLATE),
vLine = $("<div>").addClass(ORGCHART_STYLES.line + SPACE + ORGCHART_STYLES.lineVertical),
hLine = $("<div>").addClass(ORGCHART_STYLES.line + SPACE + ORGCHART_STYLES.lineHorizontal),
messages = this.options.messages,
vertical = true,
offsetDirection = kendo.support.isRtl(this.element) ? "right" : "left",
innerGroup, button, left, top, width, nodesGroupWidth, spacing;
if(item.hasChildren) {
vertical = false;
nodesGroup.append(vLine.clone());
button = $(buttonTemplate({ buttonSign: item.expanded ? MINUS : PLUS, label: item.expanded ? messages.collapse : messages.expand }));
nodesGroup.append(button);