UNPKG

@progress/kendo-ui

Version:

This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.

1,581 lines (1,261 loc) 258 kB
module.exports = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ({ /***/ 0: /***/ (function(module, exports, __webpack_require__) { module.exports = __webpack_require__(1357); /***/ }), /***/ 3: /***/ (function(module, exports) { module.exports = function() { throw new Error("define cannot be used indirect"); }; /***/ }), /***/ 1003: /***/ (function(module, exports) { module.exports = require("./kendo.dom"); /***/ }), /***/ 1015: /***/ (function(module, exports) { module.exports = require("./kendo.data"); /***/ }), /***/ 1030: /***/ (function(module, exports) { module.exports = require("./kendo.selectable"); /***/ }), /***/ 1043: /***/ (function(module, exports) { module.exports = require("./kendo.filtermenu"); /***/ }), /***/ 1142: /***/ (function(module, exports) { module.exports = require("./kendo.resizable"); /***/ }), /***/ 1143: /***/ (function(module, exports) { module.exports = require("./kendo.window"); /***/ }), /***/ 1196: /***/ (function(module, exports) { module.exports = require("./kendo.columnsorter"); /***/ }), /***/ 1198: /***/ (function(module, exports) { module.exports = require("./kendo.editable"); /***/ }), /***/ 1203: /***/ (function(module, exports) { module.exports = require("./kendo.pager"); /***/ }), /***/ 1357: /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){ !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(1003), __webpack_require__(1015), __webpack_require__(1196), __webpack_require__(1198), __webpack_require__(1143), __webpack_require__(1043), __webpack_require__(1030), __webpack_require__(1142), __webpack_require__(1358), __webpack_require__(1203) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); })(function(){ var __meta__ = { // jshint ignore:line id: "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" ], 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-editing", name: "Editing", description: "Support for record editing", depends: [ "editable", "window" ] }, { 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" ] }, { id: "treelist-paging", name: "Paging", description: "Support for treelist paging", depends: [ "pager" ] } ] }; (function($, undefined) { var data = kendo.data; var kendoDom = kendo.dom; var kendoDomElement = kendoDom.element; var kendoTextElement = kendoDom.text; var kendoHtmlElement = kendoDom.html; var outerWidth = kendo._outerWidth; var keys = 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 activeElement = kendo._activeElement; var isArray = $.isArray; var extend = $.extend; var proxy = $.proxy; 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 MOUSEDOWN = "mousedown"; 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"; 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 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 FIRSTNAVITEM = NAVROW + " > td:first:visible"; var LASTITEMROW = ITEMROW + ":last"; var isRtl = false; var HEIGHT = "height"; var INCELL = "incell"; var INLINE = "inline"; var POPUP = "popup"; var TABLE = "table"; var classNames = { wrapper: "k-treelist k-grid k-widget k-display-block", header: "k-header", button: "k-button", alt: "k-alt", editCell: "k-edit-cell", editRow: "k-grid-edit-row", dirtyCell: "k-dirty-cell", group: "k-treelist-group", 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", footerTemplate: "k-footer-template", focused: "k-state-focused", loading: "k-i-loading", refresh: "k-i-reload", retry: "k-request-retry", selected: "k-state-selected", status: "k-status", link: "k-link", withIcon: "k-with-icon", filterable: "k-filterable", icon: "k-icon", iconFilter: "k-i-filter", iconCollapse: "k-i-collapse", iconExpand: "k-i-expand", iconHidden: "k-i-none", iconPlaceHolder: "k-icon k-i-none", input: "k-input", dropPositions: "k-i-insert-up k-i-insert-down k-i-plus k-i-insert-middle", dropTop: "k-i-insert-up", dropBottom: "k-i-insert-down", dropAdd: "k-i-plus", dropMiddle: "k-i-insert-middle", dropDenied: "k-i-cancel", dragStatus: "k-drag-status", dragClue: "k-drag-clue", dragClueText: "k-clue-text" }; var defaultCommands = { create: { imageClass: "k-i-plus", className: "k-grid-add", methodName: "addRow" }, createchild: { imageClass: "k-i-plus", className: "k-grid-add", methodName: "addRow" }, destroy: { imageClass: "k-i-close", className: "k-grid-delete", methodName: "removeRow" }, edit: { imageClass: "k-i-edit", className: "k-grid-edit", methodName: "editRow" }, update: { imageClass: "k-i-check", className: "k-primary k-grid-update", methodName: "saveRow" }, canceledit: { imageClass: "k-i-cancel", className: "k-grid-cancel", methodName: "_cancelEdit" }, cancel: { imageClass: "k-icon k-i-cancel", text: "Cancel changes", className: "k-grid-cancel-changes", methodName: "cancelChanges" }, save: { imageClass: "k-icon k-i-check", text: "Save changes", className: "k-grid-save-changes", methodName: "saveChanges" }, excel: { imageClass: "k-i-file-excel", className: "k-grid-excel", methodName: "saveAsExcel" }, pdf: { imageClass: "k-i-file-pdf", className: "k-grid-pdf", methodName: "saveAsPDF" } }; 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, undefined, 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 : options.childrenMap, expanded: options.expanded, maxDepth: (skip + take) || Infinity }); childrenMap = view.childrenMap(); query = new TreeQuery(prunedData); } if (skip !== undefined && take !== undefined) { 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) { 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) { options = base; base = TreeListModel; } var parentId = options.parentId || PARENTIDFIELD; options.parentIdField = parentId; var model = Model.define(base, options); if (parentId) { 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; } } return DataSource.fn.read.call(that, data); }, remove: function(root) { this._removeChildData(root); this._removeFromDataMaps(root); 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: proxy(this._filterCallback, 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 = proxy(this._filterCallback, 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)); } } result.data = data; } return result; }, _processPageableQuery: function(data, options) { var that = this; var dataMaps = that._getDataMaps(); var result; var filteredChildrenMap; if (that._getData() !== data || !dataMaps.children || !dataMaps.ids) { dataMaps = that._initDataMaps(that._getData()); } options.childrenMap = dataMaps.children || {}; options.idsMap = dataMaps.ids || {}; result = that._processTreeQuery(data, options); that._replaceWithObservedData(result.data, data); that._processDataItemsState(result.data, result.childrenMap); that._replaceItemsInDataMaps(result.data); result.dataToAggregate = that._dataToAggregate(result.data, options); if (options.filter) { filteredChildrenMap = result.filteredChildrenMap; that._replaceInMapWithObservedData(filteredChildrenMap, data); that._setFilteredChildrenMap(filteredChildrenMap); options.filteredChildrenMap = filteredChildrenMap; } return result; }, _dataToAggregate: function(data) { var that = this; var firstDataItem = data[0] || {}; var firstItemParents = that._parentNodes(firstDataItem); var dataToAggregate = firstItemParents.concat(data); return dataToAggregate; }, _replaceItemsInDataMaps: function(observableArray) { var that = this; var view = isArray(observableArray) ? observableArray : [observableArray]; var itemType = that._defaultDataItemType(); var defaultParentId = that._defaultParentId(); var idField = that._modelIdField(); var parentIdField = that._modelParentIdField(); var dataMaps = that._getDataMaps(); var item; var parents; var directParent; for (var viewIndex = 0; viewIndex < view.length; viewIndex++) { item = view[viewIndex]; if (!(item instanceof itemType)) { continue; } that._insertInIdsMap(item); parents = that._parentNodes(item); directParent = parents && parents.length ? parents[parents.length - 1] : undefined; if (item[parentIdField] === defaultParentId) { that._replaceInMap(dataMaps.children, defaultParentId, item, itemType); } else if (directParent) { that._replaceInMap(dataMaps.children, directParent[idField], item, itemType); } } }, _replaceInMap: function(map, id, replacement, itemType) { var idField = this._modelIdField(); map[id] = map[id] || []; itemType = itemType || this._defaultDataItemType(); var itemInArray = map[id].filter(function(element) { return replacement[idField] === element[idField]; })[0]; var itemIndex = itemInArray ? map[id].indexOf(itemInArray) : -1; if (itemIndex !== -1 && !(itemInArray instanceof itemType)) { map[id][itemIndex] = replacement; } }, _replaceWithObservedData: function(dataToReplace, replacementArray) { var that = this; var idsMap = that._getDataMaps().ids || {}; var idField = that._modelIdField(); var itemType = that._defaultDataItemType(); var itemToReplace; var itemToReplaceId; var dataItem; var dataItemIndex; var observableItem; for (var i = 0; i < dataToReplace.length; i++) { itemToReplace = dataToReplace[i]; itemToReplaceId = itemToReplace[idField]; if (!(itemToReplace instanceof itemType)) { if (!(idsMap[itemToReplaceId] instanceof itemType)) { dataItem = that._getById(itemToReplaceId); dataItemIndex = replacementArray.indexOf(dataItem); if (dataItem && dataItemIndex !== -1) { observableItem = replacementArray.at(dataItemIndex); dataToReplace[i] = observableItem; } } else { dataToReplace[i] = idsMap[itemToReplaceId]; } } } }, _replaceInMapWithObservedData: function(map, replacementArray) { var that = this; for (var key in map) { that._replaceWithObservedData(map[key], replacementArray); } }, _insertInDataMaps: function(item) { var that = this; if (that._isPageable()) { that._insertInIdsMap(item); that._insertInChildrenMap(item); } }, _insertInIdsMap: function(item) { var that = this; var idsMap = that._getIdsMap(); var idField = that._modelIdField(); if (!isUndefined(item[idField])) { idsMap[item[idField]] = item; } }, _insertInChildrenMap: function(item, index) { var that = this; var childrenMap = that._getChildrenMap() || {}; var idField = that._modelIdField(); var parentIdField = that._modelParentIdField(); var itemId = item[idField]; var parentId = item[parentIdField]; index = index || 0; childrenMap[itemId] = childrenMap[itemId] || []; childrenMap[parentId] = childrenMap[parentId] || []; childrenMap[parentId].splice(index, 0, item); }, _removeFromDataMaps: function(items) { var that = this; items = isArray(items) ? items : [items]; if (that._isPageable()) { for (var i = 0; i < items.length; i++) { that._removeFromIdsMap(items[i]); that._removeFromChildrenMap(items[i]); } } }, _removeFromIdsMap: function(item) { var that = this; var idsMap = that._getIdsMap(); var idField = that._modelIdField(); if (!isUndefined(item[idField])) { idsMap[item[idField]] = undefined; } }, _removeFromChildrenMap: function(item) { var that = this; var childrenMap = that._getChildrenMap() || {}; var parentIdField = that._modelParentIdField(); var parentId = item[parentIdField]; childrenMap[parentId] = childrenMap[parentId] || []; var itemIndex = that._indexInChildrenMap(item); if (itemIndex !== -1) { childrenMap[parentId].splice(itemIndex, 1); } }, _indexInChildrenMap: function(item) { var that = this; return that._itemIndexInMap(item, that._getChildrenMap()); }, _itemIndexInMap: function(item, dataMap) { var that = this; var map = dataMap || {}; var parentIdField = that._modelParentIdField(); var parentId = item[parentIdField]; map[parentId] = map[parentId] || []; var itemInArray = map[parentId].filter(function(element) { return item.uid === element.uid; })[0]; var itemIndex = itemInArray ? map[parentId].indexOf(itemInArray) : -1; return itemIndex; }, _getById: function(id) { var that = this; var idField = that._modelIdField(); var data = that._getData(); for (var i = 0; i < data.length; i++) { if (data[i][idField] === id) { return data[i]; } } }, _isLastItemInView: function(dataItem) { var view = this.view(); return view.length && view[view.length - 1] === dataItem; }, _defaultPageableQueryOptions: function() { var that = this; var dataMaps = that._getDataMaps(); var options = { skip: that.skip(), take: that.take(), page: that.page(), pageSize: that.pageSize(), sort: that.sort(), filter: that.filter(), group: that.group(), aggregate: that.aggregate(), filterCallback: proxy(that._filterCallback, that), childrenMap: dataMaps.children, idsMap: dataMaps.ids }; return options; }, _isPageable: function() { var pageSize = this.pageSize(); return (!isUndefined(pageSize) && pageSize > 0 && !this.options.serverPaging); }, _updateTotalForAction: function(action, items) { var that = this; DataSource.fn._updateTotalForAction.call(that, action, items); if (that._isPageable()) { that._updateCollapsedTotalForAction(action, items); } }, _updateCollapsedTotalForAction: function(action, items) { var that = this; var total = parseInt(that._collapsedTotal, 10); if (!isNumber(that._collapsedTotal)) { that._calculateCollapsedTotal(); return; } if (action === "add") { total += items.length; } else if (action === "remove") { total -= items.length; } else if (action !== "itemchange" && action !== "sync" && !that.options.serverPaging) { total = that._calculateCollapsedTotal(); } else if (action === "sync") { total = that._calculateCollapsedTotal(); } that._collapsedTotal = total; }, _setFilterTotal: function(filterTotal, setDefaultValue) { var that = this; DataSource.fn._setFilterTotal.call(that, filterTotal, setDefaultValue); that._setFilterCollapsedTotal(filterTotal); }, _setFilterCollapsedTotal: function(filterTotal) { var that = this; if (!that.options.serverFiltering) { if (filterTotal !== undefined) { that._collapsedTotal = filterTotal; } else { if (that._getFilteredChildrenMap()) { that._calculateCollapsedTotal(); } that._setFilteredChildrenMap(undefined); } } }, collapsedTotal: function() { var that = this; if (!isUndefined(that._collapsedTotal)) { return that._collapsedTotal; } return that._calculateCollapsedTotal(); }, _calculateCollapsedTotal: function() { var that = this; var data = that._dataWithoutCollapsedSubtrees(); if (data.length) { that._collapsedTotal = data.length; } return that._collapsedTotal; }, _dataWithoutCollapsedSubtrees: function() { return this._removeCollapsedSubtrees(this._getData()); }, _removeCollapsedSubtrees: function(data) { var that = this; var view = that._createTreeView(data); var result = view.removeCollapsedSubtreesFromRootNodes({ expanded: that._modelOptions().expanded, childrenMap: that._getChildrenMap() }); return result; }, _processTreeQuery: function(data, options) { var result = TreeQuery.process(data, extend(options, this._defaultTreeModelOptions(), { processFromRootNodes: true })); return result; }, _processDataItemsState: function(data, childrenMap) { var dataLength = data.length; var i; for (i = 0; i < dataLength; i++) { this._processDataItemState(data[i], childrenMap); } }, _processDataItemState: function(dataItem, childrenMap) { var defaultParentId = this._defaultParentId(); if (dataItem.id === defaultParentId) { return; } var children = childrenMap[dataItem.id] || []; var hasLoadedChildren = !!(children && children.length); if (!dataItem.loaded) { return; } if (!dataItem.loaded()) { dataItem.loaded(hasLoadedChildren || !dataItem.hasChildren); } if (dataItem.loaded() || dataItem.hasChildren !== true) { dataItem.hasChildren = hasLoadedChildren; } }, _queueRequest: function(options, callback) { // allow simultaneous requests (loading multiple items at the same time) callback.call(this); }, _modelLoaded: function(id) { var model = this.get(id); model.loaded(true); model.hasChildren = this.childNodes(model).length > 0; }, _modelError: function(id, e) { this.get(id)._error = e; }, success: function(data, requestParams) { if (!requestParams || typeof requestParams.id == "undefined") {