@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,557 lines (1,300 loc) • 332 kB
JavaScript
import './kendo.dom.js';
import './kendo.data.js';
import './kendo.columnsorter.js';
import './kendo.editable.js';
import './kendo.window.js';
import './kendo.filtermenu.js';
import './kendo.columnmenu.js';
import './kendo.selectable.js';
import './kendo.resizable.js';
import './kendo.treeview.draganddrop.js';
import './kendo.pager.js';
import './kendo.filtercell.js';
import './kendo.textbox.js';
import './kendo.form.js';
import './kendo.toolbar.js';
import './kendo.icons.js';
import './kendo.reorderable.js';
import './mixins-C63N9J7p.js';
import './kendo.ooxml.js';
import './kendo.core.js';
import './html-DIrOxn6k.js';
import './mixins-pM1BXjp5.js';
import './kendo.progressbar.js';
import './kendo.menu.js';
import './kendo.licensing.js';
import '@progress/kendo-licensing';
import './kendo.data.odata.js';
import './kendo.data.xml.js';
import './kendo.html.icon.js';
import './kendo.html.base.js';
import '@progress/kendo-svg-icons';
import './kendo.checkbox.js';
import './kendo.toggleinputbase.js';
import './kendo.html.input.js';
import './kendo.dropdownlist.js';
import './kendo.list.js';
import './kendo.popup.js';
import './kendo.label.js';
import './kendo.floatinglabel.js';
import './kendo.actionsheet.js';
import './kendo.html.button.js';
import './dropdowns-loader-00xUvouJ.js';
import './kendo.mobile.scroller.js';
import './kendo.fx.js';
import './kendo.draganddrop.js';
import './kendo.userevents.js';
import './kendo.virtuallist.js';
import './valueMapper-CXgI6HWc.js';
import './kendo.datepicker.js';
import './kendo.calendar.js';
import './kendo.dateinput.js';
import '@progress/kendo-dateinputs-common';
import './kendo.numerictextbox.js';
import './prefix-suffix-containers-B9VRe3lS.js';
import './kendo.validator.js';
import './kendo.binder.js';
import './kendo.otpinput.js';
import './kendo.buttongroup.js';
import './kendo.togglebutton.js';
import './kendo.button.js';
import './kendo.badge.js';
import './kendo.pane.js';
import './kendo.view.js';
import './kendo.tabstrip.js';
import './kendo.sortable.js';
import './kendo.expansionpanel.js';
import './kendo.autocomplete.js';
import './kendo.combobox.js';
import './kendo.splitbutton.js';
import './kendo.button.menu.js';
import './kendo.dropdownbutton.js';
import '@progress/kendo-ooxml';
import '@progress/kendo-drawing';
import './kendo.color.js';
(function($, undefined$1) {
var kendo = window.kendo,
ui = kendo.ui,
ContextMenu = ui.ContextMenu,
extend = $.extend,
encode = kendo.htmlEncode;
var ACTION = "action";
var TreeListContextMenu = ContextMenu.extend({
init: function(element, options) {
var that = this;
ContextMenu.fn.init.call(that, element, options);
that._overrideTemplates();
that._extendItems();
that.bind("select", that._onSelect.bind(that));
that.bind("open", that._onOpen.bind(that));
},
_overrideTemplates: function() {
this.templates.sprite = ({ icon, spriteCssClass }) => `${(icon || spriteCssClass) ? kendo.ui.icon({ icon: encode(icon || ""), iconClass: encode(spriteCssClass || "") }) : ''}`;
},
defaultItems: {
"separator": { name: "separator", separator: true },
"create": { name: "create", text: "Add", icon: "plus", command: "AddCommand", rules: "isEditable" },
"createChild": { name: "createChild", text: "Add Child", icon: "plus", command: "CreateChildCommand", rules: "isEditable" },
"edit": { name: "edit", text: "Edit", icon: "pencil", command: "EditCommand", rules: "isEditable" },
"destroy": { name: "destroy", text: "Delete", icon: "trash", command: "DeleteCommand", rules: "isEditable" },
"select": { name: "select", text: "Select", icon: "table-body", rules: "isSelectable", items: [
{ name: "selectRow", text: "Row", icon: "table-row-groups", command: "SelectRowCommand" },
{ name: "selectAllRows", text: "All rows", icon: "grid", command: "SelectAllRowsCommand", softRules: "isMultiRowSelectionEnabled" },
{ name: "clearSelection", text: "Clear selection", icon: "table-unmerge", softRules: "hasSelection", command: "ClearSelectionCommand" },
] },
"exportPDF": { name: "exportPDF", text: "Export to PDF", icon: "file-pdf", command: "ExportPDFCommand" },
"exportExcel": { name: "exportExcel", text: "Export to Excel", icon: "file-excel", command: "ExportExcelCommand" },
"sortAsc": { name: "sortAsc", text: "Sort Ascending", icon: "sort-asc-small", rules: "isSortable", command: "SortCommand", options: "dir:asc" },
"sortDesc": { name: "sortDesc", text: "Sort Descending", icon: "sort-desc-small", rules: "isSortable", command: "SortCommand", options: "dir:desc" },
"expandItem": { name: "expandItem", text: "Expand Item", icon: "folder-open", softRules: "isExpandable", command: "ToggleItemCommand", options: "expand:true" },
"collapseItem": { name: "collapseItem", text: "Collapse Item", icon: "folder", softRules: "isCollapsible", command: "ToggleItemCommand", options: "expand:false" }
},
events: ContextMenu.fn.events.concat([
ACTION
]),
_onSelect: function(ev) {
var command = $(ev.item).data("command");
var options = $(ev.item).data("options");
options = options ? options.split(",")
.map(val => {
if (val.indexOf(":") > -1) {
var [key, val] = val.split(":");
return { [key || "_"]: val };
}
return { [val]: true };
})
.reduce((acc, v) => Object.assign(acc, v), {}) : {};
var target = $(ev.target);
if (!command) {
return;
}
this.action({
command: command,
options: Object.assign(options, { target: target })
});
},
_onOpen: function(ev) {
var menu = ev.sender,
items = menu.options.items,
elTarget = $(ev.event ? ev.event.target : null);
if ((!items && $.isEmptyObject(this.defaultItems)) || elTarget.closest(".k-grid-column-menu").length) {
ev.preventDefault();
return;
}
this._toggleSeparatorVisibility();
menu.element.find(`[${kendo.attr('soft-rules')}]`).each((i, item) => {
var rules = $(item).attr(kendo.attr('soft-rules')).split(";");
menu.enable(item, this._validateSoftRules(rules, elTarget));
});
},
_toggleSeparatorVisibility: function() {
var that = this,
items = that.element.find(".k-item.k-separator").filter((i, item) => {
var prev = $(item).prev(".k-item:not(.k-separator)");
var next = $(item).next(".k-item:not(.k-separator)");
return !(prev.length && next.length);
});
items.hide();
},
_extendItems: function() {
var that = this,
items = that.options.items,
item, isBuiltInTool;
if (items && items.length) {
for (var i = 0; i < items.length; i++) {
item = items[i];
isBuiltInTool = $.isPlainObject(item) && Object.keys(item).length === 1 && item.name;
if (isBuiltInTool) {
item = item.name;
}
if ($.isPlainObject(item)) {
that._append(item);
} else if (that.defaultItems[item]) {
item = that.defaultItems[item];
that._append(item);
} else if (typeof(item) === "string") {
item = { name: item, text: item, spriteCssClass: item, command: item + "Command" };
that._append(item);
}
}
} else {
for (var key in that.defaultItems) {
item = that.defaultItems[key];
that._append(item);
}
}
},
_extendItem: function(item) {
var that = this,
messages = that.options.messages,
attr = item.attr || {};
if (item.command) {
attr[kendo.attr("command")] = item.command;
}
if (item.options) {
attr[kendo.attr("options")] = item.options;
}
if (item.softRules) {
attr[kendo.attr("soft-rules")] = item.softRules;
}
if (item.items) {
for (var j = 0; j < item.items.length; j++) {
item.items.forEach(subItem => {
that._extendItem(subItem);
});
}
}
extend(item, {
text: messages.commands[item.name],
icon: item.icon || "",
spriteCssClass: item.spriteCssClass || "",
attr: attr,
uid: kendo.guid()
});
},
_validateSoftRules: function(rules, target) {
if (!rules || !(rules && rules.length)) {
return true;
}
for (var i = 0; i < rules.length; i++) {
if (!this._readState(rules[i], target)) {
return false;
}
}
return true;
},
_validateRules: function(tool) {
var rules = tool.rules ? tool.rules.split(";") : [];
if (!rules.length) {
return true;
}
for (var i = 0; i < rules.length; i++) {
if (!this._readState(rules[i])) {
return false;
}
}
return true;
},
_readState: function(state, target) {
var that = this,
states = that.options.states;
if (kendo.isFunction(states[state])) {
return states[state](target);
} else {
return states[state];
}
},
_append: function(item) {
var that = this;
that._extendItem(item);
if (that._validateRules(item)) {
that.append(item);
}
},
action: function(args) {
this.trigger(ACTION, args);
}
});
kendo.ui.treelist = kendo.ui.treelist || {};
extend(kendo.ui.treelist, {
ContextMenu: TreeListContextMenu
});
})(window.kendo.jQuery);
(function($, undefined$1) {
var kendo = window.kendo,
extend = $.extend,
Class = kendo.Class;
var Command = Class.extend({
init: function(options) {
this.options = options;
this.treelist = options.treelist;
}
});
var SortCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
dataSource = treelist.dataSource,
sort = dataSource.sort() || [],
options = that.options,
dir = options.dir,
field = options.target.attr(kendo.attr("field")),
multipleMode = treelist.options.sortable.mode && treelist.options.sortable.mode === "multiple",
compare = treelist.options.compare,
length, idx;
if (multipleMode) {
for (idx = 0, length = sort.length; idx < length; idx++) {
if (sort[idx].field === field) {
sort.splice(idx, 1);
break;
}
}
sort.push({ field: field, dir: dir, compare: compare });
} else {
sort = [{ field: field, dir: dir, compare: compare }];
}
dataSource.sort(sort);
},
});
var AddCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist;
treelist.addRow();
}
});
var CreateChildCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
target = that.options.target.closest("tr");
treelist.addRow(target);
}
});
var EditCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
inCellMode = treelist._editMode() === "incell",
target = inCellMode ? that.options.target : that.options.target.closest("tr");
if (inCellMode) {
treelist.editCell(target);
} else {
treelist.editRow(target);
}
}
});
var DeleteCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
target = that.options.target.closest("tr");
treelist.removeRow(target);
}
});
var SelectRowCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
selectMode = kendo.ui.Selectable.parseOptions(treelist.options.selectable),
target = that.options.target.closest("tr");
treelist.select(selectMode.cell ? target.find('td') : target);
}
});
var SelectAllRowsCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
selectMode = kendo.ui.Selectable.parseOptions(treelist.options.selectable),
rows = treelist.items();
treelist.select(selectMode.cell ? rows.find('td') : rows);
}
});
var ClearSelectionCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist;
treelist.clearSelection();
}
});
var ExportPDFCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist;
treelist.saveAsPDF();
}
});
var ExportExcelCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist;
treelist.saveAsExcel();
}
});
var ToggleItemCommand = Command.extend({
exec: function() {
var that = this,
treelist = that.treelist,
target = that.options.target,
options = that.options,
expand = options.expand === 'true';
if (expand) {
treelist.expand(target);
} else {
treelist.collapse(target);
}
}
});
kendo.ui.treelist = kendo.ui.treelist || {};
extend(kendo.ui.treelist, {
TreeListCommand: Command,
commands: {
SortCommand: SortCommand,
AddCommand: AddCommand,
CreateChildCommand: CreateChildCommand,
EditCommand: EditCommand,
DeleteCommand: DeleteCommand,
SelectRowCommand: SelectRowCommand,
SelectAllRowsCommand: SelectAllRowsCommand,
ClearSelectionCommand: ClearSelectionCommand,
ExportPDFCommand: ExportPDFCommand,
ExportExcelCommand: ExportExcelCommand,
ToggleItemCommand: ToggleItemCommand
}
});
})(window.kendo.jQuery);
const __meta__ = {
id: "treelist",
name: "TreeList",
category: "web",
description: "The TreeList widget displays self-referencing data and offers rich support for interacting with data, sorting, filtering, and selection.",
depends: [ "dom", "data", "pager", "toolbar", "icons", "reorderable", "menu" ],
features: [ {
id: "treelist-sorting",
name: "Sorting",
description: "Support for column sorting",
depends: [ "columnsorter" ]
}, {
id: "treelist-filtering",
name: "Filtering",
description: "Support for record filtering",
depends: [ "filtermenu" ]
}, {
id: "treelist-columnmenu",
name: "Column menu",
description: "Support for header column menu",
depends: [ "columnmenu" ]
}, {
id: "treelist-editing",
name: "Editing",
description: "Support for record editing",
depends: [ "editable", "window", "textbox", "form" ]
}, {
id: "treelist-selection",
name: "Selection",
description: "Support for row selection",
depends: [ "selectable" ]
}, {
id: "treelist-column-resize",
name: "Column resizing",
description: "Support for column resizing",
depends: [ "resizable" ]
}, {
id: "treelist-dragging",
name: "Drag & Drop",
description: "Support for drag & drop of rows",
depends: [ "treeview.draganddrop" ]
}, {
id: "treelist-excel-export",
name: "Excel export",
description: "Export data as Excel spreadsheet",
depends: [ "excel" ]
}, {
id: "treelist-pdf-export",
name: "PDF export",
description: "Export data as PDF",
depends: [ "pdf", "drawing", "progressbar" ]
}, {
id: "treelist-paging",
name: "Paging",
description: "Support for treelist paging",
depends: [ "pager" ]
} ]
};
(function($, undefined$1) {
var data = kendo.data;
var encode = kendo.htmlEncode;
var kendoDom = kendo.dom;
var kendoDomElement = kendoDom.element;
var kendoTextElement = kendoDom.text;
var kendoHtmlElement = kendoDom.html;
var outerWidth = kendo._outerWidth;
var keys = $.extend({ F10: 121 }, kendo.keys);
var outerHeight = kendo._outerHeight;
var ui = kendo.ui;
var DataBoundWidget = ui.DataBoundWidget;
var DataSource = data.DataSource;
var ObservableArray = data.ObservableArray;
var Query = data.Query;
var Model = data.Model;
var browser = kendo.support.browser;
var kendoTemplate = kendo.template;
var toCamelCase = kendo.toCamelCase;
var activeElement = kendo._activeElement;
var touchDevice = kendo.support.touch;
var isArray = Array.isArray;
var extend = $.extend;
var map = $.map;
var grep = $.grep;
var inArray = $.inArray;
var isPlainObject = $.isPlainObject;
var push = Array.prototype.push;
var STRING = "string";
var CHANGE = "change";
var ITEM_CHANGE = "itemChange";
var ERROR = "error";
var PROGRESS = "progress";
var DOT = ".";
var NS = ".kendoTreeList";
var CLICK = "click";
var INPUT = "input";
var BEFORE_EDIT = "beforeEdit";
var EDIT = "edit";
var PAGE = "page";
var PAGE_CHANGE = "pageChange";
var SAVE = "save";
var SAVE_CHANGES = "saveChanges";
var EXPAND = "expand";
var COLLAPSE = "collapse";
var CELL_CLOSE = "cellClose";
var REMOVE = "remove";
var DATA_CELL = "td:not(.k-group-cell):not(.k-hierarchy-cell):visible,th:not(.k-group-cell):not(.k-hierarchy-cell):visible";
var FILTER_CELL = ".k-filter-row td:not(.k-group-cell):not(.k-hierarchy-cell):visible,.k-filter-row th:not(.k-group-cell):not(.k-hierarchy-cell):visible";
var DATABINDING = "dataBinding";
var DATABOUND = "dataBound";
var CANCEL = "cancel";
var TABINDEX = "tabIndex";
var FILTERMENUINIT = "filterMenuInit";
var FILTERMENUOPEN = "filterMenuOpen";
var COLUMNHIDE = "columnHide";
var COLUMNSHOW = "columnShow";
var HEADERCELLS = "th.k-header";
var COLUMNREORDER = "columnReorder";
var COLUMNRESIZE = "columnResize";
var COLUMNMENUINIT = "columnMenuInit";
var COLUMNMENUOPEN = "columnMenuOpen";
var COLUMNLOCK = "columnLock";
var COLUMNUNLOCK = "columnUnlock";
var FILTER = "filter";
var NAVIGATE = "navigate";
var SORT = "sort";
var PARENTIDFIELD = "parentId";
var DRAGSTART = "dragstart";
var DRAG = "drag";
var DROP = "drop";
var DRAGEND = "dragend";
var NAVROW = "tr:visible";
var NAVCELL = "td:visible";
var NAVHEADER = "th:visible";
var NORECORDSCLASS = "k-grid-norecords";
var ITEMROW = "tr:not(.k-footer-template):visible";
var isRtl = false;
var HEIGHT = "height";
var INCELL = "incell";
var INLINE = "inline";
var POPUP = "popup";
var TABLE = "table";
var CHECKBOX = "k-checkbox";
var CHECKBOXINPUT = "input[data-role='checkbox']." + CHECKBOX;
var SELECTCOLUMNTMPL = '<input class="' + CHECKBOX + ' k-checkbox-md k-rounded-md" data-role="checkbox" aria-label="Select row" aria-checked="false" type="checkbox">';
var SELECTCOLUMNHEADERTMPL = '<input class="' + CHECKBOX + ' k-checkbox-md k-rounded-md" data-role="checkbox" aria-label="Select all rows" aria-checked="false" type="checkbox">';
var DRAGHANDLECOLUMNTMPL = () => kendo.ui.icon("reorder");
var SELECTED = "k-selected";
var whitespaceRegExp = "[\\x20\\t\\r\\n\\f]";
var filterRowRegExp = new RegExp("(^|" + whitespaceRegExp + ")" + "(k-filter-row)" + "(" + whitespaceRegExp + "|$)");
var ICON_REFRESH_SELECTOR = "[class*='-i-arrow-rotate-cw']";
var ICON_EXPAND_COLLAPSE_SELECTOR = "[ref-treelist-expand-collapse-icon]";
var CARET_ALT_RIGHT = "caret-alt-right";
var CARET_ALT_LEFT = "caret-alt-left";
var ARIA_LABEL = "aria-label";
var ARIA_LABEL = "aria-label",
ARIA_EXPANDED = "aria-expanded",
ARIA_ACTIVEDESCENDANT = "aria-activedescendant",
BLANK_ICON_SELECTOR = "[ref-blank-icon]";
var classNames = {
wrapper: "k-treelist k-grid k-grid-md",
header: "k-header k-table-th",
button: "k-button",
alt: "k-alt k-table-alt-row",
editCell: "k-edit-cell",
editRow: "k-grid-edit-row",
dirtyCell: "k-dirty-cell",
group: "k-treelist-group",
toolbar: "k-toolbar",
gridToolbar: "k-grid-toolbar",
gridHeader: "k-grid-header",
gridHeaderWrap: "k-grid-header-wrap",
gridContent: "k-grid-content",
gridContentWrap: "k-grid-content",
gridFilter: "k-grid-filter-menu",
footerTemplate: "k-footer-template",
focused: "k-focus",
loading: "k-i-loading",
refresh: "arrow-rotate-cw",
retry: "k-request-retry",
selected: "k-selected",
status: "k-status",
link: "k-link",
filterable: "k-filterable",
icon: "k-icon",
iconFilter: "filter",
iconCollapse: "caret-alt-down",
iconExpand: "caret-alt-right",
iconPlaceHolder: "k-treelist-toggle k-icon k-svg-icon",
input: "k-input",
dropPositions: "k-i-insert-top k-i-insert-bottom k-i-plus k-i-insert-middle",
dropTop: "insert-top",
dropBottom: "insert-bottom",
dropAdd: "plus",
dropMiddle: "insert-middle",
dropDenied: "cancel",
dragStatus: "k-drag-status",
dragClue: "k-drag-clue",
dragClueText: "k-clue-text",
headerCellInner: "k-cell-inner",
columnTitle: "k-column-title"
};
var defaultCommands = {
create: {
icon: "plus",
className: "k-grid-add",
methodName: "addRow"
},
createchild: {
icon: "plus",
className: "k-grid-add",
methodName: "addRow"
},
destroy: {
icon: "x",
className: "k-grid-remove-command",
methodName: "removeRow"
},
edit: {
icon: "pencil",
className: "k-button-solid-primary k-grid-edit-command",
methodName: "editRow"
},
update: {
icon: "save",
className: "k-button-solid-primary k-grid-save-command",
methodName: "saveRow"
},
canceledit: {
icon: "cancel",
className: "k-grid-cancel-command",
methodName: "_cancelEdit"
},
cancel: {
icon: "cancel-outline",
text: "Cancel changes",
className: "k-grid-cancel-changes",
methodName: "cancelChanges"
},
save: {
icon: "check",
text: "Save changes",
className: "k-grid-save-changes",
methodName: "saveChanges"
},
excel: {
icon: "file-excel",
className: "k-grid-excel",
methodName: "saveAsExcel"
},
pdf: {
icon: "file-pdf",
className: "k-grid-pdf",
methodName: "saveAsPDF"
},
search: {
template: ({ message }) =>
"<span class='k-spacer'></span>" +
"<span class='k-searchbox k-input k-input-md k-rounded-md k-input-solid k-grid-search'>" +
kendo.ui.icon({ icon: "search", iconClass: "k-input-icon" }) +
`<input autocomplete='off' placeholder='${message}' title='${message}' aria-label='${message}' class='k-input-inner' />` +
"</span>"
}
};
var defaultBodyContextMenu = [
"create",
"createChild",
"edit",
"destroy",
"separator",
"select",
"separator",
"exportPDF",
"exportExcel",
"separator",
"expandItem",
"collapseItem",
"separator"
];
var defaultHeadContextMenu = [
"sortAsc",
"sortDesc",
"separator"
];
var TreeView = kendo.Class.extend({
init: function(data, options) {
var that = this;
that.data = data || [];
that.options = extend(that.options, options);
},
options: {
defaultParentId: null,
idField: "id",
parentIdField: PARENTIDFIELD
},
childrenMap: function() {
var that = this;
var childrenMap = {};
var dataLength = that.data.length;
var dataItem;
var dataItemId;
var dataItemParentId;
var idField = that.options.idField;
var parentIdField = that.options.parentIdField;
if (that._childrenMap) {
return that._childrenMap;
}
for (var i = 0; i < dataLength; i++) {
dataItem = this.data[i];
dataItemId = dataItem[idField];
dataItemParentId = dataItem[parentIdField];
childrenMap[dataItemId] = childrenMap[dataItemId] || [];
childrenMap[dataItemParentId] = childrenMap[dataItemParentId] || [];
childrenMap[dataItemParentId].push(dataItem);
}
that._childrenMap = childrenMap;
return childrenMap;
},
idsMap: function() {
var that = this;
var idsMap = {};
var data = that.data;
var dataLength = data.length;
var dataItem;
var idField = that.options.idField;
if (that._idMap) {
return that._idMap;
}
for (var i = 0; i < dataLength; i++) {
dataItem = data[i];
idsMap[dataItem[idField]] = dataItem;
}
that.idsMap = idsMap;
return idsMap;
},
dataMaps: function() {
var that = this;
var childrenMap = {};
var data = that.data;
var dataLength = data.length;
var idsMap = {};
var dataItem;
var dataItemId;
var dataItemParentId;
var idField = that.options.idField;
var parentIdField = that.options.parentIdField;
if (that._dataMaps) {
return that._dataMaps;
}
for (var i = 0; i < dataLength; i++) {
dataItem = data[i];
dataItemId = dataItem[idField];
dataItemParentId = dataItem[parentIdField];
idsMap[dataItemId] = dataItem;
childrenMap[dataItemId] = childrenMap[dataItemId] || [];
childrenMap[dataItemParentId] = childrenMap[dataItemParentId] || [];
childrenMap[dataItemParentId].push(dataItem);
}
that._dataMaps = {
children: childrenMap,
ids: idsMap
};
return that._dataMaps;
},
rootNodes: function() {
var that = this;
var data = that.data;
var defaultParentId = that.options.defaultParentId;
var dataLength = data.length;
var rootNodes = [];
var dataItem;
var parentIdField = that.options.parentIdField;
for (var i = 0; i < dataLength; i++) {
dataItem = data[i];
if (dataItem[parentIdField] === defaultParentId) {
rootNodes.push(dataItem);
}
}
return rootNodes;
},
removeCollapsedSubtreesFromRootNodes: function(options) {
options = options || {};
var that = this;
var rootNodes = that.rootNodes();
var result = [];
var prunedTree;
that._childrenMap = options.childrenMap = options.childrenMap || that.childrenMap();
options.maxDepth = options.maxDepth || Infinity;
for (var i = 0; i < rootNodes.length; i++) {
prunedTree = that.removeCollapsedSubtrees(rootNodes[i], options);
result = result.concat(prunedTree);
}
return result;
},
removeCollapsedSubtrees: function(rootNode, options) {
options = options || {};
var that = this;
var result = [];
var childIdx;
var prunedTree;
var childrenMap = options.childrenMap || {};
var maxDepth = options.maxDepth || Infinity;
var idField = that.options.idField;
var children = childrenMap[rootNode[idField]] || [];
var expanded = isUndefined(rootNode.expanded) ? options.expanded : rootNode.expanded;
result.push(rootNode);
if (children && expanded) {
for (childIdx = 0; childIdx < children.length; childIdx++) {
if (result.length >= maxDepth) {
break;
}
prunedTree = that.removeCollapsedSubtrees(children[childIdx], options);
result = result.concat(prunedTree);
}
}
return result;
}
});
var TreeQuery = function(data) {
this.data = data || [];
};
TreeQuery.prototype = new Query();
TreeQuery.prototype.constructor = TreeQuery;
TreeQuery.process = function(data, options, inPlace) {
options = options || {};
var query = new TreeQuery(data);
var group = options.group;
var sort = Query.normalizeGroup(group || []).concat(Query.normalizeSort(options.sort || []));
var filterCallback = options.filterCallback;
var filter = options.filter;
var skip = options.skip;
var take = options.take;
var total;
var childrenMap;
var filteredChildrenMap;
var view;
var prunedData;
if (sort && inPlace) {
query = query.sort(sort, undefined$1, undefined$1, inPlace);
}
if (filter) {
query = query.filter(filter);
if (filterCallback) {
query = filterCallback(query);
}
total = query.toArray().length;
}
if (sort && !inPlace) {
query = query.sort(sort);
if (group) {
data = query.toArray();
}
}
if (options.processFromRootNodes) {
view = new TreeView(query.toArray(), options);
if (filter) {
filteredChildrenMap = view.childrenMap();
}
prunedData = view.removeCollapsedSubtreesFromRootNodes({
// filtering or sorting requires changes to childrenMap
childrenMap: filter || (sort && sort.length) ? undefined$1 : options.childrenMap,
expanded: options.expanded,
maxDepth: (skip + take) || Infinity
});
childrenMap = view.childrenMap();
query = new TreeQuery(prunedData);
}
if (skip !== undefined$1 && take !== undefined$1) {
query = query.range(skip, take);
}
if (group) {
query = query.group(group, data);
}
return {
total: total,
data: query.toArray(),
childrenMap: childrenMap,
filteredChildrenMap: filteredChildrenMap
};
};
var TreeListModel = Model.define({
id: "id",
parentId: PARENTIDFIELD,
fields: {
id: { type: "number" },
parentId: { type: "number", nullable: true }
},
init: function(value) {
Model.fn.init.call(this, value);
this._loaded = false;
if (!this.parentIdField) {
this.parentIdField = PARENTIDFIELD;
}
this.parentId = this.get(this.parentIdField);
},
accept: function(data) {
Model.fn.accept.call(this, data);
this.parentId = this.get(this.parentIdField);
},
set: function(field, value, initiator) {
if (field == PARENTIDFIELD && this.parentIdField != PARENTIDFIELD) {
this[this.parentIdField] = value;
}
Model.fn.set.call(this, field, value, initiator);
if (field == this.parentIdField) {
this.parentId = this.get(this.parentIdField);
}
},
loaded: function(value) {
if (value !== undefined$1) {
this._loaded = value;
} else {
return this._loaded;
}
},
shouldSerialize: function(field) {
return Model.fn.shouldSerialize.call(this, field) && field !== "_loaded" && field != "_error" && field != "_edit" && !(this.parentIdField !== "parentId" && field === "parentId");
}
});
TreeListModel.parentIdField = PARENTIDFIELD;
TreeListModel.define = function(base, options) {
if (options === undefined$1) {
options = base;
base = TreeListModel;
}
var parentId = options.parentId || PARENTIDFIELD;
options.parentIdField = parentId;
var model = Model.define(base, options);
{
model.parentIdField = parentId;
}
return model;
};
function is(field) {
return function(object) {
return object[field];
};
}
function not(func) {
return function(object) {
return !func(object);
};
}
var TreeListDataSource = DataSource.extend({
init: function(options) {
options = options || {};
var that = this;
that._dataMaps = that._getDataMaps();
options.schema = extend(true, {}, {
modelBase: TreeListModel,
model: TreeListModel
}, options.schema);
DataSource.fn.init.call(this, options);
},
_addRange: function() {
// empty override for performance - the treelist does not support virtualization
},
_createNewModel: function(data) {
var that = this;
var model = {};
var fromModel = data instanceof Model;
var parentIdField = this._modelParentIdField();
if (fromModel) {
model = data;
}
model = DataSource.fn._createNewModel.call(this, model);
if (!fromModel) {
if (data.parentId) {
data[model.parentIdField] = data.parentId;
} else if (that._isPageable() && data[parentIdField]) {
data[model.parentIdField] = data[parentIdField];
}
model.accept(data);
}
return model;
},
_shouldWrap: function() {
return true;
},
_push: function(result, operation) {
var data = DataSource.fn._readData.call(this, result);
if (!data) {
data = result;
}
this[operation](data);
},
_getData: function() {
// do not use .data(), which wraps the data items
return this._data || [];
},
_readData: function(newData) {
var that = this;
var data = that._isPageable() ? that._getData().toJSON() : that.data();
newData = DataSource.fn._readData.call(this, newData);
this._replaceData(((data.toJSON ? data.toJSON() : data)).concat(newData), data);
if (newData instanceof ObservableArray) {
return newData;
}
return data;
},
_replaceData: function(source, target) {
var sourceLength = source.length;
for (var i = 0; i < sourceLength; i++) {
target[i] = source[i];
}
target.length = sourceLength;
},
_readAggregates: function(data) {
var result = extend(this._aggregateResult, this.reader.aggregates(data));
if ("" in result) {
result[this._defaultParentId()] = result[""];
delete result[""];
}
return result;
},
read: function(data) {
var that = this;
if (that._isPageable()) {
that._dataMaps = {};
if (!that._modelOptions().expanded) {
that._skip = 0;
that._page = 1;
that._collapsedTotal = undefined$1;
}
}
return DataSource.fn.read.call(that, data);
},
remove: function(root) {
this._removeChildData(root);
this._removeFromDataMaps(root);
return DataSource.fn.remove.call(this, root);
},
_removeChildData: function(model, removePristine) {
var that = this;
var pageable = that._isPageable();
var data = pageable ? this._getData() : this.data();
var childrenMap = pageable ? that._getChildrenMap() || that.childrenMap(data) : that._childrenMap(data);
var items = this._subtree(childrenMap, model.id);
var shouldRemovePristine = isUndefined(removePristine) ? false : removePristine;
var removedItems = this._removeItems(items, shouldRemovePristine);
that._removeFromDataMaps(removedItems);
},
pushDestroy: function(items) {
var that = this;
if (!isArray(items)) {
items = [items];
}
for (var i = 0; i < items.length; i++) {
that._removeChildData(items[i], true);
that._removeFromDataMaps(items[i]);
}
DataSource.fn.pushDestroy.call(that, items);
},
insert: function(index, model) {
var that = this;
var newModel = that._createNewModel(model);
that._insertInDataMaps(newModel);
return DataSource.fn.insert.call(that, index, newModel);
},
_filterCallback: function(query) {
var that = this;
var i, item;
var map = {};
var result = [];
var data = query.toArray();
var idField = that._modelIdField();
var parentIdField = that._modelParentIdField();
var pageable = that._isPageable();
var parentSubtree = [];
var parent;
for (i = 0; i < data.length; i++) {
item = data[i];
if (pageable) {
// return view from root nodes to child nodes
parentSubtree = [];
if (!map[item[idField]]) {
map[item[idField]] = true;
parentSubtree.push(item);
}
parent = that._parentNode(item);
while (parent) {
if (!map[parent[idField]]) {
map[parent[idField]] = true;
parentSubtree.unshift(parent);
parent = that._parentNode(parent);
} else {
// the parent chain is already processed
break;
}
}
if (parentSubtree.length) {
result = result.concat(parentSubtree);
}
} else {
while (item) {
if (!map[item[idField]]) {
map[item[idField]] = true;
result.push(item);
}
if (!map[item[parentIdField]]) {
map[item[parentIdField]] = true;
item = this.parentNode(item);
if (item) {
result.push(item);
}
} else {
break;
}
}
}
}
return new Query(result);
},
_subtree: function(map, id) {
var that = this;
var result = map[id] || [];
var defaultParentId = that._defaultParentId();
var idField = that._modelIdField();
for (var i = 0, len = result.length; i < len; i++) {
if (result[i][idField] !== defaultParentId) {
result = result.concat(that._subtree(map, result[i][idField]));
}
}
return result;
},
// builds hash id -> children
_childrenMap: function(data) {
var map = {};
var i, item, id, parentId;
data = this._observeView(data);
for (i = 0; i < data.length; i++) {
item = data[i];
id = item.id;
parentId = item.parentId;
map[id] = map[id] || [];
map[parentId] = map[parentId] || [];
map[parentId].push(item);
}
return map;
},
childrenMap: function(data) {
var view = this._createTreeView(data);
var map = view.childrenMap();
return map;
},
_getChildrenMap: function() {
var that = this;
var dataMaps = that._getDataMaps();
return dataMaps.children;
},
_initIdsMap: function(data) {
var that = this;
var dataMaps = that._getDataMaps();
if (isUndefined(dataMaps.ids)) {
dataMaps.ids = that._idsMap(data);
}
return dataMaps.ids;
},
_idsMap: function(data) {
var view = this._createTreeView(data);
var map = view.idsMap();
return map;
},
_getIdsMap: function() {
var that = this;
var dataMaps = that._getDataMaps();
return dataMaps.ids || {};
},
_getFilteredChildrenMap: function() {
var that = this;
var dataMaps = that._getDataMaps();
return dataMaps.filteredChildren;
},
_setFilteredChildrenMap: function(map) {
var that = this;
var dataMaps = that._getDataMaps();
dataMaps.filteredChildren = map;
},
_initDataMaps: function(data) {
var that = this;
var view = that._createTreeView(data);
that._dataMaps = view.dataMaps();
return that._dataMaps;
},
_initChildrenMapForParent: function(parent) {
var that = this;
var data = that._getData();
var childrenMap = that._getChildrenMap();
var idField = that._modelIdField();
var parentIdField = that._modelParentIdField();
var parentId = (parent || {})[idField];
if (childrenMap && parent) {
childrenMap[parentId] = [];
for (var i = 0; i < data.length; i++) {
if (data[i][parentIdField] === parentId) {
childrenMap[parentId].push(data[i]);
}
}
}
},
_getDataMaps: function() {
var that = this;
that._dataMaps = that._dataMaps || {};
return that._dataMaps;
},
_createTreeView: function(data, options) {
var view = new TreeView(data, extend(options, this._defaultTreeModelOptions()));
return view;
},
_defaultTreeModelOptions: function() {
var that = this;
var modelOptions = that._modelOptions();
return {
defaultParentId: that._defaultParentId(),
idField: that._modelIdField(),
parentIdField: that._modelParentIdField(),
expanded: modelOptions.expanded
};
},
_defaultDataItemType: function() {
return this.reader.model || kendo.data.ObservableObject;
},
_calculateAggregates: function(data, options) {
options = options || {};
var that = this;
var result = {};
var item, subtree, i;
var filter = options.filter;
var skip = options.skip;
var take = options.take;
var maxDepth = !isUndefined(skip) && !isUndefined(take) ? (skip + take) : Infinity;
var pageable = that._isPageable();
var filteredChildrenMap = options.filteredChildrenMap;
var childrenMap = options.childrenMap;
var pageableChildrenMap;
if (pageable) {
if (isUndefined(options.aggregate)) {
return result;
}
if (filteredChildrenMap) {
pageableChildrenMap = filteredChildrenMap;
} else if (childrenMap) {
pageableChildrenMap = childrenMap;
} else {
pageableChildrenMap = that.childrenMap(that._getData());
}
}
if (!pageable && filter) {
data = Query.process(data, {
filter: filter,
filterCallback: this._filterCallback.bind(this)
}).data;
}
var map = pageable ? pageableChildrenMap : that._childrenMap(data);
// calculate aggregates for each subtree
result[this._defaultParentId()] = new Query(this._subtree(map, this._defaultParentId())).aggregate(options.aggregate);
for (i = 0; i < data.length; i++) {
if (i >= maxDepth) {
break;
}
item = data[i];
subtree = this._subtree(map, item.id);
result[item.id] = new Query(subtree).aggregate(options.aggregate);
}
return result;
},
_queryProcess: function(data, options) {
var that = this;
var result = {};
options = options || {};
options.filterCallback = this._filterCallback.bind(this);
if (that._isPageable()) {
return that._processPageableQuery(data, options);
} else {
var defaultParentId = this._defaultParentId();
result = Query.process(data, options);
var map = this._childrenMap(result.data);
var hasLoadedChildren, i, item, children;
data = map[defaultParentId] || [];
for (i = 0; i < data.length; i++) {
item = data[i];
if (item.id === defaultParentId) {
continue;
}
children = map[item.id];
hasLoadedChildren = !!(children && children.length);
if (!item.loaded()) {
item.loaded(hasLoadedChildren || !item.hasChildren);
}
if (item.loaded() || item.hasChildren !== true) {
item.hasChildren = hasLoadedChildren;
}
if (hasLoadedChildren) {
//cannot use splice due to IE8 bug
data = data.slice(0, i + 1).concat(children, data.slice(i + 1));
}