@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,461 lines (1,184 loc) • 59.7 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.data.js');
require('./kendo.icons.js');
require('./kendo.core.js');
require('./kendo.data.odata.js');
require('./kendo.data.xml.js');
require('./kendo.html.icon.js');
require('./kendo.html.base.js');
require('@progress/kendo-svg-icons');
const __meta__ = {
id: "panelbar",
name: "PanelBar",
category: "web",
description: "The PanelBar widget displays hierarchical data as a multi-level expandable panel bar.",
depends: ["core", "data", "data.odata", "icons"]
};
(function($, undefined$1) {
var kendo = window.kendo,
ui = kendo.ui,
keys = kendo.keys,
extend = $.extend,
encode = kendo.htmlEncode,
each = $.each,
isArray = Array.isArray,
template = kendo.template,
Widget = ui.Widget,
HierarchicalDataSource = kendo.data.HierarchicalDataSource,
excludedNodesRegExp = /^(ul|a|div)$/i,
NS = ".kendoPanelBar",
IMG = "img",
HREF = "href",
LINK = "k-link",
LINKSELECTOR = "." + LINK,
ERROR = "error",
ITEM = ".k-panelbar-item",
GROUP = ".k-panelbar-group",
VISIBLEGROUP = GROUP + ":visible",
IMAGE = "k-image",
CHANGE = "change",
EXPAND = "expand",
SELECT = "select",
CLICK = "click",
CONTENT = "k-panelbar-content",
ACTIVATE = "activate",
COLLAPSE = "collapse",
DATABOUND = "dataBound",
MOUSEENTER = "mouseenter",
MOUSELEAVE = "mouseleave",
CONTENTLOAD = "contentLoad",
UNDEFINED = "undefined",
EXPANDEDCLASS = "k-expanded",
GROUPS = "> .k-panelbar-group",
CONTENTS = "> .k-panelbar-content",
STRING = "string",
FOCUSEDCLASS = "k-focus",
DISABLEDCLASS = "k-disabled",
SELECTEDCLASS = "k-selected",
SELECTEDSELECTOR = "." + SELECTEDCLASS,
ACTIVEITEMSELECTOR = ITEM + ":not(.k-disabled)",
clickableItems = "> " + ACTIVEITEMSELECTOR + " > " + LINKSELECTOR + ", .k-panelbar-group > " + ACTIVEITEMSELECTOR + " > " + LINKSELECTOR,
disabledItems = ITEM + ".k-disabled > .k-link",
selectableItems = "> li > " + SELECTEDSELECTOR + ", .k-panelbar-group > li > " + SELECTEDSELECTOR,
ARIA_DISABLED = "aria-disabled",
ARIA_EXPANDED = "aria-expanded",
ARIA_HIDDEN = "aria-hidden",
ARIA_SELECTED = "aria-selected",
VISIBLE = ":visible",
EMPTY = ":empty",
SINGLE = "single",
bindings = {
text: "dataTextField",
url: "dataUrlField",
spriteCssClass: "dataSpriteCssClassField",
imageUrl: "dataImageUrlField",
icon: "dataIconField",
iconClass: "dataIconClassField",
},
itemIcon,
rendering = {
aria: function(item) {
var attr = "";
if (item.items || item.content || item.contentUrl || item.expanded) {
attr += ARIA_EXPANDED + "='" + (item.expanded ? "true" : "false") + "' ";
}
if (item.enabled === false) {
attr += ARIA_DISABLED + "='true'";
}
return attr;
},
wrapperCssClass: function(group, item) {
var result = "k-panelbar-item";
item.index;
if (group.firstLevel) {
result += " k-panelbar-header";
}
if (item.enabled === false) {
result += " " + DISABLEDCLASS;
} else if (item.expanded === true) {
result += " " + EXPANDEDCLASS;
}
if (item.cssClass) {
result += " " + item.cssClass;
}
if (item.level) {
result += " k-level-" + item.level();
}
return result;
},
textClass: function(item) {
var result = LINK;
if (item.selected) {
result += " " + SELECTEDCLASS;
}
return result;
},
textAttributes: function(url) {
return url ? " href='" + url + "'" : "";
},
arrowIconOptions: function(item) {
return {
icon: item.expanded ? "chevron-up" : "chevron-down",
iconClass: `k-panelbar-toggle k-panelbar-${item.expanded ? "collapse" : "expand"}`
};
},
text: function(item) {
return item.encoded === false ? item.text : kendo.htmlEncode(item.text);
},
groupAttributes: function(group) {
return group.expanded !== true ? ` ${kendo.attr("style-display")}="none"` : "";
},
ariaHidden: function(group) {
return group.expanded !== true;
},
groupCssClass: function() {
return "k-panelbar-group";
},
contentAttributes: function(content) {
return content.item.expanded !== true ? ` ${kendo.attr("style-display")}="none"` : "";
},
content: function(item) {
return item.content ? item.content : item.contentUrl ? "" : " ";
},
contentUrl: function(item) {
return item.contentUrl ? 'href="' + item.contentUrl + '"' : "";
}
};
function updateLevel(item) {
item = $(item);
item.addClass("k-level-" + item.parentsUntil(".k-panelbar", "ul").length);
}
function updateItemHtml(item) {
var wrapper = item,
group = item.children("ul"),
toggleButton = wrapper.children(".k-link").children(".k-panelbar-toggle");
if (item.hasClass("k-panelbar")) {
return;
}
if (!toggleButton.length && group.length) {
toggleButton = $("<span class='k-panelbar-toggle' />").appendTo(wrapper);
} else if (!group.length || !group.children().length) {
toggleButton.remove();
group.remove();
}
}
itemIcon = function(item) {
return item.children("span").children(".k-panelbar-toggle");
};
var PanelBar = kendo.ui.DataBoundWidget.extend({
init: function(element, options) {
var that = this,
content,
hasDataSource;
if (isArray(options)) {
options = { dataSource: options };
}
hasDataSource = options && !!options.dataSource;
Widget.fn.init.call(that, element, options);
element = that.wrapper = that.element.addClass("k-panelbar");
options = that.options;
if (element[0].id) {
that._itemId = element[0].id + "_pb_active";
}
that._tabindex();
that._accessors();
that._dataSource();
that._templates();
that._initData(hasDataSource);
that._updateClasses();
that._animations(options);
element
.on(CLICK + NS, clickableItems, that._click.bind(that))
.on(MOUSEENTER + NS + " " + MOUSELEAVE + NS, clickableItems, that._toggleHover)
.on(CLICK + NS, disabledItems, false)
.on(CLICK + NS, ".k-request-retry", that._retryRequest.bind(that))
.on("keydown" + NS, that._keydown.bind(that))
.on("focus" + NS, function() {
var item = that.select();
that._current(item[0] ? item : that._first());
})
.on("blur" + NS, function() {
that._current(null);
})
.attr("role", "tree");
content = element.find("li." + EXPANDEDCLASS + " > ." + CONTENT);
if (content[0]) {
that.expand(content.parent(), false);
}
kendo.notify(that);
if (that._showWatermarkOverlay) {
that._showWatermarkOverlay(that.wrapper[0]);
}
},
events: [
EXPAND,
COLLAPSE,
SELECT,
ACTIVATE,
CHANGE,
ERROR,
DATABOUND,
CONTENTLOAD
],
options: {
name: "PanelBar",
dataSource: {},
animation: {
expand: {
effects: "expand:vertical",
duration: 200
},
collapse: { // if collapse animation effects are defined, they will be used instead of expand.reverse
duration: 200
}
},
messages: {
loading: "Loading...",
requestFailed: "Request failed.",
retry: "Retry"
},
autoBind: true,
loadOnDemand: true,
expandMode: "multiple",
template: null,
dataTextField: null,
selectable: true
},
destroy: function() {
Widget.fn.destroy.call(this);
this.element.off(NS);
kendo.destroy(this.element);
},
_initData: function(hasDataSource) {
var that = this;
if (hasDataSource) {
that.element.empty();
if (that.options.autoBind) {
that._progress(true);
that.dataSource.fetch();
}
}
},
_templates: function() {
var that = this,
options = that.options,
fieldAccessor = that._fieldAccessor.bind(that);
if (options.template && typeof options.template == STRING) {
options.template = template(options.template);
} else if (!options.template) {
options.template = template((data) => {
var text = fieldAccessor("text")(data.item);
if (data.item.encoded !== false) {
text = encode(text);
}
return `<span class='k-panelbar-item-text'>${text}</span>`;
});
}
that.templates = {
content: template(
({ data, item, contentAttributes, content }) => `<div class='k-panelbar-content'${contentAttributes({ data, item, contentAttributes, content })}>${content(item)}</div>`
),
group: template( ({ data, items, group, renderItems, panelBar, ariaHidden, groupCssClass, groupAttributes }) =>
`<ul role='group' aria-hidden='${ariaHidden(group)}' class='${groupCssClass(group)}' ${groupAttributes(group)}>` +
renderItems({ data, items, group, renderItems, panelBar, ariaHidden, groupCssClass, groupAttributes }) +
"</ul>"
),
itemWrapper: template(({ panelBar, item, arrow, textClass, arrowIconOptions, textAttributes, contentUrl }) => {
var url = fieldAccessor("url")(item);
var imageUrl = fieldAccessor("imageUrl")(item);
var spriteCssClass = fieldAccessor("spriteCssClass")(item);
var icon = fieldAccessor("icon")(item);
var iconClass = fieldAccessor("iconClass")(item);
iconClass = iconClass ? " " + iconClass : "";
var contentUrl = contentUrl(item);
var tag = url || contentUrl ? 'a' : 'span';
return `<${tag} class='${textClass(item)}' ${contentUrl}${textAttributes(url)}>` +
(imageUrl ? `<img class='k-panelbar-item-icon k-image' alt='' src='${imageUrl}' />` : '') +
(spriteCssClass ? `<span class='k-sprite ${spriteCssClass}'></span>` : '') +
(icon ? kendo.ui.icon($("<span></span>"), { icon: icon, iconClass: "k-panelbar-item-icon" + iconClass }) : '') +
panelBar.options.template({ panelBar, item, arrow, textClass, textAttributes, contentUrl }) +
arrow({ panelBar, item, arrow, textClass, arrowIconOptions, textAttributes, contentUrl }) +
`</${tag}>`;
}),
item: template(({ data, group, item, panelBar, itemWrapper, renderContent, arrow, arrowIconOptions, subGroup, aria, wrapperCssClass, contentUrl, textClass, textAttributes }) =>
`<li aria-selected='false' role='treeitem' ${aria(item)}class='${wrapperCssClass(group, item)}' ` +
kendo.attr("uid") + `='${item.uid}'>` +
itemWrapper({ data, group, item, panelBar, itemWrapper, renderContent, arrow, arrowIconOptions, subGroup, aria, wrapperCssClass, contentUrl, textClass, textAttributes }) +
((item.items && item.items.length > 0) ?
subGroup({ items: item.items, panelBar: panelBar, group: { expanded: item.expanded } })
: ((item.content || item.contentUrl) ?
renderContent({ data, group, item, panelBar, itemWrapper, renderContent, arrow, arrowIconOptions, subGroup, aria, wrapperCssClass, contentUrl, textClass, textAttributes })
: "")
) +
"</li>"
),
loading: template(({ messages }) => `<li class='k-panelbar-item'><span class='k-icon k-i-loading'></span> ${encode(messages.loading)}</li>`),
retry: template(({ messages }) =>
"<li class='k-panelbar-item'>" +
`${encode(messages.requestFailed)} ` +
`<button class='k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-request-retry'><span class='k-button-text'>${encode(messages.retry)}</span></button>` +
"</li>"
),
arrow: template(({ item, arrowIconOptions }) => kendo.ui.icon(arrowIconOptions(item))),
empty: template(() => "")
};
},
setOptions: function(options) {
var animation = this.options.animation;
this._animations(options);
options.animation = extend(true, animation, options.animation);
if ("dataSource" in options) {
this.setDataSource(options.dataSource);
}
Widget.fn.setOptions.call(this, options);
},
expand: function(element, useAnimation) {
var that = this,
animBackup = {};
element = this.element.find(element);
if (that._animating && element.find("ul").is(":visible")) {
that.one("complete", function() {
setTimeout(function() {
that.expand(element);
});
});
return;
}
that._animating = true;
useAnimation = useAnimation !== false;
element.each(function(index, item) {
item = $(item);
var wrapper = element.children(".k-panelbar-group,.k-panelbar-content");
if (!wrapper.length) {
wrapper = that._addGroupElement(element);
}
var groups = wrapper.add(item.find(CONTENTS));
if (!item.hasClass(DISABLEDCLASS) && groups.length > 0) {
if (that.options.expandMode == SINGLE && that._collapseAllExpanded(item)) {
return that;
}
if (!useAnimation) {
animBackup = that.options.animation;
that.options.animation = { expand: { effects: {} }, collapse: { hide: true, effects: {} } };
}
if (!that._triggerEvent(EXPAND, item)) {
that._toggleItem(item, false, false);
}
if (!useAnimation) {
that.options.animation = animBackup;
}
}
});
return that;
},
collapse: function(element, useAnimation) {
var that = this,
animBackup = {};
that._animating = true;
useAnimation = useAnimation !== false;
element = that.element.find(element);
element.each(function(index, item) {
item = $(item);
var groups = item.find(GROUPS).add(item.find(CONTENTS));
if (!item.hasClass(DISABLEDCLASS) && groups.is(VISIBLE)) {
if (!useAnimation) {
animBackup = that.options.animation;
that.options.animation = { expand: { effects: {} }, collapse: { hide: true, effects: {} } };
}
if (!that._triggerEvent(COLLAPSE, item)) {
that._toggleItem(item, true);
}
if (!useAnimation) {
that.options.animation = animBackup;
}
}
});
return that;
},
updateArrow: function(items) {
var that = this;
items = $(items);
items.children(LINKSELECTOR).children(".k-panelbar-collapse, .k-panelbar-expand").remove();
items
.filter(function() {
var dataItem = that.dataItem(this);
if (!dataItem) {
return $(this).find(".k-panelbar-group").length > 0 ||
$(this).find(".k-panelbar-content").length > 0;
}
return dataItem.hasChildren || dataItem.content || dataItem.contentUrl;
})
.children(".k-link:not(:has([class*=-i-chevron]))")
.each(function() {
var item = $(this),
parent = item.parent();
let icon = kendo.ui.icon({
icon: parent.hasClass(EXPANDEDCLASS) ? "chevron-up" : "chevron-down",
iconClass: `k-panelbar-toggle k-panelbar-${parent.hasClass(EXPANDEDCLASS) ? "collapse" : "expand" }`
});
item.append(icon);
});
},
_accessors: function() {
var that = this,
options = that.options,
i, field, textField,
element = that.element;
for (i in bindings) {
field = options[bindings[i]];
textField = element.attr(kendo.attr(i + "-field"));
if (!field && textField) {
field = textField;
}
if (!field) {
field = i;
}
if (!isArray(field)) {
field = [field];
}
options[bindings[i]] = field;
}
},
_progress: function(item, showProgress) {
var element = this.element;
var loadingText = this.templates.loading({ messages: this.options.messages });
if (arguments.length == 1) {
showProgress = item;
if (showProgress) {
element.html(loadingText);
} else {
element.empty();
}
}
else {
itemIcon(item)
.empty()
.removeClass("k-i-arrow-rotate-cw k-svg-i-arrow-rotate-cw")
.toggleClass("k-i-loading", showProgress);
}
},
_refreshRoot: function(items) {
var that = this;
var parent = that.element;
var groupData = {
firstLevel: true,
expanded: true,
length: parent.children().length
};
this.element.empty();
var rootItemsHtml = $.map(items, function(value, idx) {
if (typeof value === "string") {
return $(value);
} else {
value.items = [];
let itemElement = $(that.renderItem({
group: groupData,
item: extend(value, { index: idx })
}));
kendo.applyStylesFromKendoAttributes(itemElement, ["display"]);
return itemElement;
}
});
this.element.append(rootItemsHtml);
var elements = this.element.children(".k-panelbar-item");
for (var i = 0; i < items.length; i++) {
this.trigger("itemChange", {
item: elements.eq(i).find(".k-link").first(),
data: items[i],
ns: ui
});
}
},
_refreshChildren: function(item, parentNode) {
var i, children, child;
parentNode.children(".k-panelbar-group").empty();
var items = item.children.data();
if (!items.length) {
updateItemHtml(parentNode);
children = parentNode.children(".k-panelbar-group").children("li");
} else {
this.append(item.children, parentNode);
if (this.options.loadOnDemand) {
this._toggleGroup(parentNode.children(".k-panelbar-group"), false);
}
children = parentNode.children(".k-panelbar-group").children("li");
for (i = 0; i < children.length; i++) {
child = children.eq(i);
this.trigger("itemChange", {
item: child.find(".k-link").first(),
data: this.dataItem(child),
ns: ui
});
}
}
},
findByUid: function(uid) {
var items = this.element.find(".k-panelbar-item");
var uidAttr = kendo.attr("uid");
var result;
for (var i = 0; i < items.length; i++) {
if (items[i].getAttribute(uidAttr) == uid) {
result = items[i];
break;
}
}
return $(result);
},
refresh: function(e) {
var options = this.options;
var node = e.node;
var action = e.action;
var items = e.items;
var parentNode = this.wrapper;
var loadOnDemand = options.loadOnDemand;
if (e.field) {
if (!items[0] || !items[0].level) {
return;
}
return this._updateItems(items, e.field);
}
if (node) {
parentNode = this.findByUid(node.uid);
this._progress(parentNode, false);
}
if (action == "add") {
this._appendItems(e.index, items, parentNode);
} else if (action == "remove") {
this.remove(this.findByUid(items[0].uid));
} else if (action == "itemchange") {
this._updateItems(items);
} else if (action == "itemloaded") {
this._refreshChildren(node, parentNode);
} else {
this._refreshRoot(items);
}
if (action != "remove") {
for (var k = 0; k < items.length; k++) {
if (!loadOnDemand || items[k].expanded) {
var tempItem = items[k];
if (this._hasChildItems(tempItem)) {
tempItem.load();
}
}
}
}
this.trigger(DATABOUND, { node: node ? parentNode : undefined$1 });
},
_error: function(e) {
var node = e.node && this.findByUid(e.node.uid);
var retryHtml = this.templates.retry({ messages: this.options.messages });
if (node) {
this._progress(node, false);
kendo.ui.icon(itemIcon(node), { icon: "arrow-rotate-cw" });
e.node.loaded(false);
} else {
this._progress(false);
this.element.html(retryHtml);
}
},
_retryRequest: function(e) {
e.preventDefault();
this.dataSource.fetch();
},
items: function() {
return this.element.find(".k-panelbar-item > span:first-child");
},
setDataSource: function(dataSource) {
var options = this.options;
options.dataSource = dataSource;
this._dataSource();
if (this.options.autoBind) {
this._progress(true);
this.dataSource.fetch();
}
},
_bindDataSource: function() {
this._refreshHandler = this.refresh.bind(this);
this._errorHandler = this._error.bind(this);
this.dataSource.bind(CHANGE, this._refreshHandler);
this.dataSource.bind(ERROR, this._errorHandler);
},
_unbindDataSource: function() {
var dataSource = this.dataSource;
if (dataSource) {
dataSource.unbind(CHANGE, this._refreshHandler);
dataSource.unbind(ERROR, this._errorHandler);
}
},
// generates accessor function for a given field name, honoring the data*Field arrays
_fieldAccessor: function(fieldName) {
var fieldBindings = this.options[bindings[fieldName]] || [],
count = fieldBindings.length;
if (count === 0) {
return (function(item) { return item[fieldName]; });
} else {
return (function(item) {
var levels = $.map(fieldBindings, kendo.getter);
if (item.level) {
return levels[Math.min(item.level(), count - 1)](item);
} else {
return levels[count - 1](item);
}
});
}
},
_dataSource: function() {
var that = this,
options = that.options,
dataSource = options.dataSource;
if (!dataSource) {
return;
}
dataSource = isArray(dataSource) ? { data: dataSource } : dataSource;
that._unbindDataSource();
if (!dataSource.fields) {
dataSource.fields = [
{ field: "text" },
{ field: "url" },
{ field: "spriteCssClass" },
{ field: "imageUrl" },
{ field: "icon" },
{ field: "iconClass" }
];
}
that.dataSource = HierarchicalDataSource.create(dataSource);
that._bindDataSource();
},
_appendItems: function(index, items, parentNode) {
var that = this, children, wrapper;
if (parentNode.hasClass("k-panelbar")) {
children = parentNode.children("li");
wrapper = parentNode;
} else {
wrapper = parentNode.children(".k-panelbar-group");
if (!wrapper.length) {
wrapper = that._addGroupElement(parentNode);
}
children = wrapper.children("li");
}
var groupData = {
firstLevel: parentNode.hasClass("k-panelbar"),
expanded: true,
length: children.length
};
var itemsHtml = $.map(items, function(value, idx) {
if (typeof value === "string") {
return $(value);
} else {
let itemElement = $(that.renderItem({
group: groupData,
item: extend(value, { index: idx })
}));
kendo.applyStylesFromKendoAttributes(itemElement, ["display"]);
return itemElement;
}
});
if (typeof index == UNDEFINED) {
index = children.length;
}
for (var i = 0; i < itemsHtml.length; i++) {
if (children.length === 0 || index === 0) {
wrapper.append(itemsHtml[i]);
} else {
itemsHtml[i].insertAfter(children[index - 1]);
}
}
if (that.dataItem(parentNode)) {
that.dataItem(parentNode).hasChildren = true;
that.updateArrow(parentNode);
}
},
_updateItems: function(items, field) {
var that = this;
var i, node, nodeWrapper, item;
var context = { panelBar: that.options, item: item, group: {} };
var render = field != "expanded";
if (field == "selected") {
if (items[0][field]) {
var currentNode = that.findByUid(items[0].uid);
if (!currentNode.hasClass(DISABLEDCLASS)) {
that.select(currentNode, true);
}
} else {
that.clearSelection();
}
} else {
var elements = $.map(items, function(item) {
return that.findByUid(item.uid);
});
for (i = 0; i < items.length; i++) {
context.item = item = items[i];
context.panelBar = that;
nodeWrapper = elements[i];
node = nodeWrapper.parent();
if (render) {
context.group = {
firstLevel: node.hasClass("k-panelbar"),
expanded: nodeWrapper.parent().hasClass(EXPANDEDCLASS),
length: nodeWrapper.children().length
};
nodeWrapper.children(".k-link").remove();
nodeWrapper.prepend(that.templates.itemWrapper(extend(context,
{
arrow: item.hasChildren || item.content || item.contentUrl ? that.templates.arrow : that.templates.empty
},
rendering)));
}
if (field == "expanded") {
that._toggleItem(nodeWrapper, !item[field], item[field] ? "true" : true);
} else if (field == "enabled") {
that.enable(nodeWrapper, item[field]);
if (!item[field]) {
if (item.selected) {
item.set("selected", false);
}
}
}
if (nodeWrapper.length) {
this.trigger("itemChange", { item: nodeWrapper.find(".k-link").first(), data: item, ns: ui });
}
}
}
},
_toggleDisabled: function(element, enable) {
element = this.element.find(element);
element
.toggleClass(DISABLEDCLASS, !enable)
.attr(ARIA_DISABLED, !enable);
},
dataItem: function(item) {
var uid = $(item).closest(ITEM).attr(kendo.attr("uid")),
dataSource = this.dataSource;
return dataSource && dataSource.getByUid(uid);
},
select: function(element, skipChange) {
var that = this;
if (element === undefined$1) {
return that.element.find(selectableItems).parent();
}
element = that.element.find(element);
if (!element.length) {
this._updateSelected(element);
} else {
element
.each(function() {
var item = $(this),
link = item.children(LINKSELECTOR);
if (item.hasClass(DISABLEDCLASS)) {
return that;
}
that._updateSelected(link, skipChange);
});
}
return that;
},
clearSelection: function() {
this.select($());
},
enable: function(element, state) {
this._toggleDisabled(element, state !== false);
return this;
},
disable: function(element) {
this._toggleDisabled(element, false);
return this;
},
append: function(item, referenceItem) {
referenceItem = this.element.find(referenceItem);
var inserted = this._insert(item, referenceItem, referenceItem.length ? referenceItem.find(GROUPS) : null);
each(inserted.items, function() {
inserted.group.append(this);
updateLevel(this);
});
this.updateArrow(referenceItem);
inserted.group.height("auto");
return this;
},
insertBefore: function(item, referenceItem) {
referenceItem = this.element.find(referenceItem);
var inserted = this._insert(item, referenceItem, referenceItem.parent());
each(inserted.items, function() {
referenceItem.before(this);
updateLevel(this);
});
inserted.group.height("auto");
return this;
},
insertAfter: function(item, referenceItem) {
referenceItem = this.element.find(referenceItem);
var inserted = this._insert(item, referenceItem, referenceItem.parent());
each(inserted.items, function() {
referenceItem.after(this);
updateLevel(this);
});
inserted.group.height("auto");
return this;
},
remove: function(element) {
element = this.element.find(element);
var that = this,
parent = element.parentsUntil(that.element, ITEM),
group = element.parent("ul");
element.remove();
if (group && !group.hasClass("k-panelbar") && !group.children(ITEM).length) {
group.remove();
}
if (parent.length) {
parent = parent.eq(0);
that.updateArrow(parent);
}
return that;
},
reload: function(element) {
var that = this;
element = that.element.find(element);
element.each(function() {
var item = $(this);
that._ajaxRequest(item, item.children("." + CONTENT), !item.is(VISIBLE));
});
},
_first: function() {
return this.element.children(ACTIVEITEMSELECTOR).first();
},
_last: function() {
var item = this.element.children(ACTIVEITEMSELECTOR).last(),
group = item.children(VISIBLEGROUP);
if (group[0]) {
return group.children(ACTIVEITEMSELECTOR).last();
}
return item;
},
_current: function(candidate) {
var that = this,
focused = that._focused,
id = that._itemId;
if (candidate === undefined$1) {
return focused;
}
that.element.removeAttr("aria-activedescendant");
if (focused && focused.length) {
if (focused[0].id === id) {
focused.removeAttr("id");
}
focused
.children(LINKSELECTOR)
.removeClass(FOCUSEDCLASS);
}
if ($(candidate).length) {
id = candidate[0].id || id;
candidate.attr("id", id)
.children(LINKSELECTOR)
.addClass(FOCUSEDCLASS);
that.element.attr("aria-activedescendant", id);
}
that._focused = candidate;
},
_keydown: function(e) {
var that = this,
key = e.keyCode,
current = that._current();
if (e.target != e.currentTarget) {
return;
}
if (key == keys.DOWN || key == keys.RIGHT) {
that._current(that._nextItem(current));
e.preventDefault();
} else if (key == keys.UP || key == keys.LEFT) {
that._current(that._prevItem(current));
e.preventDefault();
} else if (key == keys.ENTER || key == keys.SPACEBAR) {
that._click(e);
e.preventDefault();
} else if (key == keys.HOME) {
that._current(that._first());
e.preventDefault();
} else if (key == keys.END) {
that._current(that._last());
e.preventDefault();
}
},
_nextItem: function(item) {
if (!item) {
return this._first();
}
var group = item.children(VISIBLEGROUP),
next = item.nextAll(":visible").first();
if (group[0]) {
next = group.children().first();
}
if (!next[0]) {
next = item.parent(VISIBLEGROUP).parent(ITEM).next();
}
if (!next[0]) {
next = this._first();
}
return next;
},
_prevItem: function(item) {
if (!item) {
return this._last();
}
var prev = item.prevAll(":visible").first(),
result;
if (!prev[0]) {
prev = item.parent(VISIBLEGROUP).parent(ITEM);
if (!prev[0]) {
prev = this._last();
}
} else {
result = prev;
while (result[0]) {
result = result.children(VISIBLEGROUP).children().last();
if (result[0]) {
prev = result;
}
}
}
return prev;
},
_insert: function(item, referenceItem, parent) {
var that = this,
items,
plain = $.isPlainObject(item),
isReferenceItem = referenceItem && referenceItem[0],
groupData;
if (!isReferenceItem) {
parent = that.element;
}
groupData = {
firstLevel: parent.hasClass("k-panelbar"),
expanded: $(referenceItem).hasClass(EXPANDEDCLASS),
length: parent.children().length
};
if (isReferenceItem && !parent.length) {
parent = $(that.renderGroup({ group: groupData, options: that.options }));
kendo.applyStylesFromKendoAttributes(parent, ["display"]);
parent.appendTo(referenceItem);
}
if (plain || Array.isArray(item) || item instanceof HierarchicalDataSource) { // is JSON or HierarchicalDataSource
if (item instanceof HierarchicalDataSource) {
item = item.data();
}
items = $.map(plain ? [item] : item, function(value, idx) {
if (typeof value === "string") {
return $(value);
} else {
let itemElement = $(that.renderItem({
group: groupData,
item: extend(value, { index: idx })
}));
kendo.applyStylesFromKendoAttributes(itemElement, ["display"]);
return itemElement;
}
});
if (isReferenceItem) {
var dataItem = that.dataItem(referenceItem);
if (dataItem) {
dataItem.hasChildren = true;
referenceItem
.attr(ARIA_EXPANDED, dataItem.expanded)
.not("." + EXPANDEDCLASS)
.children("ul")
.attr(ARIA_HIDDEN, !dataItem.expanded);
} else {
referenceItem.attr(ARIA_EXPANDED, false);
}
}
} else {
if (typeof item == "string" && item.charAt(0) != "<") {
items = that.element.find(item);
} else {
items = $(item);
}
that._updateItemsClasses(items);
}
if (!item.length) {
item = [item];
}
return { items: items, group: parent };
},
_toggleHover: function(e) {
var target = $(e.currentTarget);
if (!target.parents("li." + DISABLEDCLASS).length) {
target.toggleClass("k-hover", e.type == MOUSEENTER);
}
},
_updateClasses: function() {
var that = this,
panels, items, expanded, panelsParent, dataItem;
panels = that.element
.find("li > ul")
.not(function() { return $(this).parentsUntil(".k-panelbar", "div").length; })
.addClass("k-panelbar-group")
.attr("role", "group");
panelsParent = panels.parent();
dataItem = that.dataItem(panelsParent);
expanded = (dataItem && dataItem.expanded) || false;
panels.parent()
.not("[" + ARIA_EXPANDED + "]")
.attr(ARIA_EXPANDED, expanded)
.not("." + EXPANDEDCLASS)
.children("ul")
.attr(ARIA_HIDDEN, !expanded)
.hide();
items = that.element.add(panels).children();
that._updateItemsClasses(items);
that.updateArrow(items);
},
_updateItemsClasses: function(items) {
var length = items.length,
idx = 0;
for (; idx < length; idx++) {
this._updateItemClasses(items[idx], idx);
}
},
_updateItemClasses: function(item, index) {
var selected = this._selected,
contentUrls = this.options.contentUrls,
url = contentUrls && contentUrls[index],
root = this.element[0],
wrapElement, link;
item = $(item)
.addClass("k-panelbar-item")
.attr({
role: "treeitem",
"aria-selected": false
});
if (kendo.support.browser.msie) { // IE10 doesn't apply list-style: none on invisible items otherwise.
item.css("list-style-position", "inside")
.css("list-style-position", "");
}
item
.children(IMG)
.addClass(IMAGE);
link = item
.children("a")
.addClass(LINK);
if (link[0]) {
link.attr("href", url); //url can be undefined
link.children(IMG)
.addClass(IMAGE);
}
item
.filter("li[disabled]")
.addClass("k-disabled")
.attr(ARIA_DISABLED, true)
.prop("disabled", false);
item
.children("div")
.addClass(CONTENT + " k-panelbar-content")
.attr(ARIA_HIDDEN, true)
.hide()
.parent()
.attr(ARIA_EXPANDED, false);
link = item.children(SELECTEDSELECTOR);
if (link[0]) {
if (selected) {
selected.attr(ARIA_SELECTED, false)
.children(SELECTEDSELECTOR)
.removeClass(SELECTEDCLASS);
}
link.addClass(SELECTEDCLASS);
this._selected = item.attr(ARIA_SELECTED, true);
}
if (!item.children(LINKSELECTOR)[0]) {
wrapElement = "<span class='" + LINK + "'><span class='k-panelbar-item-text'></span></span>";
if (contentUrls && contentUrls[index] && item[0].parentNode == root) {
wrapElement = '<a class="k-link" href="' + contentUrls[index] + '"></a>';
}
item
.contents() // exclude groups, real links, templates and empty text nodes
.filter(function() { return (!this.nodeName.match(excludedNodesRegExp) && !(this.nodeType == 3 && !kendo.trim(this.nodeValue.trim))); })
.wrapAll(wrapElement);
}
if (item.parent(".k-panelbar")[0]) {
item.addClass("k-panelbar-header");
} else {
item.addClass("k-panelbar-item");
}
if (!/k\-level\-\d+/i.test(item.attr("class"))) {
item.addClass("k-level-" + item.parentsUntil(this.element, "ul").length);
}
},
_click: function(e) {
var that = this,
target = e.type == CLICK ? $(e.target) : that._current().children(LINKSELECTOR),
element = that.element,
prevent, contents, href, isAnchor;
if (target.parents("li." + DISABLEDCLASS).length) {
return;
}
if (target.closest(".k-panelbar")[0] != element[0]) {
return;
}
if (target.is(":kendoFocusable") && !target.hasClass(LINK)) {
return;
}
var link = target.closest(LINKSELECTOR),
item = link.closest(ITEM);
that._updateSelected(link);
var wrapper = item.children(".k-panelbar-group,.k-panelbar-content");
var dataItem = this.dataItem(item);
if (!wrapper.length && ((that.options.loadOnDemand && dataItem && dataItem.hasChildren) ||
this._hasChildItems(item) || item.content || item.contentUrl)) {
wrapper = that._addGroupElement(item);
}
contents = item.find(GROUPS).add(item.find(CONTENTS));
href = link.attr(HREF);
isAnchor = href && (href.charAt(href.length - 1) == "#" || href.indexOf("#" + that.element[0].id + "-") != -1);
prevent = !!(isAnchor || contents.length);
if (contents.data("animating") && prevent) {
e.preventDefault();
return;
}
if (that._triggerEvent(SELECT, item)) {
prevent = true;
}
if (prevent === false) {
return;
}
if (that.options.expandMode == SINGLE) {
if (that._collapseAllExpanded(item) && prevent) {
e.preventDefault();
return;
}
}
if (contents.length) {
var visibility = contents.is(VISIBLE);
if (!that._triggerEvent(!visibility ? EXPAND : COLLAPSE, item)) {
prevent = that._toggleItem(item, visibility);
}
}
if (prevent) {
e.preventDefault();
}
},
_hasChildItems: function(item) {
return (item.items && item.items.length > 0) || item.hasChildren;
},
_toggleItem: function(element, isVisible, expanded) {
var that = this,
childGroup = element.find(GROUPS),
link = element.find(LINKSELECTOR),
url = link.attr(HREF),
prevent, content,
dataItem = that.dataItem(element),
notVisible = !isVisible;
var loaded = dataItem && dataItem.loaded();
if (dataItem && !expanded && dataItem.expanded !== notVisible) {
dataItem.set("expanded", notVisible);
prevent = dataItem.hasChildren || !!dataItem.content || !!dataItem.contentUrl;
return prevent;
}
if (dataItem && (!expanded || expanded === "true") && !loaded && !dataItem.content && !dataItem.contentUrl) {
if (that.options.loadOnDemand) {
this._progress(element, true);
}
element.children(".k-panelbar-group,.k-panelbar-content").remove();
prevent = dataItem.hasChildren;
dataItem.load();
} else {
if (childGroup.length) {
this._toggleGroup(childGroup, isVisible);
prevent = true;