UNPKG

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