@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
9,483 lines • 332 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.dom.js');
require('./kendo.data.js');
require('./kendo.columnsorter.js');
require('./kendo.editable.js');
require('./kendo.window.js');
require('./kendo.filtermenu.js');
require('./kendo.columnmenu.js');
require('./kendo.selectable.js');
require('./kendo.resizable.js');
require('./kendo.treeview.draganddrop.js');
require('./kendo.pager.js');
require('./kendo.filtercell.js');
require('./kendo.textbox.js');
require('./kendo.form.js');
require('./kendo.toolbar.js');
require('./kendo.icons.js');
require('./kendo.reorderable.js');
require('./mixins-RbnksPfz.js');
require('./kendo.ooxml.js');
require('./kendo.core.js');
require('./html-sdnHcjkh.js');
require('./mixins-D385O08Q.js');
require('./kendo.progressbar.js');
require('./kendo.menu.js');
require('./kendo.licensing.js');
require('@progress/kendo-licensing');
require('./kendo.data.odata.js');
require('./kendo.data.xml.js');
require('./kendo.html.icon.js');
require('./kendo.html.base.js');
require('@progress/kendo-svg-icons');
require('./kendo.checkbox.js');
require('./kendo.toggleinputbase.js');
require('./kendo.html.input.js');
require('./kendo.dropdownlist.js');
require('./kendo.list.js');
require('./kendo.popup.js');
require('./kendo.label.js');
require('./kendo.floatinglabel.js');
require('./kendo.actionsheet.js');
require('./kendo.html.button.js');
require('./kendo.actionsheet.view.js');
require('./kendo.button.js');
require('./kendo.badge.js');
require('./dropdowns-loader-Bc4IELFi.js');
require('./kendo.mobile.scroller.js');
require('./kendo.fx.js');
require('./kendo.draganddrop.js');
require('./kendo.userevents.js');
require('./kendo.virtuallist.js');
require('./valueMapper-q_OtZ-Tj.js');
require('./kendo.datepicker.js');
require('./kendo.calendar.js');
require('./kendo.dateinput.js');
require('@progress/kendo-dateinputs-common');
require('./kendo.numerictextbox.js');
require('./prefix-suffix-containers-BmDm564f.js');
require('./kendo.validator.js');
require('./kendo.binder.js');
require('./kendo.otpinput.js');
require('./kendo.upload.js');
require('./kendo.buttongroup.js');
require('./kendo.togglebutton.js');
require('./kendo.pane.js');
require('./kendo.view.js');
require('./kendo.tabstrip.js');
require('./kendo.sortable.js');
require('./kendo.expansionpanel.js');
require('./kendo.autocomplete.js');
require('./kendo.combobox.js');
require('./kendo.splitbutton.js');
require('./kendo.button.menu.js');
require('./kendo.dropdownbutton.js');
require('@progress/kendo-ooxml');
require('@progress/kendo-drawing');
require('./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-table-alt-row",
editCell: "k-edit-cell",
editRow: "k-grid-edit-row",
dirtyCell: "k-dirty-cell",
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));
}
}
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 || that.filter()) {
filteredChildrenMap = result.filteredChildrenMap;
that._replaceInMapWithObservedData(filteredChildrenMap, data);
that._setFilteredChildrenMap(filteredChildrenMap);
options.filteredChildrenMap = filteredChildrenMap;
that._calculateCollapsedTotal(result.data);
} else {
that._collapsedTotal = undefined$1;
}
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$1;
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$1;
}
},
_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: that._filterCallback.bind(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);
},
collapsedTotal: function() {
var that = this;
if (!isUndefined(that._collapsedTotal)) {
return that._collapsedTotal;
}
return that._calculateCollapsedTotal();
},
_calculateCollapsedTotal: function(filteredData) {
var that = this;
var data = that._dataWithoutCollapsedSubtrees(filteredData);//
if (data.length) {
that._collapsedTotal = data.length;
}
return that._collapsedTotal;
},
_dataWithoutCollapsedSubtrees: function(filteredData) {
return this._removeCollapsedSubtrees(filteredData || this._getData());
},
_removeCollapsedSubtrees: function(data) {
var that = this;
var view = that._createTreeView(data);
var result = view.removeCollapsedSubtreesFromRootNodes({
expanded: that._modelOptions().expanded,
childrenMap: that.filter() ? that._getFilteredChildrenMap() : 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") {
this._data = this._observe([]);
}
DataSource.fn.success.call(this, data, requestParams);
this._total = this._data.length;
},
load: function(model) {
var method = "_query";
var remote = this.options.serverSorting || this.options.serverPaging || this.options.serverFiltering || this.options.serverGrouping || this.options.serverAggregates;
var defaultPromise = $.Deferred().resolve().promise();
if (model.loaded()) {
if (remote) {
return defaultPromise;
}
} else if (model.hasChildren) {
method = "read";
this._removeChildData(model);
}
return this[method]({ id: model.id })
.done(this._modelLoaded.bind(this, model.id))
.fail(this._modelError.bind(this, model.id));
},
contains: function(root, child) {
var that = this;
var idField = that._modelIdField();
var parentIdField = that._modelParentIdField();
var rootId = root[idField];
var pageable = that._isPageable();
while (child) {
if (child[parentIdField] === rootId) {
return true;
}
child = pageable ? that._parentNode(child) : that.parentNode(child);
}
return false;
},
_byParentId: function(id, defaultId) {
var result = [];
var view = this.view();
var current;
if (id === defaultId) {
return [];
}
for (var i = 0; i < view.length; i++) {
current = view.at(i);
if (current.parentId == id) {
result.push(current);
}
}
return result;
},
_defaultParentId: function() {
return this.reader.model.fn.defaults[this.reader.model.parentIdField];
},
_modelOptions: function() {
var modelOptions = ((this.options.schema || {}).model || {});
return modelOptions;
},
_modelIdField: function() {
var modelOptions = this._modelOptions();
return modelOptions.id || "id";
},
_modelParentIdField: function() {
var modelOptions = this._modelOptions();
return modelOptions.parentId || PARENTIDFIELD;
},
childNodes: function(model) {
return this._byParentId(model.id, this._defaultParentId());
},
allChildNodes: function(model, result) {
var directChildren = this.data().filter(function(item) {
return item.parentId === model.id;
});
for (var i = 0; i < directChildren.length; i++) {
result.push(directChildren[i]);
this.allChildNodes(directChildren[i], result);
}
},
rootNodes: function() {
return this._byParentId(this._defaultParentId());
},
_rootNode: function(child) {
return this._parentNodes(child)[0];
},
_pageableRootNodes: function(options) {
options = options || {};
var that = this;
var defaultParentId = that._defaultParentId();
var parentIdField = that._modelParentIdField();
var result = [];
var nodesWithoutParentInView = that._nodesWithoutParentInView(options);
var node;
var root;
for (var i = 0; i < nodesWithoutParentInView.length; i++) {
node = nodesWithoutParentInView[i];
if (node[parentIdField] === defaultParentId) {
result.push(node);
} else {
root = that._rootNode(node);
if (root && result.indexOf(root) === -1) {
result.push(root);
}
}
}
return result;
},
parentNode: function(model) {
return this.get(model.parentId);
},
_parentNode: function(child) {
var that = this;
var parentIdField = that._modelParentIdField();
var idsMap = that._initIdsMap(that._getData());
var parentId = child[parentIdField];
var parent = idsMap[parentId] || that._getById(parentId);
return parent;
},
_parentNodes: function(child) {
var that = this;
var parent = that._parentNode(child);
var parents = [];
while (parent) {
parents.unshift(parent);
parent = that._parentNode(parent);
}
return parents;
},
_parentNodesNotInView: function() {
var that = this;
var view = that.view();
var result = [];
var defaultParentId = that._defaultParentId();
var idField = that._modelIdField();
var parentIdField = that._modelParentIdField();
var parentInView;
var parents = [];
var directParent;
var dataItem;
var dataItemParentId;
for (var i = 0; i < view.length; i++) {
dataItem = view[i];
dataItem[idField];
dataItemParentId = dataItem[parentIdField];
parentInView = that._parentInView(dataItemParentId);
if (!parentInView && dataItemParentId !== defaultParentId) {
parents = that._parentNodes(dataItem);
directParent = parents && parents.length ? parents[parents.length - 1] : that._getById(dataItemParentId);
if (directParent && result.indexOf(directParent) === -1) {
result.push(directParent);
}
}
}
return result;
},
_nodesWithoutParentInView: function(options) {
options = options || {};
var that = this;
var view = that.view();
var childrenMap = options.childrenMap || that.childrenMap(that._getData());
var idField = that._modelIdField();
var parentIdField = that._modelParentIdField();
var dataItem;
var parentInView;
var result = [];
for (var i = 0; i < view.length; i++) {
dataItem = view[i];
childrenMap[dataItem[idField]];
parentInView = that._parentInView(dataItem[parentIdField]);
if (!parentInView) {
result.push(dataItem);
}
}
return result;
},
_parentInView: function(parentId) {
var view = this.view();
for (var i = 0; i < view.length; i++) {
if (view[i].id === parentId) {
return view[i];
}
}
},
level: function(model) {
var result = -1;
if (!(model instanceof TreeListModel)) {
model = this.get(model);
}
do {
model = this.parentNode(model);
result++;
} while (model);
return result;
},
_pageableModelLevel: function(model) {
var that = this;
if (!model || !that._isPageable()) {
return 0;
}
var parents = that._parentNodes(model);
return parents.length;
},
filter: function(value) {
var baseFilter = DataSource.fn.filter;
if (value === undefined$1) {
return baseFilter.call(this, value);
}
baseFilter.call(this, value);
},
_pageableQueryOptions: function(options) {
var dataMaps = this._getDataMaps();
options.childrenMap = dataMaps.children;
options.idsMap = dataMaps.ids;
return options;
},
_flatData: function(data, skip) {
skip = this._isPageable() ? true : skip;
return DataSource.fn._flatData.call(this, data, skip);
},
data: function(data) {
var that = this;
var result = DataSource.fn.data.call(that, data);
if (that._isPageable()) {
that._initDataMaps(that._getData());
that._calculateCollapsedTotal();
}
return result;
},
cancelChanges: function(model) {
var that = this;
DataSource.fn.cancelChanges.call(that, model);
that._restorePageSizeAfterAddChild();
},
_modelCanceled: function(model) {
var that = this;
if (that._isPageable()) {
that._removeFromDataMaps(model);
}
},
_changesCanceled: function() {
var that = this;
if (that._isPageable()) {
that._initDataMaps(that._getData());
}
},
_setAddChildPageSize: function() {
var that = this;
var queryOptions = {};
if (that._isPageable()) {
// increase the page size to make the new item visible in view
that._addChildPageSize = that.pageSize() + 1;
queryOptions = that._defaultPageableQueryOptions();
queryOptions.take = that._addChildPageSize;
queryOptions.pageSize = that._addChildPageSize;
that._query(queryOptions);
}
},
_restorePageSizeAfterAddChild: function() {
var that = this;
var queryOptions = {};
if (that._isPageable()) {
if (!isUndefined(that._addChildPageSize)) {
queryOptions = that._defaultPageableQueryOptions();
queryOptions.take = that._addChildPageSize - 1;
queryOptions.pageSize = that._addChildPageSize - 1;
that._query(queryOptions);
}
}
that._addChildPageSize = undefined$1;
},
sync: function() {
var that = this;
return DataSource.fn.sync.call(that)
.then(function() {
that._restorePageSizeAfterAddChild();
});
},
_syncEnd: function() {
var that = this;
if (that._isPageable()) {
that._initDataMaps(that._getData());
}
}
});
TreeListDataSource.create = function(options) {
if (Array.isArray(options)) {
options = { data: options };
} else if (options instanceof ObservableArray) {
options = { data: options.toJSON() };
}
return options instanceof TreeListDataSource ? options : new TreeListDataSource(options);
};
function isCellVisible() {
return this.style.display !== "none";
}
function sortCells(cells) {
var indexAttr = kendo.attr("index");
return [].sort.call(cells, function(a, b) {
a = $(a);
b = $(b);
var indexA = a.attr(indexAttr);
var indexB = b.attr(indexAttr);
if (indexA === undefined$1) {
indexA = $(a).index();
}
if (indexB === undefined$1) {
indexB = $(b).index();
}
indexA = parseInt(indexA, 10);
indexB = parseInt(indexB, 10);
return indexA > indexB ? 1 : (indexA < indexB ? -1 : 0);
});
}
function leafDataCells(container) {
var rows = container.find(">tr:not(.k-filter-row)");
var filter = function() {
var el = $(this);
return !el.hasClass("k-group-cell") && !el.hasClass("k-hierarchy-cell");
};
var cells = $();
if (rows.length > 1) {
cells = rows.find("th[data-index]")
.filter(filter);
}
cells = cells.add(rows.last().find("th").filter(filter));
return sortCells(cells);
}
function createPlaceholders(options) {
var spans = [];
var className = options.className;
const blankIcon = className === classNames.iconPlaceHolder ? { "ref-blank-icon": '' } : {};
for (var i = 0, level = options.level; i < level; i++) {
spans.push(kendoDomElement("span", { className: className, 'aria-hidden': true, ...blankIcon }));
}
return spans;
}
function columnsWidth(cols) {
var colWidth, width = 0;
for (var idx = 0, length = cols.length; idx < length; idx++) {
colWidth = cols[idx].style.width;
if (colWidth && colWidth.indexOf("%") == -1) {
width += parseInt(colWidth, 10);
}
}
return width;
}
function syncTableHeight(table1, table2) {
table1 = table1[0];
table2 = table2[0];
if (table1.rows.length && table2.rows.length && table1.rows.length !== table2.rows.length) {
var lockedHeigth = table1.offsetHeight;
var tableHeigth = table2.offsetHeight;
var row;
var diff;
if (lockedHeigth > tableHeigth) {
row = table2.rows[table2.rows.length - 1];
if (filterRowRegExp.test(row.className)) {
row = table2.rows[table2.rows.length - 2];
}
diff = lockedHeigth - tableHeigth;
} else {
row = table1.rows[table1.rows.length - 1];
if (filterRowRegExp.test(row.className)) {
row = table1.rows[table1.rows.length - 2];
}
diff = tableHeigth - lockedHeigth;
}
row.style.height = row.offsetHeight + diff + "px";
}
}
var TreeListPager = ui.Pager.extend({
options: {
name: "TreeListPager"
},
totalPages: function() {
var that = this;
var dataSource = that.dataSource;
if (dataSource && dataSource._filter) {
return ui.Pager.fn.totalPages.call(that);
}
return Math.ceil((that._collapsedTotal() || 0) / (that.pageSize() || 1));
},
_createDataSource: function(options) {
this.dataSource = kendo.data.TreeListDataSource.create(options.dataSource);
},
_collapsedTotal: function() {
var dataSource = this.dataSource;
return dataSource ? (dataSource.collapsedTotal() || 0) : 0;
}
});
var Editor = kendo.Observable.extend({
init: function(element, options) {
kendo.Observable.fn.init.call(this);
options = this.options = extend(true, {}, this.options, options);
this.element = element;
this.bind(this.events, options);
this.model = this.options.model;
this.fields = this._fields(this.options.columns);
this._initContainer();
this.createEditable();
},
options: {
renderForm: false
},
events: [],
_initContainer: function() {
this.wrapper = this.element;
},
createEditable: function() {
var options = this.options;
if (options.renderForm) {
this.form = new ui.Form(this.wrapper.find(".k-treelist-form"), {
items: this.fields,
buttonsTemplate: () => '',
formData: this.model,
change: options.change
});
this.editable = this.form.editable;
} else {
this.editable = new ui.Editable(this.wrapper, {
fields: this.fields,
target: options.target,
clearContainer: options.clearContainer,
model: this.model,
change: options.change
});
}
},
_isEditable: function(column) {
return isColumnEditable(column, this.model);
},
_fields: function(columns) {
var fields = [];
var idx, length, column;
for (idx = 0, length = columns.length; idx < length; idx++) {
column = columns[idx];
if (this._isEditable(column)) {
fields.push({
field: column.field,
format: column.format,
editor: column.editor,
editorOptions: extend(true, { format: column.format }, column.editorOptions),
label: column.title || column.field || ""
});
}
}
return fields;
},
end: function() {
return this.editable.end();
},
close: function() {
this.destroy();
},
destroy: function() {
this.editable.destroy();
this.editable.element
.find("[" + kendo.attr("container-for") + "]")
.empty()
.end()
.removeAttr(kendo.attr("role"));
this.model = this.wrapper = this.element = this.columns = this.editable = null;
}
});
var PopupEditor = Editor.extend({
init: function(element, options) {
Editor.fn.init.call(this, element, options);
this._attachHandlers();
kendo.cycleForm(this.wrapper);
this.open();
},
events: [
CANCEL,
SAVE
],
options: {
window: {
modal: true,
resizable: false,
draggable: true,
title: "Edit",
visible: false
}
},
_initContainer: function() {
var options = this.options;
var formContent = [];
this.wrapper = $('<div class="k-popup-edit-form"/>')
.attr(kendo.attr("uid"), this.model.uid)
.append('<div class="k-edit-form-container"/>');
if (options.template) {
this._appendTemplate(formContent);
this.fields = [];
} else {
this.options.renderForm = true;
formContent.push(kendoHtmlElement('<div class="k-treelist-form"></div>'));
}
new kendoDom.Tree(this.wrapper.children()[0]).render(formContent);
this.wrapper.appendTo(options.appendTo);
this.window = new ui.Window(this.wrapper, options.window);
},
_appendTemplate: function(form) {
var template = this.options.template;
if (typeof template === STRING) {
template = kendo.unescape(template);
}
template = kendo.template(template)(this.model);
form.push(kendoHtmlElement(template));
},
_attachHandlers: function() {
var closeHandler = this._cancelProxy = this._cancel.bind(this);
this.window.wrapper.on(CLICK + NS, "button[data-command='canceledit']", this._cancelProxy);
this._saveProxy = this._save.bind(this);
this.window.wrapper.on(CLICK + NS, "button[data-command='update']", this._saveProxy);
this.window.bind("close", function(e) {
if (e.userTriggered) {
closeHandler(e);
}
});
},
_detachHandlers: function() {
this._cancelProxy = null;
this._saveProxy = null;
this.window.wrapper.off(NS);
},
_cancel: function(e) {
this.trigger(CANCEL, e);
},
_save: function() {
this.trigger(SAVE);
},
open: function() {
this.window.center().open();
},
close: function() {
this.window.bind("deactivate", this.destroy.bind(this)).close();
},
destroy: function() {
if (this.form) {
this.form.destroy();
}
this._detachHandlers();
this.window.destroy();
this.window = null;
Editor.fn.destroy.call(this);
}
});
var IncellEditor = Editor.extend({
destroy: function() {
var that = this;
that.editable.destroy();
that.editable.element
.off()
.empty()
.removeAttr(kendo.attr("role"));
that.model = that.wrapper = that.element = that.columns = that.editable = null;
}
});
var TreeList = DataBoundWidget.extend({
init: function(element, options, events) {
DataBoundWidget.fn.init.call(this, element, options);
if (events) {
this._events = events;
}
isRtl = kendo.support.isRtl(element);
classNames.iconExpand = isRtl ? CARET_ALT_LEFT : CARET_ALT_RIGHT;
this._dataSource(this.options.dataSource);
this._columns();
this._layout();
this._aria();
this._ariaId();
this._navigatable();
this._selectable();
this._sortable();
this._resizable();
this._filterable();
this._filterRow();
this._attachEvents();
this._toolbar();
this._scrollable();
this._reorderable();
this._columnMenu();
this._minScreenSupport();
this._draggable();
this._pageable();
if (this.options.autoBind) {
this.dataSource.fetch();
}
if (this._hasLockedColumns) {
var widget = this;
this.wrapper.addClass("k-grid-lockedcolumns");
this._resizeHandler = function() { widget.resize(); };
$(window).on("resize" + NS, this._resizeHandler);
}
if (this.options.contextMenu) {
this._initContextMenu();
}
kendo.notify(this);
},
_draggable: function() {
var that = this;
var editable = this.options.editable;
var dataSource = that.dataSource;
var idField = dataSource._modelIdField();
var parentIdField = dataSource._modelParentIdField();
var pageable = that._isPageable();
var reorderable, clickMoveClick;
if (!editable || !editable.move) {
return;
}
reorderable = editable.move.reorderable;
if (editable.move.clickMoveClick !== false && this._hasDragHandleColumn) {
clickMoveClick = true;
}
this._dragging = new kendo.ui.HierarchicalDragAndDrop(this.wrapper, {
autoScroll: true,
holdToDrag: touchDevice,
filter: that._hasDragHandleColumn ? "[ref-treelist-drag-cell]" : "tbody>tr",
itemSelector: "tr",
allowedContainers: this.table,
clickMoveClick: clickMoveClick,
hintText: function(row) {
var text = function() { return $(this).text().replace(/<(\/?)script([^>]*)>/ig, ""); };
var separator = "<span class='k-drag-separator'></span>";
row = row.closest("tr");
return row.children("td").map(text).toArray().join(separator);
},
contains: (function(source, destination) {
var dest = this.dataItem(destination);
var src = this.dataItem(source);
return src == dest || this.dataSource.contains(src, dest);
}).bind(this),
itemFromTarget: function(target) {
var tr = target.closest("tr");
var prevRow = tr.prev();
var nextRow = tr.next();
var first;
var last;
if (prevRow) {
first = !that.sameLevel(prevRow, tr);
}
if (nextRow) {
last = !that.sameLevel(nextRow, tr);
}
return {
item: tr,
content: tr,
first: first,
last: last
};
},
dragstart: (function(source) {
this.wrapper.addClass("k-treelist-dragging");
if (this.wrapper.find('.k-grid-content').length) {
this.wrapper.find('.k-grid-content table, .k-grid-content-locked table').css("position", "relative");
}
var model = this.dataItem(source);
return this.trigger(DRAGSTART, { source: model });
}).bind(this),
drag: (function(e) {
e.source = this.dataItem(e.source);
this.trigger(DRAG, e);
}).bind(this),
drop: (function(e) {
e.source = this.dataItem(e.source);
e.destination = this.dataItem(e.destination);
this.wrapper.removeClass("k-treelist-dragging");
if (this.wrapper.find('.k-grid-content').length) {
this.wrapper.find('.k-grid-content table, .k-grid-content-locked table').css("position", "static");
}
return this.trigger(DROP, e);
}).bind(this),
dragend: (function(e) {
var dest = this.dataItem(e.destination);
var src = this.dataItem(e.source);
var originalSrcParentId = src[parentIdField];
var originalSrcIndex = dataSource._indexInChildrenMap(src);
var position = e.position;
if (position == "over") {
if (pageable) {
dataSource._removeFromChildrenMap(src);
src[parentIdField] = dest ? dest[idField] : null;
dataSource._initChildrenMapForParent(dest);
// src.set() below will not work as the parent id is already set
src[parentIdField] = originalSrcParentId;
}
var isPrevented = src.set("parentId", dest ? dest.id : null);
if (pageable && isPrevented) {
dataSource._removeFromChildrenMap(src);
src[parentIdField] = originalSrcParentId;
dataSource._removeFromChildrenMap(src);
dataSource._insertInChildrenMap(src, originalSrcIndex);
}
} else {
if (position == "before") {
that.insertBefore(src, dest);
} else if (position == "after") {
that.insertAfter(src, dest);
}
}
e.source = src;
e.destination = dest;
this.trigger(DRAGEND, e);
}).bind(this),
reorderable: reorderable,
dropHintContainer: function(item) {
return item.children("td:visible").eq(0);
},
dropPositionFrom: function(dropHint) {
const dropHintParent = dropHint.parent(),
contents = dropHint.parent().contents(),
dropHintElement = dropHint[0];
let isAfter = false;
if (dropHintParent.find(BLANK_ICON_SELECTOR).length) {
return dropHint.prevAll(BLANK_ICON_SELECTOR).length > 0 ? "after" : "before";
} else if (dropHintParent.is('[ref-treelist-drag-cell]')) {
isAfter = contents[0] !== dropHintElement;
} else {
const length = contents.length;
for (let i = 0; i < length; i++) {
if (contents[i] === dropHintElement) {
break;
}
if (contents[i].nodeType === 3) {
isAfter = true;
}
}
}
return isAfter ? "after" : "before";
}
});
},
sameLevel: function() {
return arguments[0].find(BLANK_ICON_SELECTOR).length === arguments[1].find(BLANK_ICON_SELECTOR).length;
},
insertAfter: function(nodeData, referenceNode) {
this.insertAction(nodeData, referenceNode, 1);
},
insertBefore: function(nodeData, referenceNode) {
this.insertAction(nodeData, referenceNode, 0);
},
insertAction: function(nodeData, referenceNode, indexOffset) {
var that = this;
var dataSource = that.dataSource;
var parentIdField = dataSource._modelParentIdField();
var referenceNodeIndex;
var nodeDataIndex = dataSource.indexOf(nodeData);
var pageable = that._isPageable();
var originalDestIndex = dataSource._indexInChildrenMap(referenceNode);
var destIndex;
var childrenMap = dataSource._getChildrenMap() || {};
var parentId = nodeData[parentIdField];
that._unbindDataSource();
that._unbindDataChange();
if (pageable) {
dataSource._removeFromChildrenMap(nodeData);
}
if (nodeData[parentIdField] != referenceNode[parentIdField]) {
nodeData.set("parentId", referenceNode && referenceNode.parentId ? referenceNode.parentId : null);
}
dataSource._data.splice(nodeDataIndex, 1);
referenceNodeIndex = dataSource.indexOf(referenceNode);
destIndex = referenceNodeIndex + indexOffset;
if (pageable) {
originalDestIndex += indexOffset;
if (childrenMap[parentId].length <= originalDestIndex) {
originalDestIndex = childrenMap[parentId].length;
}
dataSource._insertInChildrenMap(nodeData, originalDestIndex);
}
dataSource._data.splice(destIndex, 0, nodeData);
dataSource._destroyed.pop();
that._bindDataChange();
that._bindDataSource();
that.refresh();
},
_bindDataChange: function() {
var dataSource = this.dataSource;
if (dataSource._data && dataSource._changeHandler) {
dataSource._data.bind(CHANGE, dataSource._changeHandler);
dataSource._data.trigger(CHANGE);
}
},
_unbindDataChange: function() {
var dataSource = this.dataSource;
if (dataSource._data && dataSource._changeHandler) {
dataSource._data.unbind(CHANGE, dataSource._changeHandler);
}
},
_bindDataSource: function() {
var that = this;
var dataSource = that.dataSource;
if (dataSource) {
dataSource.bind(CHANGE, that._refreshHandler);
}
},
_unbindDataSource: function() {
var that = this;
var dataSource = that.dataSource;
if (dataSource) {
dataSource.unbind(CHANGE, that._refreshHandler);
}
},
itemFor: function(model) {
if (typeof model == "number") {
model = this.dataSource.get(model);
}
return this.tbody.find("[" + kendo.attr("uid") + "=" + model.uid + "]");
},
_itemFor: function(model) {
var that = this;
var table = that.lockedContent ? that.lockedTable : that.table;
if (typeof model == "number") {
model = this.dataSource.get(model);
}
return table.find("[" + kendo.attr("uid") + "=" + model.uid + "]");
},
_scrollable: function() {
if (this.options.scrollable) {
var scrollables = this.thead.closest(".k-grid-header-wrap");
var lockedContent = $(this.lockedContent)
.on("DOMMouseScroll" + NS + " mousewheel" + NS, this._wheelScroll.bind(this));
this.content.on("scroll" + NS, function() {
kendo.scrollLeft(scrollables, this.scrollLeft);
lockedContent.scrollTop(this.scrollTop);
});
this.element.find(".k-grid-content, .k-grid-content-locked").wrapAll("<div class='k-grid-container' />");
var touchScroller = kendo.touchScroller(this.content);
if (touchScroller && touchScroller.movable) {
this._touchScroller = touchScroller;
touchScroller.movable.bind("change", function(e) {
kendo.scrollLeft(scrollables, -e.sender.x);
if (lockedContent) {
lockedContent.scrollTop(-e.sender.y);
}
});
}
}
},
_wheelScroll: function(e) {
if (e.ctrlKey) {
return;
}
var delta = kendo.wheelDeltaY(e);
var lockedDiv = $(e.currentTarget);
if (delta) {
if (lockedDiv[0].scrollHeight > lockedDiv[0].clientHeight &&
(lockedDiv[0].scrollTop < lockedDiv[0].scrollHeight - lockedDiv[0].clientHeight && delta < 0 ||
lockedDiv[0].scrollTop > 0 && delta > 0)) {
e.preventDefault();
}
//In Firefox DOMMouseScroll event cannot be canceled
lockedDiv.one("wheel" + NS, false);
this.content.scrollTop(this.content.scrollTop() + (-delta));
}
},
_progress: function() {
var messages = this.options.messages;
if (!this.tbody.find("tr").length) {
this._showStatus(
kendo.template(
({ className, messages }) => `<span class='${className}'></span> ${encode(messages.loading)}`
)({
className: classNames.icon + " " + classNames.loading,
messages: messages
})
);
}
},
_error: function(e) {
if (!this.dataSource.rootNodes().length) {
this._render({ error: e });
}
},
refresh: function(e) {
var that = this;
e = e || {};
if (e.action == "itemchange" && this.editor) {
return;
}
if (this.trigger(DATABINDING)) {
return;
}
var current = $(this.current());
var isCurrentInHeader = false;
var currentIndex, currentRowIndex;
this._cancelEditor();
this._render();
this._adjustHeight();
if (this.options.navigatable) {
if (this._isActiveInTable() || this.editor) {
isCurrentInHeader = current.is("th");
currentIndex = isCurrentInHeader ? current.parent().children(":not(.k-group-cell)").index(current[0]) : Math.max(this.cellIndex(current), 0);
currentRowIndex = !isCurrentInHeader && current.parent().index();
}
this._restoreCurrent(currentIndex, isCurrentInHeader, currentRowIndex);
}
if (that._checkBoxSelection) {
that._deselectCheckRows(that.items(), true);
}
that._aria();
this.trigger(DATABOUND);
},
items: function() {
if (this._hasLockedColumns) {
return this._items(this.tbody).add(this._items(this.lockedTable));
} else {
return this._items(this.tbody);
}
},
_items: function(container) {
return container.find("tr[data-uid]").filter(function() {
return !$(this).hasClass(classNames.footerTemplate);
});
},
_footerItems: function() {
var container = this.tbody;
if (this._hasLockedColumns) {
container = container.add(this.lockedTable);
}
return container.find("tr").filter(function() {
return $(this).hasClass(classNames.footerTemplate);
});
},
dataItems: function() {
var dataItems = kendo.ui.DataBoundWidget.fn.dataItems.call(this);
if (this._hasLockedColumns) {
var n = dataItems.length, tmp = new Array(2 * n);
for (var i = n; --i >= 0;) {
tmp[i] = tmp[i + n] = dataItems[i];
}
dataItems = tmp;
}
return dataItems;
},
_showNoRecordsTemplate: function() {
var wrapper = '<div class="{0}">{1}</div>';
var defaultTemplate = '<div class="k-grid-norecords-template"{1}>{0}</div>';
var scrollableNoGridHeightStyles = (this.options.scrollable && !this.wrapper[0].style.height) ? ` ${kendo.attr("style-margin")}="0 auto" ${kendo.attr("style-position")}="static"` : '';
var template;
var noRecordsElement;
this._contentTree.render([]);
if (this._hasLockedColumns) {
this._lockedContentTree.render([]);
}
template = kendo.format(defaultTemplate, this.options.messages.noRows, scrollableNoGridHeightStyles);
noRecordsElement = $(kendo.template(() => kendo.format(wrapper, NORECORDSCLASS, template))({}));
kendo.applyStylesFromKendoAttributes(noRecordsElement, ["margin", "position"]);
noRecordsElement.insertAfter(this.table);
},
_showStatus: function(message) {
var status = this.element.find(".k-status");
var content = $(this.content).add(this.lockedContent);
if (!status.length) {
status = $("<div class='k-status' role='alert' aria-live='polite' />").appendTo(this.element);
}
this._contentTree.render([]);
if (this._hasLockedColumns) {
this._lockedContentTree.render([]);
}
content.hide();
status.html(message);
},
_hideStatus: function() {
this.element.find(".k-status").remove();
this._hideNoRecordsTempalte();
$(this.content).add(this.lockedContent).show();
},
_hideNoRecordsTempalte: function() {
this.element.find("." + NORECORDSCLASS).remove();
},
_adjustHeight: function() {
var that = this;
var element = this.element;
var contentWrap = element.find(DOT + classNames.gridContentWrap);
var header = element.find(DOT + classNames.gridHeader);
var toolbar = element.find(DOT + classNames.gridToolbar);
var status = element.find(DOT + classNames.status);
var pagerHeight = that._isPageable() && that.pager && that.pager.element.is(":visible") ? outerHeight(that.pager.element) : 0;
var height;
var scrollbar = kendo.support.scrollbar();
element.css(HEIGHT, this.options.height);
// identical code found in grid & scheduler :(
var isHeightSet = function(el) {
var initialHeight, newHeight;
if (el[0].style.height) {
return true;
} else {
initialHeight = el.height();
}
el.height("auto");
newHeight = el.height();
el.height("");
return (initialHeight != newHeight);
};
if (isHeightSet(element)) {
height = that.options.hasHeader ?
element.height() - outerHeight(header) - outerHeight(toolbar) - outerHeight(status) - pagerHeight :
element.height() - outerHeight(toolbar) - outerHeight(status) - pagerHeight;
contentWrap.height(height);
if (this._hasLockedColumns) {
scrollbar = this.table[0].offsetWidth > this.table.parent()[0].clientWidth ? scrollbar : 0;
this.lockedContent.height(height - scrollbar);
}
}
},
_resize: function(size, force) {
this._applyLockedContainersWidth();
this._adjustHeight();
if (this.pager && this.pager.element) {
this.pager.resize(force);
}
},
_minScreenSupport: function() {
var any = this.hideMinScreenCols();
if (any) {
this.minScreenResizeHandler = this.hideMinScreenCols.bind(this);
$(window).on("resize", this.minScreenResizeHandler);
}
},
_iterateMinScreenCols: function(cols, screenWidth) {
var any = false;
for (var i = 0; i < cols.length; i++) {
var col = cols[i];
var minWidth = col.minScreenWidth;
if (minWidth !== undefined$1 && minWidth !== null) {
any = true;
if (minWidth > screenWidth) {
this.hideColumn(col);
} else {
this.showColumn(col);
}
}
if (!col.hidden && col.columns) {
any = this._iterateMinScreenCols(col.columns, screenWidth) || any;
}
}
return any;
},
hideMinScreenCols: function() {
var cols = this.columns,
screenWidth = (window.innerWidth > 0) ? window.innerWidth : screen.width;
return this._iterateMinScreenCols(cols, screenWidth);
},
destroy: function() {
this._destroyColumnAttachments();
DataBoundWidget.fn.destroy.call(this);
var dataSource = this.dataSource;
dataSource.unbind(CHANGE, this._refreshHandler);
dataSource.unbind(ERROR, this._errorHandler);
dataSource.unbind(PROGRESS, this._progressHandler);
if (this._navigatableTables) {
this._navigatableTables.off(NS);
this._navigatableTables = null;
this._headertables = null;
}
this._current = null;
if (this._resizeHandler) {
$(window).off("resize" + NS, this._resizeHandler);
}
if (this._dragging) {
this._dragging.destroy();
this._dragging = null;
}
if (this.resizable) {
this.resizable.destroy();
this.resizable = null;
}
if (this.reorderable) {
this.reorderable.destroy();
this.reorderable = null;
}
if (this._draggableInstance && this._draggableInstance.element) {
this._draggableInstance.destroy();
this._draggableInstance = null;
}
if (this.selectable) {
this.selectable.destroy();
}
if (this._userEvents) {
this._userEvents.destroy();
this._userEvents = null;
}
if (this.minScreenResizeHandler) {
$(window).off("resize", this.minScreenResizeHandler);
}
this._destroyEditor();
this.element.off(NS);
if (this.wrapper) {
this.wrapper.off(NS);
}
if (this._touchScroller) {
this._touchScroller.destroy();
}
this._destroyPager();
if (dataSource) {
dataSource._dataMaps = null;
}
this._autoExpandable = null;
this._refreshHandler = this._errorHandler = this._progressHandler = this._dataSourceFetchProxy = null;
this.thead =
this.content =
this.tbody =
this.table =
this.element =
this.lockedHeader =
this.lockedContent = null;
this._statusTree =
this._headerTree =
this._contentTree =
this._lockedHeaderColsTree =
this._lockedContentColsTree =
this._lockedHeaderTree =
this._lockedContentTree = null;
kendo.destroy(this.wrapper);
},
options: {
name: "TreeList",
columns: [],
autoBind: true,
scrollable: true,
selectable: false,
sortable: false,
toolbar: null,
height: null,
columnMenu: false,
messages: {
noRows: "No records to display",
loading: "Loading...",
requestFailed: "Request failed.",
retry: "Retry",
dragHandleLabel: "Drag row",
commands: {
edit: "Edit",
update: "Save",
canceledit: "Cancel",
create: "Add new record",
createchild: "Add child record",
destroy: "Delete",
excel: "Export to Excel",
pdf: "Export to PDF",
search: "Search...",
select: "Select",
selectRow: "Select Row",
selectAllRows: "All rows",
clearSelection: "Clear selection",
exportPdf: "Export to PDF",
exportExcel: "Export to Excel",
sortAsc: "Sort Ascending",
sortDesc: "Sort Descending",
expandItem: "Expand Item",
collapseItem: "Collapse Item"
},
sortHeader: "Press Enter to sort",
filterCellTitle: "filter cell"
},
excel: {
hierarchy: true
},
resizable: false,
search: false,
filterable: false,
editable: false,
reorderable: false,
pageable: false,
renderAllRows: true,
rowTemplate: null,
altRowTemplate: null,
hasHeader: true,
contextMenu: false
},
events: [
CHANGE,
BEFORE_EDIT,
EDIT,
PAGE,
SAVE,
SAVE_CHANGES,
REMOVE,
EXPAND,
COLLAPSE,
DATABINDING,
DATABOUND,
CANCEL,
DRAGSTART,
DRAG,
DROP,
DRAGEND,
FILTERMENUINIT,
ITEM_CHANGE,
CELL_CLOSE,
FILTERMENUOPEN,
COLUMNHIDE,
COLUMNSHOW,
COLUMNREORDER,
COLUMNRESIZE,
COLUMNMENUINIT,
COLUMNMENUOPEN,
COLUMNLOCK,
COLUMNUNLOCK,
FILTER,
NAVIGATE,
SORT
],
getOptions: function() {
var options = this.options;
options.dataSource = null;
var result = extend(true, {}, this.options);
result.columns = kendo.deepExtend([], this.columns);
var dataSource = this.dataSource;
var initialData = dataSource.options.data && dataSource._data;
dataSource.options.data = null;
result.dataSource = $.extend(true, {}, dataSource.options);
dataSource.options.data = initialData;
result.dataSource.data = initialData;
result.dataSource.page = dataSource.page();
result.dataSource.filter = $.extend(true, {}, dataSource.filter());
result.dataSource.pageSize = dataSource.pageSize();
result.dataSource.sort = dataSource.sort();
result.dataSource.group = dataSource.group();
result.dataSource.aggregate = dataSource.aggregate();
if (result.dataSource.transport) {
result.dataSource.transport.dataSource = null;
}
if (result.pageable && result.pageable.pageSize) {
result.pageable.pageSize = dataSource.pageSize();
}
return result;
},
setOptions: function(options) {
var currentOptions = this.getOptions();
kendo.deepExtend(currentOptions, options);
if (!options.dataSource) {
currentOptions.dataSource = this.dataSource;
}
var wrapper = this.wrapper;
var events = this._events;
var element = this.element;
this.destroy();
this.options = null;
if (wrapper[0] !== element[0]) {
wrapper.before(element);
wrapper.remove();
}
element.empty();
this.init(element, currentOptions, events);
this._setEvents(currentOptions);
},
_destroyColumnAttachments: function() {
var that = this;
if (!that.thead) {
return;
}
that.thead.add(that.lockedHeader).find("th").each(function() {
var th = $(this),
filterMenu = th.data("kendoFilterMenu"),
sortable = th.data("kendoColumnSorter"),
columnMenu = th.data("kendoColumnMenu");
if (filterMenu) {
filterMenu.destroy();
}
if (sortable) {
sortable.destroy();
}
if (columnMenu) {
columnMenu.destroy();
}
});
},
_toggle: function(model, expand) {
var that = this;
var defaultPromise = $.Deferred().resolve().promise();
var loaded = model.loaded();
if (that._isIncellEditable() && that.editor) {
// manually trigger change as the expand/collapse icons are not focusable
$(activeElement()).change();
that.closeCell();
}
// reset error state
if (model._error) {
model.expanded = false;
model._error = undefined$1;
}
// do not load items that are currently loading
if (!loaded && model.expanded) {
return defaultPromise;
}
// toggle expanded state
if (typeof expand == "undefined") {
expand = !model.expanded;
}
model.expanded = expand;
function afterModelLoaded() {
that._toggleData();
if (that._isPageable()) {
that.refresh();
} else {
that._render();
}
that._syncLockedContentHeight();
}
if (!loaded) {
defaultPromise = this.dataSource.load(model)
.always((function() {
afterModelLoaded();
}));
}
afterModelLoaded();
return defaultPromise;
},
_toggleData: function() {
var that = this;
if (that._isPageable()) {
that._togglePageableData();
}
},
_togglePageableData: function() {
var that = this;
var dataSource = that.dataSource;
var data = dataSource._getData();
var result;
var queryOptions = dataSource._defaultPageableQueryOptions();
that._renderProgress(true);
var childrenMap = dataSource._getChildrenMap() || dataSource.childrenMap(dataSource._getData());
dataSource._processDataItemsState(data, childrenMap);
result = dataSource._processPageableQuery(data, queryOptions);
queryOptions.childrenMap = result.childrenMap;
queryOptions.filteredChildrenMap = result.filteredChildrenMap;
dataSource._aggregateResult = dataSource._calculateAggregates(result.dataToAggregate, queryOptions);
dataSource.view(result.data);
if (!dataSource.filter()) {
dataSource._calculateCollapsedTotal();
}
that._refreshPager();
that._renderProgress(false);
},
_refreshPager: function() {
var pager = this.pager;
if (pager) {
pager.refresh();
}
},
expand: function(row) {
return this._toggle(this.dataItem(row), true);
},
collapse: function(row) {
return this._toggle(this.dataItem(row), false);
},
_toggleChildren: function(e) {
var icon = $(e.target);
var model = this.dataItem(icon);
if (!model) {
return;
}
var event = !model.expanded ? EXPAND : COLLAPSE;
if (!this.trigger(event, { model: model })) {
this._toggle(model);
}
e.preventDefault();
},
_navigatable: function() {
var that = this;
if (!that.options.navigatable) {
that.table.attr("tabindex", 0);
return;
}
var tables = that.table.add(that.lockedTable);
var headerTables = that.thead.parent().add($(">table", that.lockedHeader));
if (that.options.scrollable) {
//add the header table when the widget is scrollable
tables = tables.add(headerTables);
}
headerTables
.find("a.k-link").attr("tabIndex", -1);
this._navigatableTables = tables;
this._headertables = headerTables;
tables
//handle click on tables, will attempt to focus the table
.on((kendo.support.touch ? "touchstart" + NS : "mousedown" + NS), NAVROW + ">:visible", that._tableClick.bind(that))
.on("focus" + NS, that._tableFocus.bind(that))
.on("focusout" + NS, that._tableBlur.bind(that))
.on("keydown" + NS, that._tableKeyDown.bind(that));
},
cellIndex: function(td) {
var lockedColumnOffset = 0;
if (this.lockedTable && !$.contains(this.lockedTable[0], td[0])) {
lockedColumnOffset = leafColumns(lockedColumns(this.columns)).length;
}
return $(td).parent().children().index(td) + lockedColumnOffset;
},
_isActiveInTable: function() {
var active = kendo._activeElement();
if (!active) { return false; }
return this.table[0] === active ||
$.contains(this.table[0], active) ||
(this.lockedTable &&
(this.lockedTable[0] === active || $.contains(this.lockedTable[0], active))
);
},
_restoreCurrent: function(currentIndex, isCurrentInHeader, currentRowIndex) {
var rowIndex;
var row;
var td;
if (currentIndex === undefined$1 || currentIndex < 0) {
return;
}
if (this._current) {
this._current.removeClass("k-focus");
}
if (isCurrentInHeader) {
this._setCurrent(this.thead.find("th").eq(currentIndex));
} else {
rowIndex = currentRowIndex || 0;
currentIndex = currentIndex || 0;
row = $();
if (this.lockedTable) {
row = this.lockedTable.find(">tbody>tr:visible").eq(rowIndex);
}
row = row.add(this.tbody.children().eq(rowIndex));
td = row.find(">td:visible")
.eq(currentIndex);
this._setCurrent(td);
}
if (this._current) {
focusTable(this.table, true);
this._current.addClass("k-focus");
}
},
current: function(newCurrent) {
return this._setCurrent(newCurrent, true);
},
_setCurrent: function(newCurrent, preventTrigger, isIncellEditable) {
var that = this;
var current = that._current;
newCurrent = $(newCurrent);
if (isIncellEditable) {
if (newCurrent[0]) {
that._current = newCurrent;
that._updateCurrentAttr(that._current, newCurrent);
that._scrollCurrent();
if (!preventTrigger) {
this.trigger(NAVIGATE, {
element: newCurrent
});
}
}
} else {
if (newCurrent.length && (!current || current[0] !== newCurrent[0])) {
this._updateCurrentAttr(current, newCurrent);
this._scrollCurrent();
if (!preventTrigger) {
this.trigger(NAVIGATE, {
element: newCurrent
});
}
}
if (newCurrent && newCurrent.length) {
this._lastCellIndex = newCurrent.parent().children(DATA_CELL).index(newCurrent);
}
}
return that._current;
},
_scrollCurrent: function() {
var current = this._current;
var scrollable = this.options.scrollable;
if (!current || !scrollable) {
return;
}
var row = current.parent();
var tableContainer = row.closest("table").parent();
var isInLockedContainer = tableContainer.is(".k-grid-content-locked,.k-grid-header-locked");
var isInContent = tableContainer.is(".k-grid-content-locked,.k-grid-content");
var scrollableContainer = $(this.content)[0];
//adjust scroll vertically
if (isInContent) {
this._scrollTo(this._relatedRow(row)[0], scrollableContainer);
}
if (this.lockedContent) {
//sync locked and non-locked content scrollTop
this.lockedContent[0].scrollTop = scrollableContainer.scrollTop;
}
//adjust scroll horizontally, if not inside locked tables
if (!isInLockedContainer) {
this._scrollTo(current[0], scrollableContainer);
}
},
_findCurrentCell: function() {
var that = this;
var current = that.current();
var elements = $(that.table).add(that.header).add(that.lockedTable).add(that.lockedHeader);
if (current && elements.find(current).length > 0) {
return current;
} else {
return elements.find(DOT + classNames.focused);
}
},
_scrollTo: function(element, container) {
var elementToLowercase = element.tagName.toLowerCase();
var isHorizontal = elementToLowercase === "td" || elementToLowercase === "th";
var table = $(element).closest("table")[0];
var elementOffsetDir = element[isHorizontal ? "offsetWidth" : "offsetHeight"];
var containerScroll = container[isHorizontal ? "scrollLeft" : "scrollTop"];
var containerOffsetDir = container[isHorizontal ? "clientWidth" : "clientHeight"];
var elementOffset = $(element).css("position") === "relative" && isRtl && isHorizontal ? Math.abs(table.offsetLeft - element.offsetLeft) : element[isHorizontal ? "offsetLeft" : "offsetTop"];
var bottomDistance = elementOffset + elementOffsetDir;
var result = 0;
var ieCorrection = 0;
var firefoxCorrection = 0;
if (isRtl && isHorizontal) {
if (browser.msie || browser.edge) {
ieCorrection = table.offsetLeft;
} else if (browser.mozilla || (browser.webkit && (browser.version > 85))) {
firefoxCorrection = table.offsetLeft - kendo.support.scrollbar();
}
}
containerScroll = Math.abs(containerScroll + ieCorrection - firefoxCorrection);
if (containerScroll > elementOffset) {
result = elementOffset;
} else if (bottomDistance > (containerScroll + containerOffsetDir)) {
if (elementOffsetDir <= containerOffsetDir) {
result = (bottomDistance - containerOffsetDir);
} else {
result = elementOffset;
}
} else {
result = containerScroll;
}
result = Math.abs(result + ieCorrection) + firefoxCorrection;
container[isHorizontal ? "scrollLeft" : "scrollTop"] = result;
},
_aria: function() {
var wrapper = this.wrapper,
gridRole = "treegrid",
table = this.table,
toolbar = wrapper.find(".k-grid-toolbar"),
groupingHeader = wrapper.find(".k-grouping-header"),
gridId = table.attr("id"),
tableTabindex = table.attr("tabindex"),
tbodyId, headerGroupId, footerGroupId, tableOwned,
numberOfFixedRows = this.thead.find("tr").length + this.wrapper.find(".k-grid-footer-wrap table tr").length,
trailingColumns = this._trailingColumns(),
virtual = this.virtualScroll,
pageable = this.options.pageable,
rowsCount;
table.attr({
role: gridRole,
tabindex: tableTabindex >= 0 ? tableTabindex : 0
});
table.find("tbody, thead, tfoot").attr("role", "rowgroup");
table.find("tr").attr("role", "row");
table.find("th").attr("role", "columnheader");
table.find("td").attr("role", "gridcell");
if ((pageable && this.dataSource.totalPages() > 1) || (virtual && virtual.rows)) {
if (this._groups() > 0) {
rowsCount = -1;
} else {
rowsCount = numberOfFixedRows + this.dataSource.total();
}
table.attr("aria-rowcount", rowsCount);
}
if (rowsCount && rowsCount > 0) {
this._ariaRowIndex();
}
if ((virtual && virtual.columns) ||
(!table.attr("aria-colcount") &&
(table.find("td:hidden").length > 0 ||
wrapper.find(".k-grid-content-locked td:hidden").length > 0))) {
table.attr("aria-colcount", trailingColumns + leafColumns(this.columns).length);
this._ariaColumnIndex();
}
if (!gridId) {
gridId = kendo.guid();
table.attr("id", gridId);
}
if (this.pager) {
this.pager.element.attr("aria-controls", gridId);
}
toolbar.attr({
role: "toolbar",
"aria-label": this.options.messages.toolbarLabel,
"aria-controls": gridId
});
groupingHeader.attr({
role: "toolbar",
"aria-label": this.options.messages.groupingHeaderLabel,
"aria-controls": gridId
});
headerGroupId = this._ariaHeaderFooter("header", "thead", "th, td", "columnheader");
footerGroupId = this._ariaHeaderFooter("footer", "tfoot", "td", "gridcell");
if (wrapper.find(".k-grid-content-locked").length > 0) {
this._ariaLockedContent();
}
if (!!headerGroupId || !!footerGroupId) {
tbodyId = this.tbody.attr("id") || kendo.guid();
tableOwned = [headerGroupId, tbodyId, footerGroupId].join(" ");
this.tbody.attr("id", tbodyId);
table.attr("aria-owns", tableOwned);
}
},
_ariaColumnIndex: function() {
var trailingColumns = this._trailingColumns(),
dataVirtual = this.tbody.find(">tr").last().find("> td[data-virtual]"),
headerRows = this.thead.find(">tr").not(".k-filter-row"),
lockedHeaderRows = this.wrapper.find(".k-grid-header-locked thead > tr").not(".k-filter-row"),
firstIndex = Number.MAX_VALUE,
lastIndex = 0,
lockedLastIndex = 0,
previousVirtual = 0,
nextVirtual = 0,
previousIndex, i, cells, dataIndex, cellsIndex,
eachHeaderCell = function(j, cell) {
var current = cell.getAttribute("data-index"),
currentIndex = Number(current),
lockedParent = $(cell).closest(".k-grid-header-locked");
if (lockedParent.length === 0 && currentIndex < firstIndex) {
firstIndex = currentIndex;
}
if (lockedParent.length > 0 && lockedLastIndex < currentIndex) {
lockedLastIndex = currentIndex;
}
if (lockedParent.length === 0 && lastIndex < currentIndex) {
lastIndex = currentIndex;
}
if (current !== null) {
cell.setAttribute("aria-colindex", Number(currentIndex) + 1);
previousIndex = Number(currentIndex) + 1 + cell.getAttribute("colspan");
} else {
cell.setAttribute("aria-colindex", previousIndex + 1);
previousIndex = previousIndex + cell.getAttribute("colspan");
}
};
if (dataVirtual.length === 2) {
previousVirtual = Number(dataVirtual[0].getAttribute("colspan"));
nextVirtual = Number(dataVirtual[1].getAttribute("colspan"));
} else if (dataVirtual.length === 1 && dataVirtual.prev().length === 0) {
previousVirtual = Number(dataVirtual[0].getAttribute("colspan"));
} else if (dataVirtual.length === 1 && dataVirtual.prev().length === 1) {
nextVirtual = Number(dataVirtual[0].getAttribute("colspan"));
}
for (i = 0; i < lockedHeaderRows.length; i++) {
previousIndex = 0;
lockedHeaderRows.eq(i).find("th").each(eachHeaderCell);
}
for (i = 0; i < headerRows.length; i++) {
previousIndex = 0;
headerRows.eq(i).find("th").each(eachHeaderCell);
}
for (i = 0; i <= lockedLastIndex; i++) {
dataIndex = i + trailingColumns;
cells = this.wrapper.find(".k-grid-content-locked tbody > tr > td:nth-child(" + (i + 1) + ")");
cells.attr("aria-colindex", dataIndex + 1);
}
for (i = previousVirtual; i <= lastIndex - firstIndex - nextVirtual; i++) {
if (previousVirtual === 0) {
cellsIndex = i + 1;
} else {
cellsIndex = i - previousVirtual + 2;
}
dataIndex = firstIndex + i + trailingColumns;
cells = this.tbody.find("> tr > td:nth-child(" + cellsIndex + ")");
cells.attr("aria-colindex", dataIndex + 1);
}
},
_ariaHeaderFooter: function(type, group, el, role) {
var that = this,
wrapper = that.wrapper,
table = wrapper.find(".k-grid-" + type + " .k-grid-" + type + "-wrap table"),
lockedTable = wrapper.find(".k-grid-" + type + " .k-grid-" + type + "-locked table"),
groupId = "",
rowGroup;
if (table.length > 0) {
rowGroup = table.find(group + ", tbody");
groupId = rowGroup.attr("id") || kendo.guid();
table.attr("role", "none");
table.find("tr").attr("role", "row");
table.find(el).attr("role", role);
rowGroup.attr({
role: "rowgroup",
id: groupId
});
}
if (lockedTable.length > 0) {
that._ariaLocked(type, group, el, role);
}
lockedTable.find("td").attr("role", "gridcell");
table.find("td").attr("role", "gridcell");
return groupId;
},
_ariaId: function() {
var id = this.element.attr("id") || "aria";
{
this._cellId = id + "_active_cell";
}
},
_ariaLocked: function(type, group, el, role) {
var that = this,
wrapper = that.wrapper,
table = wrapper.find(".k-grid-" + type + " .k-grid-" + type + "-wrap table"),
lockedTable = wrapper.find(".k-grid-" + type + " .k-grid-" + type + "-locked table"),
rows = table.find("tr"),
lockedRows = lockedTable.find("tr");
lockedTable.attr("role", "none");
lockedTable.find(group + ", tbody").attr("role", "none");
lockedRows.attr("role", "none");
lockedTable.find(el).attr("role", role);
rows.each(function(i, row) {
var ownedCells = [];
ownedCells = that._cellsIds(lockedRows.eq(i).find(el), "locked_" + type, i);
ownedCells = ownedCells.concat(that._cellsIds($(row).find(el), type, i));
row.setAttribute("aria-owns", ownedCells.join(" "));
});
},
_ariaLockedContent: function() {
var that = this,
table = that.table,
tableRows = table.find("tr"),
lockedTable = that.wrapper.find(".k-grid-content-locked table"),
lockedRows = lockedTable.find("tr");
lockedTable.attr("role", "none");
lockedTable.find("tbody").attr("role", "none");
lockedRows.attr("role", "none");
lockedTable.find("td").attr("role", "gridcell");
tableRows.each(function(i, row) {
var ownedCells = [];
ownedCells = that._cellsIds(lockedRows.eq(i).find("td"), "locked_datacell", i);
ownedCells = ownedCells.concat(that._cellsIds($(row).find("td"), "datacell", i));
row.setAttribute("aria-owns", ownedCells.join(" "));
});
},
_ariaAddHiddenColIndex: function() {
var virtualScroll = this.virtualScroll || {},
columns = this.columns,
table = this.table,
leafColsCount = leafColumns(columns).length;
if (!virtualScroll.columns && !table.attr("aria-colcount")) {
this._ariaColumnIndex();
table.attr("aria-colcount", leafColsCount);
}
},
_ariaRemoveHiddenColIndex: function() {
var virtualScroll = this.virtualScroll || {},
columns = this.columns;
leafColumns(columns).length;
if (!virtualScroll.columns /* && (leafColsCount === visibleLeafColumns(this.columns).length)*/) {
this.wrapper.find("td, th").removeAttr("aria-colindex");
this.table.removeAttr("aria-colcount");
}
},
_ariaRowIndex: function() {
var headerRows = this.thead.find(">tr"),
numberOfHeaderRows = headerRows.length,
bodyRows = this.tbody.find(">tr"),
footerRows = this.wrapper.find(".k-grid-footer-wrap tfoot > tr"),
totalNumberOfItems = this.dataSource.total(),
previousItems = this.dataSource.skip() || 0,
currentIndex = 1,
i, currentRow;
for (i = 0; i < numberOfHeaderRows; i++) {
headerRows.eq(i).attr("aria-rowindex", currentIndex + i);
}
currentIndex = numberOfHeaderRows + previousItems;
for (i = 0; i < bodyRows.length; i++) {
currentRow = bodyRows.eq(i);
currentIndex = currentIndex + 1;
currentRow.attr("aria-rowindex", currentIndex);
}
currentIndex = numberOfHeaderRows + totalNumberOfItems + 1;
for (i = 0; i < footerRows.length; i++) {
footerRows.eq(i).attr("aria-rowindex", currentIndex + i);
}
},
_cellsIds: function(elements, prefix, i) {
var ownedCells = [];
elements.each(function(j, cell) {
var id = cell.getAttribute("id") || prefix + "_" + i + "_" + j;
cell.setAttribute("id", id);
ownedCells.push(id);
});
return ownedCells;
},
_trailingColumns: function() {
return this._groups();
},
_groups: function() {
var group = this.dataSource.group();
return group ? group.length : 0;
},
_currentDataIndex: function(table, current) {
var index = current.attr("data-index");
if (!index) {
return undefined$1;
}
var lockedColumnsCount = lockedColumns(this.columns).length;
if (lockedColumnsCount && !table.closest("div").hasClass("k-grid-content-locked")[0]) {
return index - lockedColumnsCount;
}
return index;
},
_prevVerticalCell: function(container, current) {
var cells;
var row = current.parent();
var rows = container.children(NAVROW);
var rowIndex = rows.index(row);
//get data-index in case of last level of multi-level columns
var index = this._currentDataIndex(container, current);
var cellSelector = DATA_CELL + "," + FILTER_CELL;
//current is in the header, but not at the last level of multi-level columns
if ((index || current.hasClass("k-header")) && !row.hasClass("k-filter-row")) {
cells = parentColumnsCells(current);
return cells.eq(cells.length - 2);
}
index = Math.max(row.children(cellSelector).index(current), this._lastCellIndex || 0);
//if current is inside filter row
if (row.hasClass("k-filter-row")) {
return leafDataCells(container).filter(isCellVisible).eq(index);
}
//move up to header container
if (rowIndex == -1) {
//is there filter row in the header container
row = container.find("tr.k-filter-row:visible");
if (!row[0]) {
return leafDataCells(container).filter(isCellVisible).eq(index);
}
} else {
row = rowIndex === 0 ? $() : rows.eq(rowIndex - 1);
}
cells = row.children(cellSelector);
if (cells.length > index) {
return cells.eq(index);
}
return cells.eq(0);
},
_nextVerticalCell: function(container, current) {
var cells;
var row = current.parent();
var rows = container.children(NAVROW);
var rowIndex = rows.index(row);
//get data-index in case of last level of multi-level columns
var index = this._currentDataIndex(container, current);
var cellSelector = DATA_CELL + "," + FILTER_CELL;
//current is in the header, but not at the last level of multi-level columns
//and we are not changing the table
if (rowIndex != -1 && index === undefined$1 && current.hasClass("k-header")) {
return childColumnsCells(current).eq(1);
}
index = index ? parseInt(index, 10) : row.children(cellSelector).index(current);
index = Math.max(index, this._lastCellIndex || 0);
//move down to data container
if (rowIndex == -1) {
row = rows.eq(0);
} else {
row = rows.eq(rowIndex + current[0].rowSpan);
}
var tmpIndex = index;
//in case of last level of multi-level columns the index should be updated depending on the hidden columns
if (this._currentDataIndex(container, current) !== undefined$1) {
var currentRowCells = row.children(":not(.k-group-cell):not(.k-hierarchy-cell)");
var hiddenColumns = currentRowCells.filter(":hidden");
for (var idx = 0, length = hiddenColumns.length; idx < length; idx++) {
if (currentRowCells.index(hiddenColumns[idx]) < index) {
tmpIndex--;
}
}
}
index = tmpIndex;
cells = row.children(cellSelector);
if (cells.length > index) {
return cells.eq(index);
}
return cells.eq(0);
},
_verticalContainer: function(container, up) {
var table = container.parent();
var length = this._navigatableTables.length;
var step = Math.floor(length / 2);
var index = inArray(table[0], this._navigatableTables);
if (up) {
step *= -1;
}
index += step;
if (index >= 0 || index < length) {
table = this._navigatableTables.eq(index);
}
return table.find(up ? "thead" : "tbody");
},
_filterFocusable: function() {
return this.wrapper.find(".k-filter-row").find(".k-dropdownlist, .k-input .k-input-inner:visible, input[type='radio']:visible, input[type='checkbox']:visible");
},
_updateCurrentAttr: function(current, next) {
var headerId = $(current).data("headerId");
$(current)
.removeClass(classNames.focused);
this.table.removeAttr(ARIA_ACTIVEDESCENDANT);
if (headerId) {
headerId = headerId.replace(this._cellId, "");
$(current).attr("id", headerId);
} else {
$(current).removeAttr("id");
}
next
.data("headerId", next.attr("id"))
.attr("id", this._cellId)
.addClass(classNames.focused);
this.table.attr(ARIA_ACTIVEDESCENDANT, this._cellId);
this._current = next;
},
_tableKeyDown: function(e) {
var handled = false;
var current = this.current();
var target = $(e.target);
var canHandle = !e.isDefaultPrevented() && !target.is(":button,a,:input,a>.k-icon,a>.k-svg-icon");
current = current ? current : $(this.lockedTable).add(this.table).find(NAVROW + " > td:visible").first();
if (e.altKey && e.keyCode == keys.DOWN) {
current.find(".k-grid-filter-menu, .k-grid-column-menu").click();
e.stopImmediatePropagation();
return;
}
if (e.keyCode === keys.F10 && this.toolbar && this.toolbar.length) {
this.toolbar.find("[tabindex=0]:visible").first().trigger("focus");
handled = true;
}
if (canHandle && e.keyCode == keys.UP) {
handled = this._moveUp(current, e.shiftKey);
}
if (canHandle && e.keyCode == keys.DOWN) {
handled = this._moveDown(current, e.shiftKey);
}
if (canHandle && e.ctrlKey && current.is(".k-header") && this.options.reorderable && e.keyCode == (isRtl ? keys.RIGHT : keys.LEFT)) {
this._moveColumn(current, true);
} else if (canHandle && e.ctrlKey && current.is(".k-header") && this.options.reorderable && e.keyCode == (isRtl ? keys.LEFT : keys.RIGHT)) {
this._moveColumn(current, false);
} else if (canHandle && e.keyCode == (isRtl ? keys.LEFT : keys.RIGHT)) {
if (e.altKey) {
this._handleExpand(current);
handled = true;
} else {
handled = this._moveRight(current);
}
} else if (canHandle && e.keyCode == (isRtl ? keys.RIGHT : keys.LEFT)) {
if (e.altKey) {
this._handleCollapse(current);
handled = true;
} else {
handled = this._moveLeft(current);
}
}
if (canHandle && e.keyCode == keys.PAGEDOWN) {
handled = this._handlePageDown();
}
if (canHandle && e.keyCode == keys.PAGEUP) {
handled = this._handlePageUp();
}
if (e.keyCode == keys.ENTER || e.keyCode == keys.F2) {
handled = this._handleEnterKey(current, e.currentTarget, target);
}
if (e.keyCode == keys.ESC) {
handled = this._handleEscKey(current, e.currentTarget);
}
if (canHandle && e.keyCode == keys.HOME) {
handled = this._handleHome(current, e.ctrlKey);
}
if (canHandle && e.keyCode == keys.END) {
handled = this._handleEnd(current, e.ctrlKey);
}
if (e.keyCode == keys.TAB) {
handled = this._handleTabKey(current, e.currentTarget, e.shiftKey, target);
}
if (handled) {
//prevent scrolling while pressing the keys
e.preventDefault();
//required in hierarchy
e.stopPropagation();
}
},
_moveColumn: function(current, isLeft) {
var elements = this.wrapper.data().kendoReorderable.element.find(this._draggableInstance.options.filter + ":visible");
var columns = visibleColumns(flatColumnsInDomOrder(this.columns));
var oldIndex = elements.index($(current));
var offset = isLeft ? -1 : 1;
var column = columns[oldIndex];
var newIndex = targetParentContainerIndex(columns, this.columns, oldIndex, oldIndex + offset);
if (newIndex >= 0) {
this.reorderColumn(newIndex, column, isLeft);
this.trigger(COLUMNREORDER, {
newIndex: newIndex,
oldIndex: oldIndex,
column: column
});
}
},
_handleExpand: function(current) {
var that = this;
var row = current.parent();
var model = that.dataItem(row);
if (current.hasClass("k-header")) {
return false;
}
if (model && model.hasChildren && !model.expanded && !that.trigger(EXPAND, { model: model })) {
this.expand(row);
return true;
}
return false;
},
_handleCollapse: function(current) {
var that = this;
var row = current.parent();
var model = that.dataItem(row);
if (current.hasClass("k-header")) {
return false;
}
if (model && model.hasChildren && model.expanded && !that.trigger(COLLAPSE, { model: model })) {
that.collapse(row);
return true;
}
return false;
},
_handleHome: function(current, ctrl) {
var row = current.parent();
var rowContainer = row.parent();
var isInLockedTable = this.lockedTable && this.lockedTable.children("tbody")[0] === rowContainer[0];
var isInBody = rowContainer[0] === this.tbody[0];
var prev;
if (ctrl) {
if (this.lockedTable) {
prev = this.lockedTable.find(NAVROW + " > td:visible").first();
} else {
prev = this.table.find(NAVROW + " > td:visible").first();
}
} else if (isInBody || isInLockedTable) {
if (isInBody && this.lockedTable) {
row = this._relatedRow(row);
}
prev = row.children(NAVCELL).first();
}
if (prev && prev.length) {
this._setCurrent(prev);
return true;
}
},
_handleEnd: function(current, ctrl) {
var row = current.parent();
var rowContainer = row.parent();
var isInLockedTable = this.lockedTable && this.lockedTable.children("tbody")[0] === rowContainer[0];
var isInBody = rowContainer[0] === this.tbody[0];
var next;
if (ctrl) {
next = this.table.find(ITEMROW).last().children(NAVCELL).last();
} else if (isInBody || isInLockedTable) {
if (!isInBody && this.lockedTable) {
row = this._relatedRow(row);
}
next = row.children(NAVCELL).last();
}
if (next && next.length) {
this._setCurrent(next);
return true;
}
},
_handlePageDown: function() {
var that = this;
if (!that._isPageable()) {
return false;
}
that.dataSource._restorePageSizeAfterAddChild();
that.dataSource.page(that.dataSource.page() + 1);
return true;
},
_handlePageUp: function() {
var that = this;
if (!that._isPageable()) {
return false;
}
that.dataSource._restorePageSizeAfterAddChild();
that.dataSource.page(that.dataSource.page() - 1);
return true;
},
_handleEscKey: function(current, currentTable) {
var active = kendo._activeElement();
var currentIndex;
var that = this;
var row;
var rowIndex;
var cellIndex;
var tbody;
if (!current || !current.parent().hasClass("k-grid-edit-row")) {
if (current.has(active).length) {
// return focus back to the table
focusTable(that.table, true);
return true;
}
if (current.parent().hasClass("k-filter-row")) {
this._filterFocusable().attr(TABINDEX, -1);
focusTable(this.table, true);
return true;
}
return false;
}
if (that._isIncellEditable()) {
row = current.parent();
cellIndex = current.index();
rowIndex = row.index();
tbody = row.closest("tbody");
that.closeCell(true);
// refresh the current element as the DOM element reference can be changed after render()
// moving this to closeCell() causes flickering when clicking on a cell and then on another
// as 'k-focused' is shown for the closing cell and then added to the newly edited cell
that._setCurrent(tbody.children().eq(rowIndex).children().eq(cellIndex), false, true);
} else {
currentIndex = $(current).parent().index();
if (active) {
active.blur();
}
this.cancelRow();
if (currentIndex >= 0) {
this._setCurrent(this.items().eq(currentIndex).children(NAVCELL).first());
}
}
focusTable(that.table, true);
return true;
},
_handleEnterKey: function(current, currentTable, target) {
var editable = this.options.editable;
var container = target.closest("[role=gridcell]");
var focusable, link, filterFocusable;
if (!target.is("table") && !$.contains(current[0], target[0])) {
current = container;
}
if (current.is("th")) {
// sort the column, if possible
link = current.find(".k-link");
if (current.has($(activeElement())).length > 0) {
return false;
} else if (link.length) {
link.click();
} else if (current.parent().hasClass("k-filter-row")) {
filterFocusable = this._filterFocusable();
filterFocusable.attr(TABINDEX, 0);
current.find(":kendoFocusable").first().trigger("focus");
} else {
current.find(CHECKBOXINPUT).trigger("focus");
}
return true;
}
focusable = current.find(":kendoFocusable").first();
if (focusable[0] && current.hasClass("k-focus")) {
focusable.trigger("focus");
return true;
}
if (editable && !target.is(":button,.k-button,textarea")) {
if (!container[0]) {
container = current;
}
this._handleEditing(container, false, currentTable);
return true;
}
if (!editable && current.is("td[aria-expanded]")) {
if (current.is("[aria-expanded=false]")) {
this._handleExpand(current);
} else {
this._handleCollapse(current);
}
}
return false;
},
_handleTabKey: function(current, currentTable, shiftKey, target) {
var that = this;
var incellEditing = that.options.editable && that._isIncellEditable();
var cell, filterFocusable;
if (!incellEditing || current.is("th") || (this.options.scrollable ? this._headertables.filter(currentTable).length : this.thead.filter(target).length)) {
if (current.parent().hasClass("k-filter-row")) {
filterFocusable = this._filterFocusable();
if (!shiftKey && filterFocusable[filterFocusable.length - 1] === document.activeElement) {
filterFocusable.first().trigger("focus");
return true;
} else if (shiftKey && filterFocusable[0] === document.activeElement) {
filterFocusable.last().trigger("focus");
return true;
}
}
return false;
}
cell = $(activeElement()).closest(DOT + classNames.editCell);
if (that.options._tabCycleStop) {
return false;
}
if (cell[0] && cell[0] !== current[0]) {
current = cell;
}
cell = that._tabNext(current, currentTable, shiftKey);
if (cell.length) {
that._handleEditing(current, cell, cell.closest(TABLE));
return true;
} else {
that._preventPageSizeRestore = false;
}
return false;
},
_tabNext: function(current, currentTable, back) {
var that = this;
var switchRow = true;
var next = back ? current.prevAll(DATA_CELL).first() : current.nextAll(":visible").first();
if (!next.length) {
next = current.parent();
if (that.lockedTable) {
switchRow = (back && currentTable == that.lockedTable[0]) || (!back && currentTable == that.table[0]);
next = that._relatedRow(next);
}
if (switchRow) {
next = next[back ? "prevAll" : "nextAll"]("tr:not(.k-grouping-row):not(.k-detail-row):visible").first();
}
if (back) {
next = next.children(DATA_CELL).last();
} else {
next = next.children(DATA_CELL).first();
}
that.dataSource._restorePageSizeAfterAddChild();
}
return next;
},
_handleEditing: function(current, next, table) {
var that = this,
active = $(kendo._activeElement()),
isIE = browser.msie,
editContainer,
focusable,
isEdited;
var editable = that.options.editable && that.options.editable.update !== false;
var incellEditing = that._isIncellEditable();
var nextFocusableCellRowIndex = $(next).parents("tr").index();
var nextFocusableCellIndex = $(next).index();
var currentFocusedCellRowIndex = $(current).parents("tr").index();
var currentFocusedCellIndex = current.index();
var editedCell;
table = $(table);
if (incellEditing) {
isEdited = current.hasClass(classNames.editCell);
} else {
isEdited = current.parent().hasClass("k-grid-edit-row");
}
if (that.editor) {
editContainer = that.editor.wrapper;
if (editContainer && $.contains(editContainer[0], active[0])) {
if (browser.opera) {
active.trigger("blur").change().triggerHandler("blur");
} else {
active.trigger("blur");
if (isIE) {
//IE10 with jQuery 1.9.x does not trigger blur handler
//numeric textbox does trigger change
active.trigger("blur");
}
}
}
if (!that.editor) {
focusTable(that.table);
return;
}
if (that.editor.end()) {
if (incellEditing) {
that._preventPageSizeRestore = true;
that.closeCell();
that._preventPageSizeRestore = false;
if ($(that.table).add(that.lockedTable).find(DOT + classNames.editCell).length === 0) {
that._setCurrent(table.find("tbody").children().eq(currentFocusedCellRowIndex).children().eq(currentFocusedCellIndex));
}
} else {
that.saveRow();
isEdited = true;
}
} else {
if (incellEditing) {
that._setCurrent(editContainer);
} else {
that._setCurrent(editContainer.children().filter(NAVCELL).first());
}
focusable = editContainer.find(":kendoFocusable").first()[0];
if (focusable) {
focusable.focus();
}
return;
}
}
// the next cell to focus might be re-rendered, so update the reference to it if it is an element
next = $(next).length && table.find(next).length === 0 ? table.find("tbody").children().eq(nextFocusableCellRowIndex).children().eq(nextFocusableCellIndex) : next;
if (next) {
that._setCurrent(next);
}
focusTable(that.table, true);
if (!editable) {
return;
}
if ((!isEdited && !next) || next) {
if (!that.current()) {
return;
}
var currentIndex = that.current().index();
if (incellEditing) {
that.editCell(that.current());
editedCell = $(that.table).add(that.lockedTable).find(DOT + classNames.editCell)[0];
if (editedCell) {
that._current = $(editedCell);
} else {
that._setCurrent(that._findCurrentCell());
}
} else {
that.editRow(that.current().parent());
that._setCurrent(that.editor.wrapper.children().eq(currentIndex));
that.current().removeClass("k-focus");
}
} else {
that.dataSource._restorePageSizeAfterAddChild();
}
},
_moveRight: function(current) {
var next = current.nextAll(NAVCELL).first();
var row = current.parent();
var rowIndex = row.index();
if (current.hasClass("k-header") || row.is('.k-filter-row')) {
next = current.nextAll(NAVHEADER).first();
if (!next[0] && this.lockedTable && current.closest("table")[0] === this.lockedHeader.find("table")[0]) {
next = this.thead.find("tr").eq(rowIndex).find(NAVHEADER).first();
}
}
if (!next[0] && this.lockedTable && current.closest("table")[0] === this.lockedTable[0]) {
next = this._relatedRow(row).children(NAVCELL).first();
}
if (next[0] && next[0] !== current[0]) {
focusTable(this.table, true);
}
this._setCurrent(next);
return true;
},
_moveLeft: function(current) {
var prev = current.prevAll(NAVCELL).first();
var row = current.parent();
var rowIndex = row.index();
if (current.hasClass("k-header") || row.is('.k-filter-row')) {
prev = current.prevAll(NAVHEADER).first();
if (!prev[0] && this.lockedTable && current.closest("table")[0] === this.thead.parent()[0]) {
prev = this.lockedHeader.find(">table>thead>tr").eq(rowIndex).children(NAVHEADER).last();
}
}
if (!prev[0] && this.lockedTable && current.closest("table")[0] === this.table[0]) {
prev = this._relatedRow(row).children(NAVCELL).last();
}
if (prev[0] && prev[0] !== current[0]) {
focusTable(this.table, true);
}
this._setCurrent(prev);
return true;
},
_moveUp: function(current, shiftKey) {
var container = current.parent().parent();
var prev;
if (shiftKey) {
prev = current.parent();
prev = prev.prevAll(ITEMROW).first();
prev = current.parent().is(ITEMROW) ? prev.children().eq(current.index()) : prev.children(DATA_CELL).last();
} else {
prev = this._prevVerticalCell(container, current);
if (!prev[0]) {
this._lastCellIndex = 0;
container = this._verticalContainer(container, true);
prev = this._prevVerticalCell(container, current);
if (prev[0]) {
focusTable(this.table, true);
}
}
}
var tmp = this._lastCellIndex || 0;
this._setCurrent(prev);
this._lastCellIndex = tmp;
return true;
},
_moveDown: function(current, shiftKey) {
var container = current.parent().parent();
var next;
if (shiftKey) {
next = current.parent();
next = next.nextAll(ITEMROW).first();
next = current.parent().is(ITEMROW) ? next.children().eq(current.index()) : next.children(DATA_CELL).first();
} else {
next = this._nextVerticalCell(container, current);
if (!next[0]) {
this._lastCellIndex = 0;
container = this._verticalContainer(container);
next = this._nextVerticalCell(container, current);
if (next[0]) {
focusTable(this.table, true);
}
}
}
var tmp = this._lastCellIndex || 0;
this._setCurrent(next);
this._lastCellIndex = tmp;
return true;
},
_tableClick: function(e) {
var that = this,
currentTarget = $(e.currentTarget),
isHeader = currentTarget.is("tr:not('.k-filter-row')>th"),
target = $(e.target),
table = this.table.add(this.lockedTable),
headerTable = this.thead.parent().add($(">table", this.lockedHeader)),
isInput = isInputElement(target.add(target.closest(".k-button-icon"))),
currentTable = currentTarget.closest("table")[0];
if (kendo.support.touch) {
return;
}
if (currentTable !== table[0] && currentTable !== table[1] && currentTable !== headerTable[0] && currentTable !== headerTable[1]) {
return;
}
if (this.options.navigatable && !isInput) {
this._setCurrent(currentTarget);
}
if (isHeader || !isInput) {
setTimeout(function() {
if (!isInputElement(kendo._activeElement()) || !$.contains(currentTable, kendo._activeElement())) {
focusTable(that.table, true);
}
});
}
if (isHeader) {
e.preventDefault(); //if any problem occurs, call preventDefault only for the clicked header links
}
},
_tableFocus: function(e) {
var current = this.current();
var table = this.lockedTable ? this.lockedTable : this.table;
if (current && current.is(":visible")) {
current.addClass(classNames.focused);
} else {
this._setCurrent(table.find(NAVROW + " > td:visible").first());
}
this.table.attr(TABINDEX, 0);
},
_tableBlur: function() {
var current = this.current();
if (current) {
current.removeClass(classNames.focused);
}
},
_attachEvents: function() {
var that = this;
var retryButton = DOT + classNames.retry;
that._userEvents = new kendo.UserEvents(that.element, {
tap: that._onPress.bind(that),
allowSelection: true
});
this.element
.on(CLICK + NS, retryButton, this._dataSourceFetchProxy)
.on(CLICK + NS, ".k-button[data-command]", this._commandClick.bind(this))
.on(INPUT + NS, ".k-grid-search input", this._search.bind(this));
this._attachCellEditingEventHandlers();
},
_onPress: function(e) {
var that = this;
if (that._isToggleIcon(e.event.target)) {
that._toggleChildren.call(that, e.event);
}
},
_isToggleIcon: function(target) {
const icons = ICON_EXPAND_COLLAPSE_SELECTOR +
"," + ICON_REFRESH_SELECTOR;
return $(target).closest(":not(path,svg)").is(icons);
},
_attachCellEditingEventHandlers: function() {
var that = this;
var editable = that.options.editable;
var selectable = that.selectable && that.selectable.options.multiple;
var closeCell = function(e) {
var target = activeElement();
var editor = that.editor || {};
var cell = editor.element;
if (cell && !$.contains(cell[0], target) && cell[0] !== target && !$(target).closest(".k-animation-container").length) {
if (editor.end()) {
if (!e.relatedTarget && that._isPageable() && !isUndefined(that.dataSource._addChildPageSize)) {
that._preventPageSizeRestore = false;
}
that.closeCell();
}
}
that._preventPageSizeRestore = false;
};
if (that._isIncellEditable() && editable.update !== false) {
that.wrapper
.on(that.options._editCellEvent || CLICK + NS, "tr:not(.k-grouping-row) > td", function(e) {
var td = $(this),
isLockedCell = that.lockedTable && td.closest("table")[0] === that.lockedTable[0];
if (that._isToggleIcon(e.target)) {
return;
}
if (td.hasClass(classNames.editCell) ||
td.has("a.k-grid-delete").length ||
td.has("button.k-grid-delete").length ||
(td.closest("tbody")[0] !== that.tbody[0] && !isLockedCell) ||
$(e.target).is(":input") ||
$(e.target).is(ICON_EXPAND_COLLAPSE_SELECTOR)) {
if (!that.editor) {
that.dataSource._restorePageSizeAfterAddChild();
}
that._preventPageSizeRestore = false;
return;
}
if (that.editor) {
if (td.is(":not(.k-command-cell)") && that.editor.end()) {
if (selectable) {
$(activeElement()).trigger("blur");
}
that.closeCell();
that.editCell(td);
}
} else {
that.editCell(td);
}
})
.on("mousedown" + NS, "tr:not(.k-grouping-row) > td", function(e) {
// cache the result on "mousedown", which is fired before "focusout" and "click"
if (that.editor && that._isPageable() && !isUndefined(that.dataSource._addChildPageSize)) {
that._preventPageSizeRestore = $(e.target).parents(DOT + classNames.editRow).length > 0;
} else {
that._preventPageSizeRestore = false;
}
})
.on("focusin" + NS, function() {
// fix focus issue in IE
if (!$.contains(this, activeElement())) {
clearTimeout(that._closeCellTimeout);
that._closeCellTimeout = null;
}
})
.on("focusout" + NS, function(e) {
that._closeCellTimeout = setTimeout(function() {
closeCell(e);
}, 1);
});
}
},
_commandByName: function(name) {
var columns = this.columns;
var toolbar = Array.isArray(this.options.toolbar) ? this.options.toolbar : [];
var i, j, commands, currentName;
if (!name) {
return;
}
name = name.toLowerCase();
if (defaultCommands[name]) {
return defaultCommands[name];
}
// command not found in defaultCommands, must be custom
for (i = 0; i < columns.length; i++) {
commands = columns[i].command;
if (commands) {
for (j = 0; j < commands.length; j++) {
currentName = commands[j].name;
if (!currentName) {
continue;
}
if (currentName.toLowerCase() == name) {
return commands[j];
}
}
}
}
// custom command in toolbar
for (i = 0; i < toolbar.length; i++) {
currentName = toolbar[i].name;
if (!currentName) {
continue;
}
if (currentName.toLowerCase() == name) {
return toolbar[i];
}
}
},
_commandClick: function(e) {
var button = $(e.currentTarget);
var commandName = button.attr("data-command") || button.parent().attr("data-command");
var command = this._commandByName(commandName);
var row = button.parentsUntil(this.wrapper, "tr");
row = row.length ? row : undefined$1;
if (command) {
if (command.methodName) {
this[command.methodName](row);
} else if (command.click) {
command.click.call(this, e);
}
if (e.preventDefault) {
e.preventDefault();
}
}
},
_search: function(e) {
var that = this;
var input = e.currentTarget;
clearTimeout(that._searchTimeOut);
that._searchTimeOut = setTimeout(function() {
that._searchTimeOut = null;
var options = that.options;
var searchFields = options.search ? options.search.fields : null;
var expression = { filters: [], logic: "or" };
var value = input.value;
if (!searchFields) {
searchFields = getColumnsFields(options.columns);
}
if (value) {
for (var i = 0; i < searchFields.length; i++) {
expression.filters.push({ field: searchFields[i], operator: "contains", value: value });
}
} else {
expression = {};
}
that.dataSource.filter(expression);
}, 300);
},
_ensureExpandableColumn: function() {
if (this._autoExpandable) {
delete this._autoExpandable.expandable;
}
var visibleColumns = grep(this.columns, not(is("hidden")));
visibleColumns = grep(visibleColumns, not(is("command")));
visibleColumns = grep(visibleColumns, not(is("selectable")));
visibleColumns = grep(visibleColumns, not(is("draggable")));
var expandableColumns = grep(visibleColumns, is("expandable"));
if (this.columns.length && !expandableColumns.length) {
this._autoExpandable = visibleColumns[0];
visibleColumns[0].expandable = true;
}
},
_columns: function() {
var that = this,
columns = this.options.columns || [],
draggableColumns;
this.columns = map(columns, function(column) {
column = (typeof column === "string") ? { field: column } : column;
return extend({ encoded: true }, column);
});
var lockedCols = lockedColumns(columns);
if (lockedCols.length > 0) {
if (this.options.rowTemplate || this.options.altRowTemplate) {
throw new Error("Having both row template and locked columns is not supported");
}
this._hasLockedColumns = true;
this.columns = lockedCols.concat(nonLockedColumns(this.columns));
}
this.columns = normalizeColumns(this.columns);
this._ensureExpandableColumn();
this._columnTemplates();
this._columnAttributes();
if ($.grep(leafColumns(that.columns), function(col) {
if (col.selectable) {
that._includeChildren = col.includeChildren;
}
return col.selectable;
}).length) {
that._checkBoxSelection = true;
that.element.on(CLICK + NS, "tbody > tr " + CHECKBOXINPUT, that._checkboxClick.bind(that));
that.element.on(CLICK + NS, "thead > tr " + CHECKBOXINPUT, that._headerCheckboxClick.bind(that));
}
draggableColumns = $.grep(leafColumns(that.columns), function(col) { return col.draggable; });
if (draggableColumns.length) {
that._hasDragHandleColumn = true;
for (var i = 0; i < draggableColumns.length; i++) {
draggableColumns[i].headerAttributes = $.extend({
"aria-label": that.options.messages.dragHandleLabel
}, draggableColumns[i].headerAttributes);
}
}
},
_columnTemplates: function() {
var idx, length, column;
var columns = leafColumns(this.columns);
for (idx = 0, length = columns.length; idx < length; idx++) {
column = columns[idx];
if (column.template) {
column.template = kendo.template(column.template);
}
if (this._isIncellEditable()) {
column.dirtyCellTemplate = this._createDirtyColumnTemplate(column);
column.dirtyIndicatorTemplate = this._createIndicatorTemplate(column);
}
if (column.headerTemplate) {
column.headerTemplate = kendo.template(column.headerTemplate);
}
if (column.footerTemplate) {
column.footerTemplate = kendo.template(column.footerTemplate);
}
}
},
_columnAttributes: function() {
// column style attribute is string, kendo.dom expects object
var idx, length;
var columns = flatColumns(this.columns);
function convertStyle(attr) {
var properties, i, declaration;
if (attr && attr.style && attr.style.split) {
properties = attr.style.split(";");
attr.style = {};
for (i = 0; i < properties.length; i++) {
declaration = properties[i].split(":");
var name = kendo.trim(declaration[0]);
if (name) {
attr.style[toCamelCase(name)] = kendo.trim(declaration[1]);
}
}
}
}
for (idx = 0, length = columns.length; idx < length; idx++) {
convertStyle(columns[idx].attributes);
convertStyle(columns[idx].headerAttributes);
}
},
_clearSortClasses: function() {
var that = this;
if (that.content) {
that.content.find("col:not(.k-group-col):not(.k-hierarchy-col)").removeClass("k-sorted");
}
if (that.lockedContent) {
that.lockedContent.find("col:not(.k-group-col):not(.k-hierarchy-col)").removeClass("k-sorted");
}
},
_layout: function() {
var that = this;
this.columns;
var element = this.element;
this.wrapper = element.addClass(classNames.wrapper);
var layoutTemplateFunction = ({ gridHeader, gridHeaderWrap, gridContentWrap, toolbar, gridToolbar }) => {
var layout = this.options.hasHeader ? `<div class='${gridHeader}'>` : '';
if (this.options.hasHeader && this._hasLockedColumns) {
layout += "<div class='k-grid-header-locked'>" +
"<table class='k-grid-header-table k-table k-table-md'>" +
"<colgroup></colgroup>" +
"<thead class='k-table-thead' role='rowgroup'></thead>" +
"</table>" +
"</div>";
}
if (this.options.hasHeader) {
layout += `<div class='${gridHeaderWrap}'>` +
"<table class='k-grid-header-table k-table k-table-md'>" +
"<colgroup></colgroup>" +
"<thead class='k-table-thead' role='rowgroup'></thead>" +
"</table>" +
"</div>" +
"</div>";
}
if (this._hasLockedColumns) {
layout += "<div class='k-grid-content-locked'>" +
"<table class='k-grid-table k-table k-table-md' role='treegrid'>" +
"<colgroup></colgroup>" +
"<tbody class='k-table-tbody' role='rowgroup'></tbody>" +
"</table>" +
"</div>";
}
layout += `<div class='${gridContentWrap} k-auto-scrollable'>` +
"<table class='k-grid-table k-table k-table-md' role='treegrid'>" +
"<colgroup></colgroup>" +
"<tbody class='k-table-tbody' role='rowgroup'></tbody>" +
"</table>" +
"</div>";
if (!this.options.scrollable) {
layout =
`<table class='k-grid-table k-table k-table-md' role='treegrid' >` +
`<colgroup></colgroup>` +
`${this.options.hasHeader ? `<thead class='k-table-thead ${gridHeader}' role='rowgroup'></thead>` : ''}` +
`<tbody class='k-table-tbody' role='rowgroup'></tbody>` +
`</table>`;
}
if (this.options.toolbar) {
layout = `<div class='${toolbar} ${gridToolbar}'></div>` + layout;
}
return layout;
};
layoutTemplateFunction = layoutTemplateFunction.bind(that);
element.append(
kendo.template(layoutTemplateFunction)(classNames) +
"<div class='k-status' role='alert' aria-live='polite'></div>"
);
this.toolbar = element.find(DOT + classNames.gridToolbar);
var header = element.find(DOT + classNames.gridHeader).find("thead").addBack().filter("thead");
this.thead = header.last();
if (this.options.scrollable) {
var rtl = kendo.support.isRtl(element);
element.find("div." + classNames.gridHeader)
.css(rtl ? "padding-left" : "padding-right", kendo.support.scrollbar());
}
var content = element.find(DOT + classNames.gridContentWrap);
if (!content.length) {
content = element;
} else {
this.content = content;
}
this.table = content.find(">table").addClass("k-grid-table");
this.tbody = this.table.find(">tbody");
if (this._hasLockedColumns) {
this.lockedHeader = header.first().closest(".k-grid-header-locked");
this.lockedContent = element.find(".k-grid-content-locked");
this.lockedTable = this.lockedContent.children().addClass("k-grid-table");
}
this._initVirtualTrees();
this._renderCols();
if (that.options.hasHeader) {
this._renderHeader();
}
},
_initVirtualTrees: function() {
this._headerColsTree = new kendoDom.Tree(this.thead.prev()[0]);
this._contentColsTree = new kendoDom.Tree(this.tbody.prev()[0]);
this._headerTree = new kendoDom.Tree(this.thead[0]);
this._contentTree = new kendoDom.Tree(this.tbody[0]);
this._statusTree = new kendoDom.Tree(this.element.children(".k-status")[0]);
if (this.lockedHeader) {
this._lockedHeaderColsTree = new kendoDom.Tree(this.lockedHeader.find("colgroup")[0]);
this._lockedContentColsTree = new kendoDom.Tree(this.lockedTable.find(">colgroup")[0]);
this._lockedHeaderTree = new kendoDom.Tree(this.lockedHeader.find("thead")[0]);
this._lockedContentTree = new kendoDom.Tree(this.lockedTable.find(">tbody")[0]);
}
},
_processToolbarItems: function(commands) {
var that = this,
messages = that.options.messages.commands,
items = [];
commands.map(command => {
var name = (isPlainObject(command) ? command.name || "" : command).toLowerCase(),
text = messages[name];
if (!name && !(isPlainObject(command) && command.template)) {
throw new Error("Commands should have name specified");
}
command = extend({}, defaultCommands[name], {
name: name,
text: (defaultCommands[name] || {}).text || text || capitalize(name),
type: command.template ? null : "button"
}, command);
if (name === "search") {
items.push({ type: "spacer" });
command.template = command.template({ message: command.text || messages.search });
}
if (command.imageClass) {
command.spriteCssClass = command.imageClass;
command.iconClass = command.imageClass;
}
if (that._commandByName(name)) {
if (!command.attributes) {
command.attributes = {};
}
command.attributes["data-command"] = name;
command.click = (e) => {
e.event.preventDefault();
e.event.stopPropagation();
that._commandClick({
currentTarget: e.target
});
};
}
if (command.className) {
if (!command.attributes) {
command.attributes = {};
}
command.attributes["class"] = command.className;
}
items.push(command);
});
return items;
},
_toolbar: function() {
var options = this.options.toolbar;
var toolbar = this.toolbar;
if (!options) {
return;
}
if (Array.isArray(options)) {
toolbar.kendoToolBar({
size: "medium",
navigateOnTab: !this.options.navigatable,
items: this._processToolbarItems(options)
});
} else if (isPlainObject(options)) {
toolbar.kendoToolBar({
size: "medium",
navigateOnTab: !this.options.navigatable,
items: this._processToolbarItems(options.items || []),
overflow: options.overflow
});
}
else {
toolbar.append(kendo.template(options)({}));
}
},
_initContextMenu: function() {
var that = this,
options = that.options,
tbodyContextMenu = isPlainObject(options.contextMenu) && isArray(options.contextMenu.body) ? { items: options.contextMenu.body } : { items: defaultBodyContextMenu },
theadContextMenu = isPlainObject(options.contextMenu) && isArray(options.contextMenu.head) ? { items: options.contextMenu.head } : { items: defaultHeadContextMenu };
var mainOptions = isPlainObject(options.contextMenu) ? options.contextMenu : {};
tbodyContextMenu = extend({}, {
messages: options.messages,
target: that.tbody,
filter: ".k-table-td",
action: that._action.bind(that),
states: that._buildStates()
}, mainOptions, tbodyContextMenu);
theadContextMenu = extend({}, {
messages: options.messages,
target: that.thead,
filter: ".k-table-th",
action: that._action.bind(that),
states: that._buildStates()
}, mainOptions, theadContextMenu);
that.tbodyContextMenu = new ui.treelist.ContextMenu("<ul></ul>", tbodyContextMenu);
that.theadContextMenu = new ui.treelist.ContextMenu("<ul></ul>", theadContextMenu);
},
_buildStates: function() {
var that = this;
return {
isEditable: that.options.editable,
isSelectable: that.options.selectable,
isMultiRowSelectionEnabled: that.options.selectable === "multiple, row",
isSortable: that.options.sortable && that.options.hasHeader,
alwaysDisabled: false,
hasSelection: () => (this.select() ? this.select().length > 0 : false),
isSorted: () => !(this.dataSource.sort() ? this.dataSource.sort().length > 0 : false),
isExpandable: (target) => {
let dataItem = this.dataItem(target);
return (dataItem && dataItem.hasChildren && !dataItem.expanded);
},
isCollapsible: (target) => {
let dataItem = this.dataItem(target);
return (dataItem && dataItem.hasChildren && dataItem.expanded);
}
};
},
_action: function(args) {
var commandName = args.command,
commandOptions = extend({ treelist: this }, args.options),
command = new ui.treelist.commands[commandName](commandOptions);
return command.exec();
},
_lockedColumns: function() {
return grep(this.columns, is("locked"));
},
_nonLockedColumns: function() {
return grep(this.columns, not(is("locked")));
},
_templateColumns: function() {
return grep(this.columns, is("template"));
},
_render: function(options) {
var that = this;
options = options || {};
options = that._renderOptions(options);
var messages = this.options.messages;
var pageable = that._isPageable();
var dataSource = that.dataSource;
var maps = { children: (options.filteredChildrenMap || options.childrenMap), ids: options.idsMap };
var dataMaps = pageable ? (maps && maps.children && maps.ids ? maps : dataSource._initDataMaps(dataSource._getData())) : {};
var childrenMap = dataMaps.children;
var idsMap = dataMaps.ids;
options.childrenMap = childrenMap;
options.idsMap = idsMap;
var data = that._dataToRender(options);
var level = that._renderedModelLevel(data[0], options);
var uidAttr = kendo.attr("uid");
var hasFooterTemplate;
var selected = this.select().removeClass("k-selected").map(function(_, row) {
return $(row).attr(uidAttr);
});
var viewChildrenMap;
this._absoluteIndex = 0;
that._clearRenderMap();
if (options.error) {
// root-level error message
this._showStatus(kendo.template(
({ messages, buttonClass }) =>
`${encode(messages.requestFailed)} ` +
`<button class='${buttonClass} k-button-md k-rounded-md k-button-solid k-button-solid-base'><span class='k-button-text'>${encode(messages.retry)}</span></button>`
)({
buttonClass: [classNames.button, classNames.retry].join(" "),
messages: messages
}));
} else if (!data.length) {
// no rows message
this._hideStatus();
this._showNoRecordsTemplate();
} else {
if (pageable) {
viewChildrenMap = that._viewChildrenMap(options);
}
// render rows
this._hideStatus();
hasFooterTemplate = this._hasFooterTemplate();
that._renderRows(options, data, leafColumns(nonLockedColumns(this.columns)), selected, childrenMap, viewChildrenMap, hasFooterTemplate);
if (this._hasLockedColumns) {
this._absoluteIndex = 0;
this._lockedContentTree.render(this._trs({
columns: leafColumns(lockedColumns(this.columns)),
editedColumn: options.editedColumn,
editedColumnIndex: options.editedColumnIndex,
aggregates: options.aggregates,
selected: selected,
data: data,
childrenMap: childrenMap,
viewChildrenMap: viewChildrenMap,
hasFooterTemplate: hasFooterTemplate,
visible: true,
level: level,
isLockedTable: true
}));
}
}
if (this._touchScroller) {
this._touchScroller.contentResized();
}
this.items().filter(function() {
return $.inArray($(this).attr(uidAttr), selected) >= 0;
})
.addClass("k-selected");
this._syncLockedContentHeight();
that._togglePagerVisibility();
that._setExpanderElement();
},
_renderRows: function(options, data, columns, selected, childrenMap, viewChildrenMap, hasFooterTemplate) {
this._contentTree.render(this._trs({
columns: columns,
editedColumn: options.editedColumn,
editedColumnIndex: options.editedColumnIndex,
aggregates: options.aggregates,
selected: selected,
data: data,
childrenMap: childrenMap,
viewChildrenMap: viewChildrenMap,
hasFooterTemplate: hasFooterTemplate,
visible: true,
level: 0
}));
},
_setExpanderElement: function() {
var that = this,
hiddenDivClass = 'k-grid-content-expander',
hiddenDiv = '<div class="' + hiddenDivClass + '"></div>',
expander;
if (that.options.scrollable && that.wrapper.is(":visible")) {
expander = that.table.parent().children('.' + hiddenDivClass);
if (!that.dataSource || !that.dataSource.view().length) {
if (!expander[0]) {
expander = $(hiddenDiv).appendTo(that.table.parent());
}
if (that.thead) {
expander.width(that.thead.width());
}
} else if (expander[0]) {
expander.remove();
}
}
},
_renderProgress: function(toggle) {
kendo.ui.progress(this.wrapper, toggle);
},
_renderOptions: function(options) {
options = options || {};
var that = this;
var dataMaps = that.dataSource._getDataMaps();
var filter = that.dataSource.filter();
if (that._isPageable()) {
options.childrenMap = dataMaps.children;
options.idsMap = dataMaps.ids;
if (filter) {
options.filteredChildrenMap = dataMaps.filteredChildren;
}
}
return options;
},
_renderedModelLevel: function(model, options) {
return !this._isPageable() ? 0 : this.dataSource._pageableModelLevel(model, options);
},
_viewChildrenMap: function(options) {
var that = this;
var dataSource = that.dataSource;
var viewChildrenMap = dataSource.childrenMap(dataSource.view());
var idField = dataSource._modelIdField();
var parentsNotInView = dataSource._parentNodesNotInView();
var parentNotInView;
var parentNotInViewId;
var parents;
var parent;
var parentId;
var child;
var childId;
var parentsCopy;
that._clearRenderMap();
for (var i = 0; i < parentsNotInView.length; i++) {
parentNotInView = parentsNotInView[i];
parentNotInViewId = parentNotInView[idField];
that._markNodeAsNonRenderable(parentNotInViewId);
viewChildrenMap[parentNotInViewId] = viewChildrenMap[parentNotInViewId] || [];
parents = dataSource._parentNodes(parentNotInView);
// copy the items to avoid mutating the original collection
parentsCopy = parents.slice();
parentsCopy.push(parentNotInView);
for (var parentIndex = 0; parentIndex < parentsCopy.length - 1; parentIndex++) {
parent = parentsCopy[parentIndex];
parentId = parent[idField];
that._markNodeAsNonRenderable(parentId);
viewChildrenMap[parentId] = viewChildrenMap[parentId] || [];
child = parentsCopy[parentIndex + 1];
childId = child[idField];
that._markNodeAsNonRenderable(childId);
viewChildrenMap[childId] = viewChildrenMap[childId] || [];
if (viewChildrenMap[parentId].indexOf(child) === -1) {
viewChildrenMap[parentId].unshift(child);
}
}
}
return viewChildrenMap;
},
_clearRenderMap: function() {
this._skipRenderingMap = {};
},
_dataToRender: function(options) {
var that = this;
if (that._isPageable()) {
return that.dataSource._pageableRootNodes(options);
}
return that.dataSource.rootNodes();
},
_markNodeAsNonRenderable: function(nodeId) {
this._skipRenderingMap[nodeId] = true;
},
_adjustRowsHeight: function(table1, table2) {
if (!this._hasLockedColumns) {
return;
}
var rows = table1[0].rows;
var length = rows.length;
var idx;
var rows2 = table2[0].rows;
var containers = table1.add(table2);
var containersLength = containers.length;
var heights = [];
for (idx = 0; idx < length; idx++) {
if (!rows2[idx]) {
break;
}
if (rows[idx].style.height) {
rows[idx].style.height = rows2[idx].style.height = "";
}
}
for (idx = 0; idx < length; idx++) {
if (!rows2[idx]) {
break;
}
var offsetHeight1 = rows[idx].offsetHeight;
var offsetHeight2 = rows2[idx].offsetHeight;
var height = 0;
if (offsetHeight1 > offsetHeight2) {
height = offsetHeight1;
} else if (offsetHeight1 < offsetHeight2) {
height = offsetHeight2;
}
heights.push(height);
}
for (idx = 0; idx < containersLength; idx++) {
containers[idx].style.display = "none";
}
for (idx = 0; idx < length; idx++) {
if (heights[idx]) {
//add one to resolve row misalignment in IE
rows[idx].style.height = rows2[idx].style.height = (heights[idx] + 1) + "px";
}
}
for (idx = 0; idx < containersLength; idx++) {
containers[idx].style.display = "";
}
},
_ths: function(columns, rowSpan) {
var ths = [];
var column, title, children, cellClasses, attr, headerContent;
var index;
var leafs;
for (var i = 0, length = columns.length; i < length; i++) {
column = columns[i];
children = [];
cellClasses = [classNames.header];
if (column.selectable) {
leafs = leafColumns(columns);
index = inArray(column, leafs);
attr = {
scope: "col",
role: "columnheader",
className: cellClasses.join(" ")
};
if (column.headerTemplate) {
title = column.headerTemplate({});
}
title = column.headerTemplate ? title : kendo.template(() => SELECTCOLUMNHEADERTMPL)({});
if (rowSpan && !column.colSpan) {
attr.rowSpan = rowSpan;
}
if (index > -1) {
attr[kendo.attr("index")] = index;
}
children.push(kendoHtmlElement(title));
ths.push(kendoDomElement("th", $.extend(true, {}, attr, column.headerAttributes), children));
continue;
}
if (column.headerTemplate) {
title = column.headerTemplate({});
} else {
title = column.title || column.field || "";
}
if (column.headerTemplate) {
headerContent = kendoHtmlElement(title);
} else {
headerContent = kendoTextElement(title);
}
if (this.options.sortable) {
if (!column.draggable) {
children.push(kendoDomElement("span", { className: classNames.headerCellInner }, [
kendoDomElement("span", { className: classNames.link }, [
kendoDomElement("span", { className: classNames.columnTitle }, [
headerContent
])
])
]));
}
} else {
children.push(headerContent);
}
attr = {
"data-field": column.field,
"data-title": column.title,
"style": column.hidden === true ? { "display": "none" } : {},
className: cellClasses.join(" "),
"role": "columnheader"
};
if (this.options.sortable && column.sortable !== false) {
let sortableTitle = `${column.title || column.field}. ${this.options.messages.sortHeader}`;
attr["aria-label"] = sortableTitle;
attr["title"] = sortableTitle;
}
if (!column.columns) {
attr.rowSpan = rowSpan ? rowSpan : 1;
}
if (column.headerAttributes) {
if (column.headerAttributes.colSpan === 1) {
delete column.headerAttributes.colSpan;
}
if (column.headerAttributes["class"]) {
attr.className += " " + column.headerAttributes["class"];
}
}
if (column["data-index"] > -1) {
attr["data-index"] = column["data-index"];
}
let headerAttributesCopy = { ...column.headerAttributes };
delete headerAttributesCopy["class"];
attr = extend(true, {}, attr, headerAttributesCopy);
ths.push(kendoDomElement("th", attr, children));
}
return ths;
},
_cols: function(columns) {
var cols = [];
var width, attr;
for (var i = 0; i < columns.length; i++) {
if (columns[i].hidden === true) {
continue;
}
width = columns[i].width;
attr = {};
if (width && parseInt(width, 10) !== 0) {
attr.style = {
width: typeof width === "string" ? width : width + "px"
};
}
if (columns[i].draggable) {
attr.class = "k-drag-col";
}
cols.push(kendoDomElement("col", attr));
}
return cols;
},
_clearColsCache: function() {
this._headerColsTree.render([]);
if (this.options.scrollable) {
this._contentColsTree.render([]);
}
if (this._hasLockedColumns) {
this._lockedHeaderColsTree.render([]);
this._lockedContentColsTree.render([]);
}
},
_renderCols: function() {
var columns = nonLockedColumns(this.columns);
if (this.options.hasHeader) {
this._headerColsTree.render(this._cols(leafColumns(columns)));
}
if (this.options.scrollable) {
this._contentColsTree.render(this._cols(leafColumns(columns)));
}
if (this._hasLockedColumns) {
columns = lockedColumns(this.columns);
if (this.options.hasHeader) {
this._lockedHeaderColsTree.render(this._cols(leafColumns(columns)));
}
this._lockedContentColsTree.render(this._cols(leafColumns(columns)));
if (!this.options.hasHeader) {
this._applyLockedContainersWidth();
}
}
},
_retrieveFirstColumn: function(columns, rows) {
var result = $();
if (rows.length && columns[0]) {
var column = columns[0];
while (column.columns && column.columns.length) {
column = column.columns[0];
rows = rows.filter(":not(:first)");
}
result = result.add(rows);
}
return result;
},
_updateFirstColumnClass: function() {
var that = this;
var columns = that.columns || [];
var tr = that.thead.find(">tr:not(:first, .k-filter-row)");
var rows;
columns = nonLockedColumns(columns);
rows = that._retrieveFirstColumn(columns, tr);
if (that.lockedHeader) {
tr = that.lockedHeader.find("thead>tr:not(.k-filter-row):not(:first)");
columns = lockedColumns(that.columns);
rows = rows.add(that._retrieveFirstColumn(columns, tr));
}
rows.each(function() {
var ths = $(this).find("th");
ths.removeClass("k-first");
ths.eq(0).addClass("k-first");
});
},
_updateRowSpans: function(rows) {
for (var i = rows.length - 1; i >= 0; i--) {
var included = visibleChildColumns(rows[i].cells).length > 0;
if (included) {
rows[i].rowSpan = rows.length - i;
}
}
},
_setColumnDataIndexes: function(columns) {
for (var i = 0; i < columns.length; i++) {
columns[i]["data-index"] = i;
}
},
_updateColumnCellIndex: function() {
var header;
var offset = 0;
if (this.lockedHeader) {
header = this.lockedHeader.find("thead");
offset = updateCellIndex(header, lockedColumns(this.columns));
}
updateCellIndex(this.thead, nonLockedColumns(this.columns), offset);
},
_setParentsVisibility: function(column, visible) {
var columns = this.columns;
var idx;
var parents = [];
var parent;
var predicate = visible ?
function(p) { return visibleColumns(p.columns).length && p.hidden; } :
function(p) { return !visibleColumns(p.columns).length && !p.hidden; };
if (columnParents(column, columns, parents) && parents.length) {
for (idx = parents.length - 1; idx >= 0; idx--) {
parent = parents[idx];
if (predicate(parent)) {
parent.hidden = !visible;
}
}
}
},
_prepareColumns: function(rows, columns, parentCell, parentRow, parentColumn) {
var row = parentRow || rows[rows.length - 1];
var childRow = rows[row.index + 1];
var totalColSpan = 0;
for (var idx = 0; idx < columns.length; idx++) {
var cell = $.extend({}, columns[idx], { headerAttributes: columns[idx].headerAttributes || {} });
row.cells.push(cell);
if (columns[idx].columns && columns[idx].columns.length) {
if (!childRow) {
childRow = { rowSpan: 0, cells: [], index: rows.length };
rows.push(childRow);
}
if (columns[idx].columns.length) {
cell.headerAttributes.colSpan = visibleChildColumns(columns[idx].columns).length || 1;
cell.headerAttributes["data-colspan"] = leafColumns(columns[idx].columns).length;
}
this._prepareColumns(rows, columns[idx].columns, cell, childRow, columns[idx]);
if (!cell.hidden) {
totalColSpan += cell.headerAttributes.colSpan - 1;
}
row.rowSpan = rows.length - row.index;
}
columns[idx].rowIndex = row.index;
if (parentColumn) {
columns[idx].parentColumn = parentColumn;
}
columns[idx].cellIndex = row.cells.length - 1;
}
if (parentCell) {
parentCell.headerAttributes.colSpan += totalColSpan;
}
},
_renderHeaderTree: function(tree, columns, hasMultiColumnHeaders) {
var idx;
var rows = [];
var rowsToRender = [];
var filterThs = [];
if (hasMultiColumnHeaders) {
rows = [{ rowSpan: 1, cells: [], index: 0 }];
this._prepareColumns(rows, columns);
this._updateRowSpans(rows);
for (idx = 0; idx < rows.length; idx++) {
rowsToRender.push(kendoDomElement("tr", { "role": "row", "class": "k-table-row" }, this._ths(rows[idx].cells, rows[idx].rowSpan)));
}
} else {
rowsToRender.push(kendoDomElement("tr", { "role": "row", "class": "k-table-row" }, this._ths(columns)));
}
if (this._hasFilterRow()) {
this._filterThs(columns, filterThs);
rowsToRender.push(kendoDomElement("tr", { "class": "k-filter-row k-table-row" }, filterThs));
}
tree.render(rowsToRender);
},
_renderHeader: function() {
var columns = nonLockedColumns(this.columns);
var hasMultiColumnHeaders = grep(this.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0;
this._setColumnDataIndexes(leafColumns(this.columns));
this._renderHeaderTree(this._headerTree, columns, hasMultiColumnHeaders);
if (this._hasLockedColumns) {
columns = lockedColumns(this.columns);
this._renderHeaderTree(this._lockedHeaderTree, columns, hasMultiColumnHeaders);
this._applyLockedContainersWidth();
this._syncLockedHeaderHeight();
}
this._updateFirstColumnClass();
},
_filterThs: function(columns, ths) {
var column;
var attr;
var uidAttr = kendo.attr('uid');
for (var i = 0, length = columns.length; i < length; i++) {
column = columns[i];
if (column.columns) {
this._filterThs(column.columns, ths);
}
if (column.columns && column.columns.length) {
continue;
}
attr = {
"style": column.hidden === true ? { "display": "none" } : {},
"className": "k-table-th k-header",
"title": this.options.messages.filterCellTitle,
"aria-label": this.options.messages.filterCellTitle
};
attr[uidAttr] = column.headerAttributes.id;
ths.push(kendoDomElement("th", attr));
}
},
_updateFilterThs: function(before, column, refColumn) {
var columns = leafColumns([column]);
var filterRowThs = $(this.lockedHeader).add(this.thead).find("tr.k-filter-row th");
var refIndex;
var currIndex;
var uidAttr = kendo.attr('uid');
function thIndex(ths, uid) {
for (var i = 0; i < ths.length; i++) {
if (ths.eq(i).attr(uidAttr) === uid) {
return i;
}
}
}
for (var i = columns.length - 1; i >= 0; i--) {
column = columns[i];
currIndex = thIndex(filterRowThs, column.headerAttributes.id);
refIndex = thIndex(filterRowThs, refColumn.headerAttributes.id);
filterRowThs.eq(currIndex)[before ? "insertBefore" : "insertAfter"](filterRowThs.eq(refIndex));
}
},
_applyLockedContainersWidth: function() {
if (!this._hasLockedColumns) {
return;
}
var lockedWidth = this.options.hasHeader ?
columnsWidth(this.lockedHeader.find(">table>colgroup>col")) :
columnsWidth(this.lockedTable.find(">colgroup>col"));
var headerTable = this.options.hasHeader ? this.thead.parent() : this.tbody.parent();
var nonLockedWidth = columnsWidth(headerTable.find(">colgroup>col"));
var wrapperWidth = this.wrapper[0].clientWidth;
var scrollbar = kendo.support.scrollbar();
if (lockedWidth >= wrapperWidth) {
lockedWidth = wrapperWidth - 3 * scrollbar;
}
this.lockedHeader
.add(this.lockedContent)
.width(lockedWidth);
headerTable.add(this.table).width(nonLockedWidth);
var width = wrapperWidth - lockedWidth;
this.content.width(width - 1);
headerTable.parent().width(width - scrollbar - 2);
},
_generateRowOptions: function(model, attr, pageable, options, level, hasChildren) {
var that = this;
var rowOptions = {
model: model,
attr: attr,
level: pageable ? that._renderedModelLevel(model, options) : level,
editedColumn: options.editedColumn,
editedColumnIndex: options.editedColumnIndex,
hasChildren: hasChildren,
visible: options.visible,
isAlt: this._absoluteIndex % 2 === 0
};
return rowOptions;
},
_renderRow: function(rowOptions, columns, renderer) {
return this._tds(rowOptions, columns, renderer);
},
_trs: function(options) {
var that = this;
var model, attr, className, hasChildren, childNodes, i, length;
var modelId;
var rows = [];
var level = options.level;
var data = options.data;
var dataSource = this.dataSource;
var aggregates = dataSource.aggregates() || {};
var idField = dataSource._modelIdField();
var parentIdField = dataSource._modelParentIdField();
var columns = options.columns;
var pageable = that._isPageable();
var isLockedTable = options.isLockedTable;
var childrenMap = options.childrenMap || dataSource.childrenMap(dataSource._getData());
for (i = 0, length = data.length; i < length; i++) {
className = ["k-table-row"];
model = data[i];
modelId = model[idField];
childNodes = pageable ? childrenMap[modelId] : (model.loaded() ? dataSource.childNodes(model) : []);
hasChildren = childNodes && childNodes.length;
attr = { "role": "row" };
attr[kendo.attr("uid")] = model.uid;
if (!isLockedTable && hasChildren) {
attr[ARIA_EXPANDED] = !!model.expanded;
}
if (options.visible) {
if (!pageable || (pageable && !that._skipRenderingMap[modelId])) {
if (this._absoluteIndex % 2 !== 0) {
className.push(classNames.alt);
}
this._absoluteIndex++;
}
} else {
attr.style = { display: "none" };
}
if ($.inArray(model.uid, options.selected) >= 0) {
className.push(classNames.selected);
}
if (model._edit) {
className.push("k-grid-edit-row");
}
attr.className = className.join(" ");
if (!that._skipRenderingMap[modelId]) {
var row;
var rowOptions = that._generateRowOptions(model, attr, pageable, options, level, hasChildren);
if (that.options.rowTemplate) {
row = this._trFromTemplate(rowOptions);
} else {
row = this._renderRow(rowOptions, columns, this._td.bind(this));
}
rows.push(row);
}
if (hasChildren && (that.options.renderAllRows || !!model.expanded)) {
if (pageable) {
// render the child nodes in the paged view only
childNodes = (options.viewChildrenMap || {})[modelId] || [];
}
if (childNodes.length === 0) {
continue;
}
rows = rows.concat(this._trs({
columns: columns,
editedColumn: options.editedColumn,
editedColumnIndex: options.editedColumnIndex,
aggregates: aggregates,
selected: options.selected,
visible: pageable ? options.visible : (options.visible && !!model.expanded),
data: childNodes,
childrenMap: options.childrenMap || childrenMap,
hasFooterTemplate: options.hasFooterTemplate,
viewChildrenMap: options.viewChildrenMap,
level: level + 1,
isLockedTable: options.isLockedTable
}));
}
}
if (options.hasFooterTemplate && model) {
attr = {
className: classNames.footerTemplate + " k-table-row",
"data-parentId": model[parentIdField]
};
if (!options.visible) {
attr.style = { display: "none" };
}
rows.push(this._tds({
model: aggregates[model[parentIdField]],
attr: attr,
level: level,
editedColumn: options.editedColumn,
editedColumnIndex: options.editedColumnIndex
}, columns, this._footerId));
}
return rows;
},
_trFromTemplate: function(options) {
var rowTemplate = this.options.rowTemplate;
var altRowTemplate = this.options.altRowTemplate;
var row;
var template;
altRowTemplate = altRowTemplate ? altRowTemplate : rowTemplate;
if (!kendo.isFunction(rowTemplate)) {
rowTemplate = kendo.template(rowTemplate);
}
if (!kendo.isFunction(altRowTemplate)) {
altRowTemplate = kendo.template(altRowTemplate);
}
if (this._absoluteIndex % 2 !== 0) {
template = rowTemplate(options);
} else {
template = altRowTemplate(options);
}
if (!$(template).length) {
return kendoTextElement(template);
}
row = this.parseRowTemplate($(template)[0], options);
return row;
},
parseRowTemplate: function(element, options) {
var nodeName = element.nodeName.toLocaleLowerCase();
var childNodes = element.childNodes;
var children = [];
var currElement;
var attributes;
attributes = this.parseAttributes(element);
for (var i = 0; i < childNodes.length; i++) {
if (!/\S/.test(childNodes[i].nodeValue)) {
continue;
}
if (childNodes[i].nodeName.toLocaleLowerCase() === "td") {
children.push(this._createCellElement(childNodes[i]));
}
}
if (options && !options.visible) {
attributes.style = attributes.style || {};
attributes.style = $.extend(true, attributes.style, { display: "none" });
}
if (this._isTextNode(nodeName)) {
currElement = kendoTextElement(element.nodeValue);
} else {
currElement = kendoDomElement(nodeName, attributes, children);
}
return currElement;
},
_createCellElement: function(element) {
var attributes = this.parseAttributes(element);
var spaceElements = $(element).find('.' + classNames.iconHidden).remove();
var iconElement = $(element).find(ICON_EXPAND_COLLAPSE_SELECTOR).remove()[0];
var children = [];
for (var i = 0; i < spaceElements.length; i++) {
children.push(kendoDomElement("span", this.parseAttributes(spaceElements[i])));
}
if (iconElement) {
children.push(kendoHtmlElement(iconElement.outerHTML, true));
}
children.push(kendoHtmlElement($(element).html()));
return kendoDomElement("td", attributes, children);
},
parseAttributes: function(element) {
if (this._isTextNode(element.nodeName)) {
return null;
}
element = $(element)[0];
var attributes = element.attributes;
var length = attributes.length;
var result = {};
for (var i = 0; i < length; i++) {
result[attributes[i].name] = attributes[i].value;
}
return result;
},
_isTextNode: function(nodeName) {
return nodeName.indexOf('text') >= 0;
},
_footerId: function(options) {
var content = [];
var column = options.column;
var template = options.column.footerTemplate || $.noop;
var aggregates = options.model[column.field] || {};
var attr = {
"role": "gridcell",
"class": "k-table-td",
"style": column.hidden === true ? { "display": "none" } : {}
};
if (column.expandable) {
content = content.concat(createPlaceholders({
level: options.level + 1,
className: classNames.iconPlaceHolder
}));
}
if (column.attributes) {
extend(true, attr, column.attributes, {
"style": column.hidden === true ? { "display": "none" } : {}
});
}
content.push(kendoHtmlElement(template(aggregates) || ""));
return kendoDomElement("td", attr, content);
},
_hasFooterTemplate: function() {
return !!grep(leafColumns(this.columns), function(c) {
return c.footerTemplate;
}).length;
},
_tds: function(options, columns, renderer) {
var children = [];
var column;
var editedColumnField = (options.editedColumn || {}).field;
var incellEditing = this._isIncellEditable();
var length = columns.length;
for (var i = 0; i < length; i++) {
column = columns[i];
var col = renderer({
model: options.model,
column: column,
editColumn: !incellEditing || (incellEditing && column.field === editedColumnField && options.editedColumnIndex === i),
level: options.level
});
children.push(col);
}
return kendoDomElement("tr", options.attr, children);
},
_td: function(options) {
var children = [];
var model = options.model;
var column = options.column;
var iconType = kendo.defaults.iconType;
var iconClass;
var attr = {
"role": "gridcell",
"class": "k-table-td",
"style": column.hidden === true ? { "display": "none" } : {}
};
var incellEditing = this._isIncellEditable();
var columnHasEditCommand = false;
if (column.attributes) {
extend(true, attr, column.attributes);
}
if (!!column.headerAttributes && !!column.headerAttributes.id) {
attr["aria-describedby"] = column.headerAttributes.id;
}
if (model._edit && column.field && options.editColumn && (incellEditing || (!incellEditing && isColumnEditable(column, model)))) {
attr[kendo.attr("container-for")] = column.field;
if (incellEditing) {
if (attr.className && attr.className.indexOf(classNames.editCell) !== -1) {
attr.className += " k-table-td" + classNames.editCell;
} else if (!attr.className) {
attr.className = "k-table-td " + classNames.editCell;
}
}
} else {
if (column.expandable) {
children = createPlaceholders({ level: options.level, className: classNames.iconPlaceHolder });
if (model.hasChildren) {
attr.ariaExpanded = model.expanded;
iconClass = model.expanded ? classNames.iconCollapse : classNames.iconExpand;
} else {
iconClass = classNames.iconPlaceHolder;
}
if (model._error) {
iconClass = classNames.refresh;
} else if (!model.loaded() && model.expanded) {
iconClass = "loading";
attr["aria-busy"] = true;
}
// The true flag at the end specifies that the element reference should be replaced instead of being removed and added back to the DOM tree. Check the HtmlNode.render function in kendo.dom.js.
children.push(kendoHtmlElement(kendo.ui.icon($(`<span ref-treelist-expand-collapse-icon ${iconClass === classNames.iconPlaceHolder ? "ref-blank-icon" : ''} class="k-treelist-toggle ${iconClass === classNames.iconPlaceHolder ? '' : iconClass === 'loading' ? 'k-i-loading' : ''}"></span>`), { icon: iconClass, type: iconType }), true));
attr.style["white-space"] = "nowrap";
}
if (isDirtyColumn(column, model)) {
if (attr.className) {
attr.className += classNames.dirtyCell;
} else if (!attr.className) {
attr.className = classNames.dirtyCell;
}
}
if (column.draggable) {
attr["class"] += " k-drag-cell k-touch-action-none";
attr["ref-treelist-drag-cell"] = true;
if (typeof attr[ARIA_LABEL] === "undefined") {
attr[ARIA_LABEL] = this.options.messages.dragHandleLabel;
}
attr.style.cursor = "move";
}
if (column.command) {
if (attr.className && attr.className.indexOf("k-command-cell") !== -1) {
attr.className += " k-command-cell";
} else if (!attr.className) {
attr.className = "k-command-cell";
}
columnHasEditCommand = grep(column.command, function(command) {
return command === EDIT || command.name === EDIT;
}).length > 0;
if (model._edit && !this._isIncellEditable() && columnHasEditCommand) {
children = this._buildCommands(["update", "canceledit"]);
} else {
children = this._buildCommands(column.command);
}
} else {
children.push(this._cellContent(column, model));
}
attr.className = [attr["class"], attr.className].join(" ").trim();
}
return kendoDomElement("td", attr, children);
},
_cellContent: function(column, model) {
var that = this;
var value;
var incellEditing = that._isIncellEditable();
var dirtyIndicator;
if (column.selectable) {
return kendoHtmlElement(SELECTCOLUMNTMPL);
}
if (column.draggable) {
return kendoHtmlElement(DRAGHANDLECOLUMNTMPL());
}
if (column.template) {
value = that._evalColumnTemplate(column, model);
} else if (column.field) {
value = model.get(column.field);
dirtyIndicator = incellEditing ? column.dirtyIndicatorTemplate(model) : "";
if (value !== null && !isUndefined(value)) {
if (column.format) {
value = kendo.format(column.format, value);
}
value = dirtyIndicator + value;
} else {
value = dirtyIndicator;
}
} else if (value === null || isUndefined(value)) {
value = "";
}
if (column.template || !column.encoded) {
return kendoHtmlElement(value);
} else {
if (incellEditing) {
return kendoHtmlElement(value);
} else {
return kendoTextElement(value);
}
}
},
_evalColumnTemplate: function(column, model) {
if (this._isIncellEditable()) {
return column.dirtyCellTemplate(model);
} else {
return column.template(model);
}
},
_createDirtyColumnTemplate: function(column) {
var that = this;
var templateSettings = that._customTemplateSettings();
var templateFunction = function(data) {
return (that._dirtyIndicatorTemplate(column.field)(data) + this.columnTemplate(data));
};
return kendoTemplate(templateFunction, templateSettings).bind({ columnTemplate: column.template });
},
_createIndicatorTemplate: function(column) {
var dirtyIndicatorTemplate = this._dirtyIndicatorTemplate(column.field);
return kendoTemplate(dirtyIndicatorTemplate);
},
_dirtyIndicatorTemplate: function(field) {
var that = this;
var templateSettings = that._customTemplateSettings();
var paramName = templateSettings.paramName;
if (field && paramName) {
return ({ dirty, dirtyFields }) => (dirty && dirtyFields && dirtyFields[field] ? '<span class="k-dirty"></span>' : '');
}
return () => "";
},
_customTemplateSettings: function() {
return extend({}, kendo.Template, this.options.templateSettings);
},
_buildCommands: function(commands, skipCommandClass) {
var i, result = [];
for (i = 0; i < commands.length; i++) {
result.push(this._handleCommand(commands[i], skipCommandClass));
}
return result;
},
_handleCommand: function(command, skipCommandClass) {
var name = (command.name || command).toLowerCase();
var text = this.options.messages.commands[name];
command = extend({}, defaultCommands[name], { text: text }, command);
if (command.template) {
return kendoHtmlElement(kendo.template(command.template)({ message: command.text || this.options.messages.commands.search }));
} else {
return this._button(command, name, command.icon, skipCommandClass);
}
},
_button: function(command, name, icon, skipCommandClass) {
if (command.className && command.className.indexOf("k-primary") > -1) {
command.className = command.className.replace("k-primary", "k-button-solid-primary");
}
if (!command.className || command.className.indexOf("k-button-solid-primary") === -1) {
command.className = (command.className || "") + " k-button-solid-base";
}
if (skipCommandClass && command.className) {
let classes = command.className.split(" ");
command.className = classes.filter(c => c.indexOf("command") === -1).join(" ");
}
let buttonHTML = '<button data-command="' + name + '" class="' + command.className + '">' + (command.text || (command.text === "" ? "" : command.name)) + '</button>';
let button = kendoHtmlElement(kendo.html.renderButton(buttonHTML, {
icon: icon,
iconClass: command.imageClass
}));
return button;
},
_positionResizeHandle: function(e) {
var th = $(e.currentTarget);
var resizeHandle = this.resizeHandle;
var position = th.position();
var left;
var rtlCorrection = 0;
var headerWrap;
var ieCorrection;
var webkitCorrection;
var firefoxCorrection;
var leftMargin;
var invisibleSpace;
var leftBorderWidth;
var scrollLeft;
var cellWidth = outerWidth(th);
var container = th.closest("div");
var button = typeof e.buttons !== "undefined" ? e.buttons : (e.which || e.button);
var indicatorWidth = this.options.columnResizeHandleWidth || 3;
var halfResizeHandle = (indicatorWidth * 3) / 2;
left = cellWidth;
if (typeof button !== "undefined" && button !== 0) {
//do not create a new resize handle if a mouse button is still pressed
//this happens during resizing or before UserEvents trigger "start"
return;
}
if (!resizeHandle) {
resizeHandle = this.resizeHandle = $(
'<div class="k-resize-handle"><div class="k-resize-handle-inner"></div></div>'
);
}
var cells = leafDataCells(th.closest("thead")).filter(":visible");
if (isRtl) {
scrollLeft = kendo.scrollLeft(container);
if (browser.mozilla || (browser.webkit && browser.version >= 85)) {
scrollLeft = scrollLeft * -1;
}
leftBorderWidth = parseFloat(container.css("borderLeftWidth"));
left = th.offset().left + scrollLeft - parseFloat(th.css("marginLeft")) - (container.offset().left + leftBorderWidth);
rtlCorrection = (left <= scrollLeft ? halfResizeHandle : 0);// when shown on first column headers are misaligned due to the width of the resize handler
headerWrap = th.closest(".k-grid-header-wrap, .k-grid-header-locked");
invisibleSpace = headerWrap[0].scrollWidth - headerWrap[0].offsetWidth; // the difference between the entire width and the visible area
leftMargin = parseFloat(headerWrap.css("marginLeft"));
ieCorrection = browser.msie ? 2 * kendo.scrollLeft(headerWrap) + leftBorderWidth - leftMargin - rtlCorrection : 0;
webkitCorrection = browser.webkit && (browser.version < 85) ? (invisibleSpace - rtlCorrection - leftMargin + leftBorderWidth) : -rtlCorrection; //margin left is added due to a margin that avoids double borders
firefoxCorrection = browser.mozilla ? leftBorderWidth - leftMargin - rtlCorrection : 0;
left -= webkitCorrection + firefoxCorrection + ieCorrection;
} else {
for (var idx = 0; idx < cells.length; idx++) {
if (cells[idx] == th[0]) {
break;
}
left += cells[idx].offsetWidth;
}
}
container.append(resizeHandle);
resizeHandle
.show()
.css({
top: position.top,
left: left - halfResizeHandle,
height: outerHeight(th),
width: indicatorWidth * 3
})
.data("th", th);
var that = this;
resizeHandle.off("dblclick" + NS).on("dblclick" + NS, function() {
//TODO handle frozen columns index
var index = th.index();
if ($.contains(that.thead[0], th[0])) {
index += grep(that.columns, function(val) { return val.locked && !val.hidden; }).length;
}
that.autoFitColumn(index);
});
},
autoFitColumn: function(column) {
var that = this,
options = that.options,
columns = that.columns,
index,
th,
headerTable,
isLocked,
visibleLocked = that.lockedHeader ? leafDataCells(that.lockedHeader.find(">table>thead")).filter(isCellVisible).length : 0,
col;
// retrieve the column object, depending on the method argument
if (typeof column == "number") {
column = columns[column];
} else if (isPlainObject(column)) {
column = grep(columns, function(item) {
return item === column;
})[0];
} else {
column = grep(columns, function(item) {
return item.field === column;
})[0];
}
if (!column || column.hidden) {
return;
}
index = inArray(column, columns);
isLocked = column.locked;
if (isLocked) {
headerTable = that.lockedHeader.children("table");
} else {
headerTable = that.thead.parent();
}
th = headerTable.find("[data-index='" + index + "']");
var contentTable = isLocked ? that.lockedTable : that.table,
footer = that.footer || $();
if (that.footer && that.lockedContent) {
footer = isLocked ? that.footer.children(".k-grid-footer-locked") : that.footer.children(".k-grid-footer-wrap");
}
var footerTable = footer.find("table").first();
if (that.lockedHeader && visibleLocked >= index && !isLocked) {
index -= visibleLocked;
}
// adjust column index, depending on previous hidden columns
for (var j = 0; j < columns.length; j++) {
if (columns[j] === column) {
break;
} else {
if (columns[j].hidden) {
index--;
}
}
}
// get col elements
if (options.scrollable) {
col = headerTable.find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index)
.add(contentTable.children("colgroup").find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index))
.add(footerTable.find("colgroup").find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index));
} else {
col = contentTable.children("colgroup").find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index);
}
var tables = headerTable.add(contentTable).add(footerTable);
var oldColumnWidth = outerWidth(th);
// reset the table and autofitted column widths
// if scrolling is disabled, we need some additional repainting of the table
col.width("");
tables.css("table-layout", "fixed");
col.width("auto");
tables.addClass("k-autofitting");
tables.css("table-layout", "");
var newColumnWidth = Math.ceil(
Math.max(
outerWidth(th),
outerWidth(contentTable.find("tr").eq(0).children("td:visible").eq(index)),
outerWidth(footerTable.find("tr").eq(0).children("td:visible").eq(index))
));
col.width(newColumnWidth);
column.width = newColumnWidth;
// if all visible columns have widths, the table needs a pixel width as well
if (options.scrollable) {
var cols = headerTable.find("col"),
colWidth,
totalWidth = 0;
for (var idx = 0, length = cols.length; idx < length; idx += 1) {
colWidth = cols[idx].style.width;
if (colWidth && colWidth.indexOf("%") == -1) {
totalWidth += parseInt(colWidth, 10);
} else {
totalWidth = 0;
break;
}
}
if (totalWidth) {
tables.each(function() {
this.style.width = totalWidth + "px";
});
}
}
tables.removeClass("k-autofitting");
that.trigger(COLUMNRESIZE, {
column: column,
oldWidth: oldColumnWidth,
newWidth: newColumnWidth
});
that._applyLockedContainersWidth();
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
},
_adjustLockedHorizontalScrollBar: function() {
var table = this.table,
content = table.parent();
var scrollbar = table[0].offsetWidth > content[0].clientWidth ? kendo.support.scrollbar() : 0;
this.lockedContent.height(outerHeight(content) - scrollbar);
},
_syncLockedContentHeight: function() {
if (this.lockedTable) {
if (!this._touchScroller) {
this._adjustLockedHorizontalScrollBar();
}
this._adjustRowsHeight(this.table, this.lockedTable);
this._syncLockedScroll();
}
},
_syncLockedHeaderHeight: function() {
if (this.lockedHeader) {
var lockedTable = this.lockedHeader.children("table");
var table = this.thead.parent();
this._adjustRowsHeight(lockedTable, table);
syncTableHeight(lockedTable, table);
}
},
_syncLockedScroll: function() {
if (!this.options.scrollable) {
return;
}
this.lockedContent[0].scrollTop = this.content[0].scrollTop;
},
_resizable: function() {
if (!this.options.resizable) {
return;
}
if (this.resizable) {
this.resizable.destroy();
}
var treelist = this;
$(this.lockedHeader).find("thead").add(this.thead)
.on("mousemove" + NS, "tr:not(.k-filter-row) > th", this._positionResizeHandle.bind(this));
this.resizable = new kendo.ui.Resizable(this.wrapper, {
handle: ".k-resize-handle",
start: function(e) {
var th = $(e.currentTarget).data("th");
var index = $.inArray(th[0], leafDataCells(th.closest("thead")).filter(":visible"));
var header, contentTable;
treelist.wrapper.addClass("k-grid-column-resizing");
if (treelist.lockedHeader && $.contains(treelist.lockedHeader[0], th[0])) {
header = treelist.lockedHeader;
contentTable = treelist.lockedTable;
} else {
header = treelist.thead.parent();
contentTable = treelist.table;
}
this.col = contentTable.children("colgroup").find("col").eq(index)
.add(header.find("col").eq(index));
this.th = th;
this.startLocation = e.x.location;
this.columnWidth = outerWidth(th);
this.table = this.col.closest("table");
this.totalWidth = this.table.width();
},
resize: function(e) {
var rtlModifier = isRtl ? -1 : 1;
var minColumnWidth = 11;
var delta = (e.x.location * rtlModifier) - (this.startLocation * rtlModifier);
if (this.columnWidth + delta < minColumnWidth) {
delta = minColumnWidth - this.columnWidth;
}
this.table.width(this.totalWidth + delta);
this.col.width(this.columnWidth + delta);
},
resizeend: function() {
treelist.wrapper.removeClass("k-grid-column-resizing");
var field = this.th.attr("data-field");
var column = grep(leafColumns(treelist.columns), function(c) {
return c.field == field;
});
var newWidth = Math.floor(outerWidth(this.th));
column[0].width = newWidth;
treelist._resize();
treelist._syncLockedContentHeight();
treelist._syncLockedHeaderHeight();
treelist.trigger(COLUMNRESIZE, {
column: column,
oldWidth: this.columnWidth,
newWidth: newWidth
});
this.table = this.col = this.th = null;
}
});
},
_sortable: function() {
var columns;
var column;
var sortableInstance;
var cells;
var cell, idx, length;
var sortable = this.options.sortable;
var hasMultiColumnHeaders = grep(this.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0;
var sortHandler = this._sort.bind(this);
if (!sortable) {
return;
}
if (hasMultiColumnHeaders) {
if (this.lockedHeader) {
cells = sortCells(leafDataCells(this.lockedHeader.find(">table>thead")).add(leafDataCells(this.thead)));
} else {
cells = leafDataCells(this.thead);
}
} else {
cells = $(this.lockedHeader).add(this.thead).find("tr:not(.k-filter-row) th");
}
columns = leafColumns(this.columns);
for (idx = 0, length = cells.length; idx < length; idx++) {
column = columns[idx];
if (column.sortable !== false && !column.command && !column.draggable && column.field && !column.selectable) {
cell = cells.eq(idx);
sortableInstance = cell.data("kendoColumnSorter");
if (sortableInstance) {
sortableInstance.destroy();
}
cell.kendoColumnSorter(
extend({}, sortable, column.sortable, {
dataSource: this.dataSource,
change: sortHandler
})
);
}
}
},
_filterable: function() {
var cells;
var filterable = this.options.filterable;
var idx;
var length;
var columns;
var column;
var cell;
var filterMenuInstance;
var hasMultiColumnHeaders = grep(this.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0;
if (!filterable || this.options.columnMenu) {
return;
}
var filterInit = (function(e) {
this.trigger(FILTERMENUINIT, { field: e.field, container: e.container });
}).bind(this);
var filterOpen = (function(e) {
this.trigger(FILTERMENUOPEN, { field: e.field, container: e.container });
}).bind(this);
var filterHandler = this._filter.bind(this);
if (hasMultiColumnHeaders) {
if (this.lockedHeader) {
cells = leafDataCells(this.lockedHeader.find(">table>thead").add(this.thead));
} else {
cells = leafDataCells(this.thead);
}
} else {
cells = $(this.lockedHeader).add(this.thead).find("tr:not(.k-filter-row) th");
}
columns = leafColumns(this.columns);
if (filterable && typeof filterable.mode == STRING && filterable.mode.indexOf("menu") == -1) {
filterable = false;
}
if (!filterable) {
return;
}
for (idx = 0, length = cells.length; idx < length; idx++) {
column = columns[idx];
cell = cells.eq(idx);
filterMenuInstance = cell.data("kendoFilterMenu");
if (filterMenuInstance) {
filterMenuInstance.destroy();
}
if (column.draggable || column.command || column.filterable === false || column.selectable) {
continue;
}
cell.kendoFilterMenu(extend(true, {}, filterable, column.filterable, {
dataSource: this.dataSource,
init: filterInit,
open: filterOpen,
change: filterHandler,
appendTo: DOT + classNames.headerCellInner
}));
}
},
_filterRow: function() {
var that = this;
if (!that._hasFilterRow()) {
return;
}
var settings;
var uidAttr = kendo.attr('uid');
var columns = leafColumns(that.columns),
filterable = that.options.filterable,
filterHandler = this._filter.bind(this),
existingInstance;
for (var i = 0; i < columns.length; i++) {
var suggestDataSource,
col = columns[i],
operators = that.options.filterable.operators,
customDataSource = false,
th = this.wrapper.find('.k-grid-header .k-filter-row th[' + uidAttr + '="' + col.headerAttributes.id + '"]'),
field = col.field,
parentColumn = col.parentColumn;
delete col.parentColumn;
if (field && col.filterable !== false) {
var cellOptions = col.filterable && col.filterable.cell || {};
existingInstance = th.find('.k-filtercell').data('kendoFilterCell');
if (existingInstance) {
existingInstance.destroy();
th.empty();
}
suggestDataSource = that.options.dataSource;
if (suggestDataSource instanceof DataSource) {
suggestDataSource = that.options.dataSource.options;
}
var messages = extend(true, {}, filterable.messages);
if (col.filterable) {
extend(true, messages, col.filterable.messages);
}
if (cellOptions.enabled === false) {
th.html(" ");
continue;
}
if (cellOptions.dataSource) {
suggestDataSource = cellOptions.dataSource;
customDataSource = true;
}
if (col.filterable && col.filterable.operators) {
operators = col.filterable.operators;
}
settings = {
column: col,
dataSource: that.dataSource,
suggestDataSource: suggestDataSource,
customDataSource: customDataSource,
field: field,
messages: messages,
values: col.values,
template: cellOptions.template,
delay: cellOptions.delay,
inputWidth: cellOptions.inputWidth,
suggestionOperator: cellOptions.suggestionOperator,
minLength: cellOptions.minLength,
dataTextField: cellOptions.dataTextField,
operator: cellOptions.operator,
operators: operators,
showOperators: cellOptions.showOperators,
change: filterHandler
};
$("<span/>").attr(kendo.attr("field"), field)
.appendTo(th)
.kendoFilterCell(settings);
col.parentColumn = parentColumn;
} else {
th.html(" ");
}
}
this._filterFocusable().attr(TABINDEX, -1);
},
_hasFilterRow: function() {
var filterable = this.options.filterable;
var hasFiltering = filterable &&
typeof filterable.mode == STRING &&
filterable.mode.indexOf("row") != -1;
var columns = this.columns;
var columnsWithoutFiltering = $.grep(columns, function(col) {
return col.filterable === false;
});
if (columns.length && columnsWithoutFiltering.length == columns.length) {
hasFiltering = false;
}
return hasFiltering;
},
_change: function() {
var that = this;
var selectedValues;
if (that._checkBoxSelection) {
selectedValues = that.selectable.value();
that._uncheckCheckBoxes();
that._checkRows(selectedValues);
if (selectedValues.length && selectedValues.length === that.items().length) {
that._toggleHeaderCheckState(true);
} else {
that._toggleHeaderCheckState(false);
}
}
this.trigger(CHANGE);
},
_isLocked: function() {
return this.lockedHeader !== null;
},
_selectable: function() {
var that = this;
var selectable = this.options.selectable;
var filter;
var element = this.table;
var useAllItems;
var isLocked = that._isLocked();
var multi;
var cell;
if (selectable) {
selectable = kendo.ui.Selectable.parseOptions(selectable);
if (this._hasLockedColumns) {
element = element.add(this.lockedTable);
useAllItems = selectable.multiple && selectable.cell;
}
filter = ">tbody>tr:not(.k-footer-template)";
if (selectable.cell) {
filter = filter + ">td";
}
this.selectable = new kendo.ui.Selectable(element, {
filter: filter,
aria: true,
multiple: selectable.multiple,
change: this._change.bind(this),
useAllItems: useAllItems,
continuousItems: this._continuousItems.bind(this, filter, selectable.cell),
relatedTarget: !selectable.cell && this._hasLockedColumns ? this._selectableTarget.bind(this) : undefined$1
});
if (that.options.navigatable) {
multi = selectable.multiple;
cell = selectable.cell;
element.on("keydown" + NS, function(e) {
var current = that.current();
if (!current) {
return;
}
var target = e.target;
if (e.keyCode === keys.SPACEBAR && !e.shiftKey && $.inArray(target, element) > -1 &&
!current.is(".k-header")) {
e.preventDefault();
e.stopPropagation();
current = cell ? current : current.parent();
if (isLocked && !cell) {
current = current.add(that._relatedRow(current));
}
if (multi) {
if (!e.ctrlKey) {
that.selectable.clear();
} else {
if (current.hasClass(classNames.selected)) {
current.removeClass(classNames.selected);
that.trigger(CHANGE);
return;
}
}
} else {
that.selectable.clear();
}
if (!cell) {
that.selectable._lastActive = current;
}
that.selectable.value(current);
that.trigger(CHANGE);
} else if (!cell && ((e.shiftKey && e.keyCode == keys.LEFT) ||
(e.shiftKey && e.keyCode == keys.RIGHT) ||
(e.shiftKey && e.keyCode == keys.UP) ||
(e.shiftKey && e.keyCode == keys.DOWN) ||
(e.keyCode === keys.SPACEBAR && e.shiftKey))) {
e.preventDefault();
e.stopPropagation();
current = current.parent();
if (isLocked) {
current = current.add(that._relatedRow(current));
}
if (multi) {
if (!that.selectable._lastActive) {
that.selectable._lastActive = current;
}
that.selectable.selectRange(that.selectable._firstSelectee(), current);
} else {
that.selectable.clear();
that.selectable.value(current);
}
that.trigger(CHANGE);
}
});
}
}
},
_continuousItems: function(filter, cell) {
if (!this.lockedContent) {
return;
}
var lockedItems = $(filter, this.lockedTable);
var nonLockedItems = $(filter, this.table);
var columns = cell ? lockedColumns(this.columns).length : 1;
var nonLockedColumns = cell ? this.columns.length - columns : 1;
var result = [];
for (var idx = 0; idx < lockedItems.length; idx += columns) {
push.apply(result, lockedItems.slice(idx, idx + columns));
push.apply(result, nonLockedItems.splice(0, nonLockedColumns));
}
return result;
},
_selectableTarget: function(items) {
var related;
var result = $();
for (var idx = 0, length = items.length; idx < length; idx++) {
related = this._relatedRow(items[idx]);
if (inArray(related[0], items) < 0) {
result = result.add(related);
}
}
return result;
},
_relatedRow: function(row) {
var lockedTable = this.lockedTable;
row = $(row);
if (!lockedTable) {
return row;
}
var table = row.closest(this.table.add(this.lockedTable));
var index = table.find(">tbody>tr").index(row);
table = table[0] === this.table[0] ? lockedTable : this.table;
return table.find(">tbody>tr").eq(index);
},
select: function(value) {
var that = this;
var selectable = this.selectable;
if (that._checkBoxSelection) {
if (value) {
that._checkRows(value);
if (that.select().length === that.items().length) {
that._toggleHeaderCheckState(true);
}
}
return that.items().filter("." + SELECTED);
}
if (!selectable) {
return $();
}
if (typeof value !== "undefined") {
if (!selectable.options.multiple) {
selectable.clear();
value = value.first();
}
if (this._hasLockedColumns) {
value = value.add($.map(value, this._relatedRow.bind(this)));
}
}
return selectable.value(value);
},
clearSelection: function() {
var that = this;
if (that.selectable && !that._checkBoxSelection) {
that.selectable.clear();
}
if (that._checkBoxSelection) {
that._deselectCheckRows(that.select(), true);
return;
}
},
_uncheckCheckBoxes: function() {
var that = this;
var tables = that.table.add(that.lockedTable);
tables.find("tbody " + CHECKBOXINPUT).attr("aria-checked", false)
.prop("checked", false).attr("aria-label", "Select row");
},
_deselectCheckRows: function(items, preventChange) {
var that = this;
items = that.table.add(that.lockedTable).find(items);
if (that._isLocked()) {
items = items.add(items.map(function() {
return that._relatedRow(this);
}));
}
items.each(function() {
$(this).removeClass(SELECTED).find(CHECKBOXINPUT).attr("aria-checked", false)
.prop("checked", false).attr("aria-label", "Select row");
});
that._toggleHeaderCheckState(false);
if (!preventChange) {
that.trigger(CHANGE);
}
},
_headerCheckboxClick: function(e) {
var that = this,
checkBox = $(e.target),
checked = checkBox.prop("checked"),
parentGrid = checkBox.closest(".k-grid").getKendoTreeList();
if (that !== parentGrid) {
return;
}
if (checked) {
that.select(parentGrid.items());
} else {
that.clearSelection();
}
that.trigger(CHANGE);
},
_checkboxClick: function(e) {
var that = this,
row = $(e.target).closest("tr"),
isSelecting = !row.hasClass(SELECTED),
dataItem = that.dataItem(row),
children = [],
selector = "";
if (that !== row.closest(".k-grid").getKendoTreeList()) {
return;
}
if (that._includeChildren) {
that.dataSource.allChildNodes(dataItem, children);
for (var i = 0; i < children.length; i++) {
selector += "tr[data-uid='" + children[i].uid + "'],";
}
}
selector += "tr[data-uid='" + dataItem.uid + "']";
row = $(selector);
if (isSelecting) {
that.select(row);
that.trigger(CHANGE);
} else {
that._deselectCheckRows(row);
}
},
_checkRows: function(items) {
items.each(function() {
$(this).addClass(SELECTED).find(CHECKBOXINPUT).prop("checked", true)
.attr("aria-label", "Deselect row").attr("aria-checked", true);
});
},
_toggleHeaderCheckState: function(checked) {
var that = this;
if (checked) {
that.thead.add(that.lockedHeader).find("tr " + CHECKBOXINPUT)
.prop("checked", true).attr("aria-checked", true)
.attr("aria-label", "Deselect all rows");
} else {
that.thead.add(that.lockedHeader).find("tr " + CHECKBOXINPUT)
.prop("checked", false).attr("aria-checked", false)
.attr("aria-label", "Select all rows");
}
},
_dataSource: function(dataSource) {
var that = this;
var ds = this.dataSource;
var pageable = that.options.pageable;
if (ds) {
ds.unbind(CHANGE, this._refreshHandler);
ds.unbind(ERROR, this._errorHandler);
ds.unbind(SORT, this._sortHandler);
ds.unbind(PROGRESS, this._progressHandler);
}
this._refreshHandler = this.refresh.bind(this);
this._errorHandler = this._error.bind(this);
this._sortHandler = this._clearSortClasses.bind(this);
this._progressHandler = this._progress.bind(this);
if (isPlainObject(dataSource)) {
extend(dataSource, { table: that.table, fields: that.columns });
if (isPlainObject(pageable) && pageable.pageSize !== undefined$1) {
dataSource.pageSize = pageable.pageSize;
}
}
ds = this.dataSource = TreeListDataSource.create(dataSource);
if (pageable) {
ds._collapsedTotal = undefined$1;
}
ds.bind(CHANGE, this._refreshHandler);
ds.bind(ERROR, this._errorHandler);
ds.bind(SORT, this._sortHandler);
ds.bind(PROGRESS, this._progressHandler);
this._dataSourceFetchProxy = (function() {
this.dataSource.fetch();
}).bind(this);
},
setDataSource: function(dataSource) {
this._dataSource(dataSource);
this._sortable();
this._filterable();
this._filterRow();
this._columnMenu();
this._pageable();
this._contentTree.render([]);
if (this.options.autoBind) {
this.dataSource.fetch();
}
},
dataItem: function(element) {
if (element instanceof TreeListModel) {
return element;
}
var row = $(element).closest("tr");
var uid = row.attr(kendo.attr("uid"));
var model = isUndefined(uid) ? null : this.dataSource.getByUid(uid);
return model;
},
editRow: function(row) {
var that = this;
var model;
if (this._isIncellEditable() || !this.options.editable) {
return;
}
if (typeof row === STRING) {
row = this.tbody.find(row);
}
if (that._isPageable() && that._isPopupEditable() && row instanceof TreeListModel) {
// popup editor can be created without a rendered row
model = row;
} else {
model = this.dataItem(row);
}
if (!model) {
return;
}
if (that.editor) {
model._edit = true;
this._render();
this._cancelEditor();
} else {
that._preventPageSizeRestore = false;
}
if (this._editMode() != "popup") {
model._edit = true;
}
if (this.trigger(BEFORE_EDIT, { model: model })) {
that.dataSource._restorePageSizeAfterAddChild();
return;
}
this._render();
this._createEditor(model);
this.trigger(EDIT, {
container: this.editor.wrapper,
model: model
});
},
_cancelEdit: function(e) {
if (!this.editor) {
return;
}
var currentIndex;
e = extend(e, {
container: this.editor.wrapper,
model: this.editor.model
});
if (this.trigger(CANCEL, e)) {
return;
}
if (this.options.navigatable) {
currentIndex = this.items().index($(this.current()).parent());
}
this.cancelRow();
if (this.options.navigatable) {
this._setCurrent(this.items().eq(currentIndex).children().filter(NAVCELL).first());
focusTable(this.table, true);
}
},
cancelRow: function() {
if (this._isIncellEditable()) {
return;
}
this._cancelEditor();
this._render();
},
saveRow: function() {
var editor = this.editor;
var args;
if (this._isIncellEditable()) {
return;
}
if (!editor) {
return;
}
args = {
model: editor.model,
container: editor.wrapper
};
if (editor.end() && !this.trigger(SAVE, args)) {
this.dataSource.sync();
}
},
addRow: function(parent) {
var that = this;
var dataSource = that.dataSource;
var pageable = that._isPageable();
var incellEditing = that._isIncellEditable();
var inlineEditing = that._isInlineEditable();
var editor = this.editor;
var index = 0;
var model = {};
if ((editor && !editor.end()) || !this.options.editable) {
return;
}
if (parent) {
if (!(parent instanceof TreeListModel)) {
parent = this.dataItem(parent);
}
model[parent.parentIdField] = parent.id;
index = this.dataSource.indexOf(parent) + 1;
this.expand(parent)
.then(function() {
var showNewModelInView = pageable && dataSource._isLastItemInView(parent) && (incellEditing || inlineEditing);
that._insertAt(model, index, showNewModelInView);
});
return;
}
this._insertAt(model, index);
},
_insertAt: function(model, index, showNewModelInView) {
var that = this;
var dataSource = that.dataSource;
model = that.dataSource.insert(index, model);
if (showNewModelInView) {
dataSource._setAddChildPageSize();
}
var row = this._itemFor(model);
var cell;
if (that._isIncellEditable()) {
cell = row.children("td").eq(that._firstEditableColumnIndex(row));
that.editCell(cell);
} else if (row && row[0]) {
that.editRow(row);
} else if ((that._isPageable() || that.dataSource.filter()) && (that._isPopupEditable() || that._isInlineEditable())) {
that.editRow(model);
}
},
_firstEditableColumnIndex: function(container) {
var that = this;
var model = that.dataItem(container);
var columns = leafColumns(that.columns);
var length = columns.length;
var column;
var idx;
for (idx = 0; idx < length; idx++) {
column = columns[idx];
if (model && (!model.editable || model.editable(column.field)) && !column.command && !column.draggable && column.field && column.hidden !== true) {
return idx;
}
}
return -1;
},
removeRow: function(row) {
var model = this.dataItem(row);
var args = {
model: model,
row: row
};
if (this.options.editable && model && !this.trigger(REMOVE, args)) {
if (document.activeElement === $(row).find(".k-grid-delete")[0]) {
$(row).find(".k-grid-delete").trigger("blur");
}
this.dataSource.remove(model);
if (!this._isIncellEditable()) {
this.dataSource.sync();
}
}
},
_cancelEditor: function() {
var that = this;
var model;
var editor = that.editor;
if (editor) {
model = editor.model;
that._destroyEditor();
if (!that._isIncellEditable()) {
that.dataSource.cancelChanges(model);
} else if (that._shouldRestorePageSize()) {
that.dataSource._restorePageSizeAfterAddChild();
}
model._edit = false;
}
that._preventPageSizeRestore = false;
},
_shouldRestorePageSize: function() {
var that = this;
return that._isPageable() && that._isIncellEditable() && !that._preventPageSizeRestore;
},
_destroyEditor: function() {
if (!this.editor) {
return;
}
this.editor.close();
this.editor = null;
},
_createEditor: function(model) {
let row = this.itemFor(model);
let columns = leafColumns(this.columns);
let leafCols = [];
let that = this;
for (var idx = 0; idx < columns.length; idx++) {
leafCols.push(extend({}, columns[idx]));
delete leafCols[idx].parentColumn;
}
row = row.add(this._relatedRow(row));
let mode = this._editMode();
let options = {
columns: leafCols,
model: model,
target: this,
clearContainer: false,
template: this.options.editable.template
};
if (mode == "inline") {
this.editor = new Editor(row, options);
} else {
let windowOptions = extend({}, that.options.editable.window, {
_footerTemplate: () =>
`<div class="k-actions k-actions-start k-actions-horizontal k-window-actions">` +
that._buildCommands(["update"], true)[0].html +
that._buildCommands(["canceledit"], true)[0].html +
`</div>`
});
extend(options, {
window: windowOptions,
fieldRenderer: this._cellContent.bind(this),
save: this.saveRow.bind(this),
cancel: this._cancelEdit.bind(this),
appendTo: this.wrapper
});
this.editor = new PopupEditor(row, options);
}
},
_createIncellEditor: function(cell, options) {
var that = this;
var column = extend({}, options.columns[0]);
delete column.parentColumn;
return new IncellEditor(cell, extend({}, {
fieldRenderer: that._cellContent.bind(that),
appendTo: that.wrapper,
clearContainer: false,
target: that,
columns: [column],
model: options.model,
change: options.change
}));
},
editCell: function(cell) {
var that = this;
cell = $(cell);
var column = leafColumns(that.columns)[that.cellIndex(cell)];
var model = that.dataItem(cell);
if (that._isIncellEditable() && model && isColumnEditable(column, model)) {
that._editCell(cell, column, model, cell.index());
}
},
_editCell: function(cell, column, model, cellIndex) {
var that = this;
var editedCell;
if (that.trigger(BEFORE_EDIT, { model: model })) {
that.dataSource._restorePageSizeAfterAddChild();
return;
}
that.closeCell();
model._edit = true;
that._cancelEditor();
that._render({
editedColumn: column,
editedColumnIndex: cellIndex
});
editedCell = that.table.add(that.lockedTable).find(DOT + classNames.editCell).first();
that.editor = that._createIncellEditor(editedCell, {
columns: [column],
model: model,
change: function(e) {
if (that.trigger(SAVE, { values: e.values, container: cell, model: model })) {
e.preventDefault();
}
}
});
if (that.lockedTable) {
that._syncLockedContentHeight();
}
// refresh the current element as the DOM element reference can be changed after render()
that.current() && that.current().removeClass("k-focus");
that._current = editedCell;
that.trigger(EDIT, { container: cell, model: model });
},
closeCell: function(isCancel) {
var that = this;
var cell = (that.editor || {}).element;
var tr;
var model;
if (!cell || !cell[0] || !that._isIncellEditable()) {
return;
}
model = that.dataItem(cell);
if (isCancel && that.trigger(CANCEL, { container: cell, model: model })) {
return;
}
that.trigger(CELL_CLOSE, { type: isCancel ? CANCEL : SAVE, model: model, container: cell });
that._cancelEditor();
cell.removeClass(classNames.editCell);
tr = cell.parent().removeClass(classNames.editRow);
if (that.lockedContent) {
that._relatedRow(tr).removeClass(classNames.editRow);
}
that._render();
that.trigger(ITEM_CHANGE, { item: tr, data: model, ns: ui });
if (that.lockedContent) {
adjustRowHeight(tr.css("height", "")[0], that._relatedRow(tr).css("height", "")[0]);
}
},
cancelChanges: function() {
this.dataSource.cancelChanges();
},
saveChanges: function() {
var that = this;
var editable = (that.editor || {}).editable;
var valid = editable && editable.end();
if ((valid || !editable) && !that.trigger(SAVE_CHANGES)) {
that.dataSource.sync();
}
},
_editMode: function() {
var mode = "inline",
editable = this.options.editable;
if (editable !== true) {
if (typeof editable == "string") {
mode = editable;
} else {
mode = editable.mode || mode;
}
}
return mode.toLowerCase();
},
_isIncellEditable: function() {
return this._editMode() === INCELL;
},
_isInlineEditable: function() {
return this._editMode() === INLINE;
},
_isPopupEditable: function() {
return this._editMode() === POPUP;
},
hideColumn: function(column) {
this._toggleColumnVisibility(column, true);
},
showColumn: function(column) {
this._toggleColumnVisibility(column, false);
},
_toggleColumnVisibility: function(column, hidden) {
column = this._findColumn(column);
if (!column || column.hidden === hidden) {
return;
}
column.hidden = hidden;
this._setParentsVisibility(column, !hidden);
this._ensureExpandableColumn();
this._clearColsCache();
this._renderCols();
this._renderHeader();
this._render();
this._adjustTablesWidth();
if (hidden) {
this._ariaAddHiddenColIndex();
} else {
this._ariaRemoveHiddenColIndex();
}
this.trigger(hidden ? COLUMNHIDE : COLUMNSHOW, { column: column });
if (!hidden && !column.width) {
this.table
.add(this.thead.closest("table"))
.width("");
}
this._updateFirstColumnClass();
},
_findColumn: function(column) {
if (typeof column == "number") {
column = this.columns[column];
} else if (isPlainObject(column)) {
column = grep(leafColumns(this.columns), function(item) {
return item === column;
})[0];
} else {
column = grep(leafColumns(this.columns), function(item) {
return item.field === column;
})[0];
}
return column;
},
_adjustTablesWidth: function() {
var idx, length;
var cols = this.thead.prev().children();
var colWidth, width = 0;
for (idx = 0, length = cols.length; idx < length; idx++) {
colWidth = cols[idx].style.width;
if (colWidth && colWidth.indexOf("%") == -1) {
width += parseInt(colWidth, 10);
} else {
width = 0;
break;
}
}
if (width) {
this.table
.add(this.thead.closest("table"))
.width(width);
}
},
_reorderable: function() {
if (!this.options.reorderable) {
return;
}
var scrollable = this.options.scrollable === true;
var selector = (scrollable ? ".k-grid-header " : "table>.k-grid-header ") + HEADERCELLS;
var that = this;
this._draggableInstance = new ui.Draggable(this.wrapper, {
group: kendo.guid(),
filter: selector,
ignore: ".k-filter-row *",
hint: function(target) {
return $('<div class="k-reorder-clue k-drag-clue" />')
.html(target.attr(kendo.attr("title")) || target.attr(kendo.attr("field")) || target.text())
.prepend(kendo.ui.icon({ icon: "cancel", iconClass: "k-drag-status" }));
}
});
this.reorderable = new ui.Reorderable(this.wrapper, {
draggable: this._draggableInstance,
dragOverContainers: this._allowDragOverContainers.bind(this),
inSameContainer: function(e) {
return $(e.source).parent()[0] === $(e.target).parent()[0] && targetParentContainerIndex(flatColumnsInDomOrder(that.columns), that.columns, e.sourceIndex, e.targetIndex) > -1;
},
change: function(e) {
var columns = flatColumnsInDomOrder(that.columns);
var column = columns[e.oldIndex];
var newIndex = targetParentContainerIndex(columns, that.columns, e.oldIndex, e.newIndex);
that.trigger(COLUMNREORDER, {
newIndex: newIndex,
oldIndex: inArray(column, columns),
column: column
});
that.reorderColumn(newIndex, column, e.position === "before");
}
});
},
_allowDragOverContainers: function(sourceIndex, targetIndex) {
var columns = flatColumnsInDomOrder(this.columns);
return columns[sourceIndex].lockable !== false && targetParentContainerIndex(columns, this.columns, sourceIndex, targetIndex) > -1;
},
_reorderTrees: function(destSources, destContainer, destDomTree, sources, sourcesContainer, sourcesDomTree, before, depth) {
var ths = $();
var source = sourcesContainer.find("tr").eq(sources[0].rowIndex);
var sourceDOM = sourcesDomTree.children[sources[0].rowIndex];
var sourceChildren = source.children();
var destDomChildren;
var currentIndex;
var destColumn = before ? destSources[0] : destSources[destSources.length - 1];
var destRow;
var sourcesLeafs;
var destLeafs;
var reorderTaget;
var destThs;
for (var idx = 0; idx < sources.length; idx++) {
currentIndex = sources[idx].cellIndex;
ths = ths.add(sourceChildren.eq(currentIndex));
destDomChildren = destDomTree.children[destColumn.rowIndex].children;
if (destDomTree === sourcesDomTree && before) {
currentIndex += idx;
}
destDomChildren.splice(before ? destColumn.cellIndex + idx : destColumn.cellIndex + 1 + idx, 0, sourceDOM.children[currentIndex]);
}
if (destDomTree === sourcesDomTree && before) {
sourceDOM.children.splice(sources[0].cellIndex + sources.length, sources.length);
} else {
sourceDOM.children.splice(sources[0].cellIndex, sources.length);
}
destRow = destContainer.find("tr").eq(destColumn.rowIndex);
destThs = destRow.find(">th.k-header").eq(destColumn.cellIndex);
if (destThs.length && ths[0] !== destThs[0]) {
ths[before ? "insertBefore" : "insertAfter"](destThs);
}
if (depth >= sources[0].rowIndex + 1 && depth != 1) {
sourcesLeafs = [];
for (idx = 0; idx < sources.length; idx++) {
if (sources[idx].columns) {
sourcesLeafs = sourcesLeafs.concat(sources[idx].columns);
}
}
if (!sourcesLeafs.length) {
return;
}
destLeafs = [];
for (idx = 0; idx < destSources.length; idx++) {
if (destSources[idx].columns) {
destLeafs = destLeafs.concat(destSources[idx].columns);
}
}
if (!destLeafs.length && (destContainer !== sourcesContainer || (destColumn.cellIndex - sources[0].cellIndex > 1 || sources[0].cellIndex - destColumn.cellIndex > 1))) {
reorderTaget = findReorderTarget(this.columns, destColumn, sources[0], before, this.columns);
destLeafs = [reorderTaget];
if (!reorderTaget && sourcesLeafs.length && destContainer.find("tr").length > sources[0].rowIndex + 1) {
this._insertTree(sourcesLeafs, sourcesContainer, sourcesDomTree, destContainer, destDomTree);
return;
}
}
if (!destLeafs.length) {
return;
}
this._reorderTrees(destLeafs, destContainer, destDomTree, sourcesLeafs, sourcesContainer, sourcesDomTree, before, depth);
}
},
_insertTree: function(columns, sourcesContainer, sourcesDomTree, destContainer, destDomTree) {
var leafs = [];
var row;
var ths = $();
var domTr;
row = sourcesContainer.find("tr").eq(columns[0].rowIndex);
domTr = sourcesDomTree.children[columns[0].rowIndex];
for (var idx = 0; idx < columns.length; idx++) {
if (columns[idx].columns) {
leafs = leafs.concat(columns[idx].columns);
}
destDomTree.children[columns[0].rowIndex].children.splice(idx, 0, domTr.children[columns[idx].rowIndex]);
ths = ths.add(row.find(">th.k-header").eq(columns[idx].cellIndex));
}
sourcesDomTree.children[columns[0].rowIndex].children.splice(columns[0].cellIndex, columns.length);
destContainer.find("tr").eq(columns[0].rowIndex).append(ths);
if (leafs.length) {
this._insertTree(leafs, sourcesContainer, sourcesDomTree, destContainer, destDomTree);
}
},
_reorderHeader: function(destColumn, column, before) {
var sourcesDepth = column.columns ? depth([column]) : 1;
var targetDepth = destColumn.columns ? depth([destColumn]) : 1;
var sourceLocked = isLocked(column);
var destLocked = isLocked(destColumn);
var destContainer = destLocked ? this.lockedHeader : this.thead;
var sourcesContainer = sourceLocked ? this.lockedHeader : this.thead;
var destDomTree = destLocked ? this._lockedHeaderTree : this._headerTree;
var sourcesDomTree = sourceLocked ? this._lockedHeaderTree : this._headerTree;
var rowsToAdd;
var destRows = destContainer.find("tr:not(.k-filter-row)");
var destTarget;
if (sourcesDepth === targetDepth || sourcesDepth < destRows.length) {
this._reorderTrees([destColumn], destContainer, destDomTree, [column], sourcesContainer, sourcesDomTree, before, sourcesDepth);
updateRowSpans(destContainer, destDomTree);
removeEmptyRows(sourcesContainer, sourcesDomTree);
} else {
if (destContainer !== sourcesContainer) {
rowsToAdd = sourcesDepth - destRows.length;
destRows.each(function(idx) {
var cells = this.cells;
for (var i = 0; i < cells.length; i++) {
if (cells[i].colSpan <= 1 && cells[i].attributes.rowspan) {
destDomTree.children[idx].children[i].attr.rowSpan += rowsToAdd;
cells[i].rowSpan += rowsToAdd;
}
}
});
for (var j = 0; j < rowsToAdd; j++) {
destDomTree.children.push(kendoDomElement("tr", { "role": "row" }));
if (destContainer.is("thead")) {
destTarget = destContainer;
} else {
destTarget = destContainer.find("thead");
}
if (this._hasFilterRow()) {
$("<tr class='k-table-row' role='row'></tr>").insertBefore(destTarget.find('tr.k-filter-row'));
} else {
destTarget.append("<tr class='k-table-row' role='row'></tr>");
}
}
}
this._reorderTrees([destColumn], destContainer, destDomTree, [column], sourcesContainer, sourcesDomTree, before, sourcesDepth);
removeEmptyRows(sourcesContainer, sourcesDomTree);
}
},
reorderColumn: function(destIndex, column, before) {
var lockChanged;
var parent = column.parentColumn;
var columns = parent ? parent.columns : this.columns;
var sourceIndex = inArray(column, columns);
var destColumn = columns[destIndex];
var isLocked = !!destColumn.locked;
var hasMultiColumnHeaders = grep(this.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0;
var nonLockedColumnsLength = nonLockedColumns(columns).length;
if (sourceIndex === destIndex) {
return;
}
if (isLocked && !column.locked && nonLockedColumnsLength == 1) {
return;
}
if (!isLocked && column.locked && (columns.length - nonLockedColumnsLength == 1)) {
return;
}
if (before === undefined$1) {
before = destIndex < sourceIndex;
}
if (hasMultiColumnHeaders) {
this._reorderHeader(destColumn, column, before);
}
lockChanged = !!column.locked;
lockChanged = lockChanged != isLocked;
column.locked = isLocked;
columns.splice(before ? destIndex : destIndex + 1, 0, column);
columns.splice(sourceIndex < destIndex ? sourceIndex : sourceIndex + 1, 1);
this._setColumnDataIndexes(leafColumns(this.columns));
this._clearColsCache();
this._renderCols();
//reorder column header manually
if (!hasMultiColumnHeaders) {
var ths = $(this.lockedHeader).add(this.thead).find("tr:not(.k-filter-row) th");
ths.eq(sourceIndex)[before ? "insertBefore" : "insertAfter"](ths.eq(destIndex));
var dom = this._headerTree.children[0].children;
if (this._hasLockedColumns) {
dom = this._lockedHeaderTree.children[0].children.concat(dom);
}
dom.splice(before ? destIndex : destIndex + 1, 0, dom[sourceIndex]);
dom.splice(sourceIndex < destIndex ? sourceIndex : sourceIndex + 1, 1);
if (this._hasLockedColumns) {
this._lockedHeaderTree.children[0].children = dom.splice(0, lockedColumns(columns).length);
this._headerTree.children[0].children = dom;
}
} else {
if (this.lockedHeader) {
columns = nonLockedColumns(this.columns);
this._prepareColumns([{ rowSpan: 1, cells: [], index: 0 }], columns);
columns = lockedColumns(this.columns);
this._prepareColumns([{ rowSpan: 1, cells: [], index: 0 }], columns);
} else {
this._prepareColumns([{ rowSpan: 1, cells: [], index: 0 }], this.columns);
}
}
this._updateColumnCellIndex();
this._applyLockedContainersWidth();
this._syncLockedHeaderHeight();
this._updateFirstColumnClass();
if (this._hasFilterRow()) {
this._updateFilterThs(before, column, destColumn);
}
this.refresh();
if (!lockChanged) {
return;
}
if (isLocked) {
this.trigger(COLUMNLOCK, {
column: column
});
} else {
this.trigger(COLUMNUNLOCK, {
column: column
});
}
},
lockColumn: function(column) {
var columns = this.columns;
if (typeof column == "number") {
column = columns[column];
} else {
column = grep(columns, function(item) {
return item.field === column;
})[0];
}
if (!column || column.hidden) {
return;
}
var index = lockedColumns(columns).length - 1;
this.reorderColumn(index, column, false);
},
unlockColumn: function(column) {
var columns = this.columns;
if (typeof column == "number") {
column = columns[column];
} else {
column = grep(columns, function(item) {
return item.field === column;
})[0];
}
if (!column || column.hidden) {
return;
}
var index = lockedColumns(columns).length;
this.reorderColumn(index, column, true);
},
_columnMenu: function() {
var ths = $(this.lockedHeader).add(this.thead).find("th");
var columns = this.columns;
var options = this.options;
var columnMenu = options.columnMenu;
var column, menu, menuOptions, sortable, filterable;
var initHandler = this._columnMenuInit.bind(this);
var openHandler = this._columnMenuOpen.bind(this);
var sortHandler = this._sort.bind(this);
var filterHandler = this._filter.bind(this);
var hasLockableColumns = grep(this.columns, function(item) {
return item.lockable !== false;
}).length > 0;
var hasMultiColumnHeaders = grep(this.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0;
if (hasMultiColumnHeaders) {
columns = leafColumns(columns);
if (this.lockedHeader) {
ths = sortCells(leafDataCells(this.lockedHeader.find(">table>thead")).add(leafDataCells(this.thead)));
} else {
ths = leafDataCells(this.thead);
}
} else {
ths = $(this.lockedHeader).add(this.thead).find("tr:not(.k-filter-row) th");
}
if (!columnMenu) {
return;
}
if (typeof columnMenu == "boolean") {
columnMenu = {};
}
for (var i = 0; i < ths.length; i++) {
column = columns[i];
if (!column.field) {
continue;
}
menu = ths.eq(i).data("kendoColumnMenu");
if (menu) {
menu.destroy();
}
sortable = false;
if (column.sortable !== false && columnMenu.sortable !== false && options.sortable !== false) {
sortable = extend({}, options.sortable, { compare: (column.sortable || {}).compare });
}
filterable = false;
if (options.filterable && column.filterable !== false && columnMenu.filterable !== false) {
filterable = extend({ pane: this.pane }, column.filterable, options.filterable);
}
menuOptions = {
dataSource: this.dataSource,
values: column.values,
columns: columnMenu.columns,
sortable: sortable,
filterable: filterable,
messages: columnMenu.messages,
owner: this,
closeCallback: closeCallback,
init: initHandler,
open: openHandler,
sort: sortHandler,
filtering: filterHandler,
pane: this.pane,
hasLockableColumns: lockedColumns(columns).length > 0 && hasLockableColumns && !hasMultiColumnHeaders,
appendTo: DOT + classNames.headerCellInner,
reorderable: !!options.reorderable
};
ths.eq(i).kendoColumnMenu(menuOptions);
}
},
_columnMenuInit: function(e) {
this.trigger(COLUMNMENUINIT, { field: e.field, container: e.container });
},
_columnMenuOpen: function(e) {
this.trigger(COLUMNMENUOPEN, { field: e.field, container: e.container });
},
_filter: function(e) {
if (this.trigger(FILTER, { filter: e.filter, field: e.field })) {
e.preventDefault();
}
},
_sort: function(e) {
if (this.trigger(SORT, { sort: e.sort })) {
e.preventDefault();
}
},
_pageable: function() {
var that = this,
wrapper,
pageable = that.options.pageable;
if (pageable) {
wrapper = that.wrapper.children("div.k-grid-pager");
if (!wrapper.length) {
wrapper = $('<div class="k-pager k-grid-pager"/>').appendTo(that.wrapper);
}
that._destroyPager();
if (typeof pageable === "object" && pageable instanceof kendo.ui.TreeListPager) {
that.pager = pageable;
} else if (that.dataSource && !that.dataSource.options.serverPaging) {
that._createPager(wrapper);
}
if (that.pager) {
that.pager.bind(PAGE_CHANGE, function(e) {
if (that.trigger(PAGE, { page: e.index })) {
e.preventDefault();
}
});
}
}
},
_createPager: function(element, options) {
var that = this;
that.pager = new TreeListPager(element, extend({}, that.options.pageable, {
dataSource: that.dataSource,
size: "medium",
navigatable: that.options.navigatable
}, options));
},
_destroyPager: function() {
if (this.pager) {
this.pager.destroy();
this.pager = null;
}
},
_isPageable: function() {
var that = this;
return that.options.pageable && (!that.dataSource || (that.dataSource && that.dataSource._isPageable()));
},
_togglePagerVisibility: function() {
var that = this;
var pageable = that.options.pageable;
if (pageable && (isPlainObject(pageable) || pageable instanceof TreeListPager) && pageable.alwaysVisible === false) {
that.wrapper.find(".k-grid-pager").toggle((that.dataSource.collapsedTotal() || 0) >= that.dataSource.pageSize());
}
}
});
function closeCallback(element) {
focusTable(element.closest(".k-treelist").find("[role=treegrid]"), true);
}
function isInputElement(element) {
return $(element).is(":button,a,:input,a>.k-icon,a>.k-svg-icon,textarea,span.k-select,span.k-icon:not(.k-treelist-toggle),span.k-svg-icon:not(.k-treelist-toggle),span.k-link,.k-input,.k-multiselect-wrap,.k-tool-icon,.k-input-value-text,.k-input-inner,.k-button-icon,.k-switch-thumb,.k-switch-track,.k-switch-label-off,.k-switch-label-on");
}
function isLocked(column) {
if (!column.parentColumn) {
return !!column.locked;
}
return !!isLocked(column.parentColumn);
}
function findParentColumnWithChildren(columns, index, source, rtl) {
var target;
var locked = !!source.locked;
var targetLocked;
do {
target = columns[index];
index += rtl ? 1 : -1;
targetLocked = !!target.locked;
} while (target && index > -1 && index < columns.length && target != source && !target.columns && targetLocked === locked);
return target;
}
function findReorderTarget(columns, target, source, before, masterColumns) {
if (target.columns) {
target = target.columns;
return target[before ? 0 : target.length - 1];
} else {
var parent = columnParent(target, columns);
var parentColumns;
if (parent) {
parentColumns = parent.columns;
} else {
parentColumns = columns;
}
var index = inArray(target, parentColumns);
if (index === 0 && before && parentColumns.length !== 1) {
index++;
} else if (index == parentColumns.length - 1 && !before && index !== 0) {
index--;
} else if (index > 0 || (index === 0 && !before && index !== 0)) {
index += before ? -1 : 1;
}
var sourceIndex = inArray(source, parentColumns);
target = findParentColumnWithChildren(parentColumns, index, source, sourceIndex > index);
var targetIndex = inArray(target, masterColumns);
if (target.columns && (!targetIndex || targetIndex === parentColumns.length - 1)) {
return null;
}
if (target && target != source && target.columns) {
return findReorderTarget(columns, target, source, before, masterColumns);
}
}
return null;
}
function leafColumns(columns) {
var result = [];
for (var idx = 0; idx < columns.length; idx++) {
if (!columns[idx].columns) {
result.push(columns[idx]);
continue;
}
result = result.concat(leafColumns(columns[idx].columns));
}
return result;
}
function getColumnsFields(columns) {
var result = [];
columns = leafColumns(columns);
for (var idx = 0; idx < columns.length; idx++) {
if (typeof columns[idx] === "string") {
result.push(columns[idx]);
} else if (columns[idx].field) {
result.push(columns[idx].field);
}
}
return result;
}
function visibleChildColumns(columns) {
return grep(columns, function(column) {
return !column.hidden;
});
}
function isVisible(column) {
return visibleColumns([column]).length > 0;
}
function visibleColumns(columns) {
return grep(columns, function(column) {
var result = !column.hidden;
if (result && column.columns) {
result = visibleColumns(column.columns).length > 0;
}
return result;
});
}
function normalizeColumns(columns, hide, parentIds) {
return map(columns, function(column) {
var hidden;
column.parentIds = parentIds;
if (!isVisible(column) || hide) {
hidden = true;
}
var uid = kendo.guid();
column.headerAttributes = extend({ headers: parentIds }, column.headerAttributes);
if (!column.headerAttributes || !column.headerAttributes.id) {
column.headerAttributes = extend({ id: uid }, column.headerAttributes);
} else {
uid = column.headerAttributes.id;
}
if (column.columns) {
column.columns = normalizeColumns(column.columns, hidden, parentIds ? (parentIds + " " + uid) : uid);
}
return extend({ hidden: hidden }, column);
});
}
function flatColumnsInDomOrder(columns) {
var result = flatColumns(lockedColumns(columns));
return result.concat(flatColumns(nonLockedColumns(columns)));
}
function targetParentContainerIndex(flatColumns, columns, sourceIndex, targetIndex) {
var column = flatColumns[sourceIndex];
var target = flatColumns[targetIndex];
var parent = columnParent(column, columns);
columns = parent ? parent.columns : columns;
return inArray(target, columns);
}
function parentColumnsCells(cell) {
var container = cell.closest("table");
var result = $().add(cell);
var row = cell.closest("tr");
var headerRows = container.find("tr");
var level = headerRows.index(row);
if (level > 0) {
var parent = headerRows.eq(level - 1);
var parentCellsWithChildren = parent.find("th").filter(function() {
return !$(this).attr("rowspan");
});
var offset = 0;
var index = row.find("th").index(cell);
var prevCells = cell.prevAll().filter(function() {
return this.colSpan > 1;
});
for (var idx = 0; idx < prevCells.length; idx++) {
offset += prevCells[idx].colSpan || 1;
}
index += Math.max(offset - 1, 0);
offset = 0;
for (idx = 0; idx < parentCellsWithChildren.length; idx++) {
var parentCell = parentCellsWithChildren.eq(idx);
if (parentCell.attr("data-colspan")) {
offset += parentCell[0].getAttribute("data-colspan");
} else {
offset += 1;
}
if (index >= idx && index < offset) {
result = parentColumnsCells(parentCell).add(result);
break;
}
}
}
return result;
}
function childColumnsCells(cell) {
var container = cell.closest("thead");
var result = $().add(cell);
var row = cell.closest("tr");
var headerRows = container.find("tr");
var level = headerRows.index(row) + cell[0].rowSpan;
var colSpanAttr = kendo.attr("colspan");
if (level <= headerRows.length - 1) {
var child = row.next();
var prevCells = cell.prevAll();
var idx;
prevCells = prevCells.filter(function() {
return !this.rowSpan || this.rowSpan === 1;
});
var offset = 0;
for (idx = 0; idx < prevCells.length; idx++) {
offset += parseInt(prevCells.eq(idx).attr(colSpanAttr), 10) || 1;
}
var cells = child.find("th");
var colSpan = parseInt(cell.attr(colSpanAttr), 10) || 1;
idx = 0;
while (idx < colSpan) {
child = cells.eq(idx + offset);
result = result.add(childColumnsCells(child));
var value = parseInt(child.attr(colSpanAttr), 10);
if (value > 1) {
colSpan -= value - 1;
}
idx++;
}
}
return result;
}
function columnParent(column, columns) {
var parents = [];
columnParents(column, columns, parents);
return parents[parents.length - 1];
}
function columnParents(column, columns, parents) {
parents = parents || [];
for (var idx = 0; idx < columns.length; idx++) {
if (column === columns[idx]) {
return true;
} else if (columns[idx].columns) {
var inserted = parents.length;
parents.push(columns[idx]);
if (!columnParents(column, columns[idx].columns, parents)) {
parents.splice(inserted, parents.length - inserted);
} else {
return true;
}
}
}
return false;
}
function flatColumns(columns) {
var result = [];
var children = [];
for (var idx = 0; idx < columns.length; idx++) {
result.push(columns[idx]);
if (columns[idx].columns) {
children = children.concat(columns[idx].columns);
}
}
if (children.length) {
result = result.concat(flatColumns(children));
}
return result;
}
function columnPosition(column, columns, row, cellCounts) {
var result;
var idx;
row = row || 0;
cellCounts = cellCounts || {};
cellCounts[row] = cellCounts[row] || 0;
for (idx = 0; idx < columns.length; idx++) {
if (columns[idx] == column) {
result = { cell: cellCounts[row], row: row };
break;
} else if (columns[idx].columns) {
result = columnPosition(column, columns[idx].columns, row + 1, cellCounts);
if (result) {
break;
}
}
cellCounts[row]++;
}
return result;
}
function updateCellIndex(thead, columns, offset) {
offset = offset || 0;
var position;
var cell;
var allColumns = columns;
columns = leafColumns(columns);
var cells = {};
var rows = thead.find(">tr:not(.k-filter-row)");
var filter = function() {
var el = $(this);
return !el.hasClass("k-group-cell") && !el.hasClass("k-hierarchy-cell");
};
for (var idx = 0, length = columns.length; idx < length; idx++) {
position = columnPosition(columns[idx], allColumns);
if (!cells[position.row]) {
cells[position.row] = rows.eq(position.row)
.find(".k-header")
.filter(filter);
}
cell = cells[position.row].eq(position.cell);
cell.attr(kendo.attr("index"), offset + idx);
}
return columns.length;
}
function depth(columns) {
var result = 1;
var max = 0;
for (var idx = 0; idx < columns.length; idx++) {
if (columns[idx].columns) {
var temp = depth(columns[idx].columns);
if (temp > max) {
max = temp;
}
}
}
return result + max;
}
function lockedColumns(columns) {
return grep(columns, is("locked"));
}
function nonLockedColumns(columns) {
return grep(columns, not(is("locked")));
}
function updateRowSpans(container, containerDOMtree) {
var rows = container.find("tr:not(.k-filter-row)");
var length = rows.length;
rows.each(function(idx) {
var cells = this.cells;
for (var i = 0; i < cells.length; i++) {
if (cells[i].colSpan <= 1 && cells[i].attributes.rowspan) {
containerDOMtree.children[idx].children[i].attr.rowSpan = length - idx;
cells[i].rowSpan = length - idx;
}
}
});
}
function removeEmptyRows(container, containerDOMtree) {
var rows = container.find("tr");
var emptyRows = [];
rows.filter(function(idx) {
var shouldRemove = !$(this).children().length;
if (shouldRemove) {
emptyRows.push(idx);
}
return shouldRemove;
}).remove();
for (var i = emptyRows.length - 1; i >= 0; i--) {
containerDOMtree.children.splice(emptyRows[i], 1);
}
updateRowSpans(container, containerDOMtree);
}
function focusTable(table, direct) {
if (direct === true) {
table = $(table);
var scrollTop, scrollLeft;
scrollTop = table.parent().scrollTop();
scrollLeft = kendo.scrollLeft(table.parent());
kendo.focusElement(table);
kendo.scrollLeft(table.parent().scrollTop(scrollTop), scrollLeft);
} else {
$(table).one("focusin", function(e) { e.preventDefault(); }).trigger("focus");
}
}
function adjustRowHeight(row1, row2) {
var height;
var offsetHeight1 = row1.offsetHeight;
var offsetHeight2 = row2.offsetHeight;
if (offsetHeight1 > offsetHeight2) {
height = offsetHeight1 + "px";
} else if (offsetHeight1 < offsetHeight2) {
height = offsetHeight2 + "px";
}
if (height) {
row1.style.height = row2.style.height = height;
}
}
function isColumnEditable(column, model) {
if (!column || !model || !column.field || column.selectable || column.command || column.draggable || (column.editable && !column.editable(model))) {
return false;
}
return (column.field && model.editable && model.editable(column.field));
}
function capitalize(word) {
return word.charAt(0).toUpperCase() + word.slice(1);
}
function isDirtyColumn(column, model) {
var field = (column || {}).field || "";
return (model.dirty && model.dirtyFields && model.dirtyFields[field] && isColumnEditable(column, model));
}
function isUndefined(value) {
return typeof (value) === "undefined";
}
function isNumber(value) {
return typeof value === "number" && !isNaN(value);
}
if (kendo.ExcelMixin) {
kendo.ExcelMixin.extend(TreeList.prototype);
}
if (kendo.PDFMixin) {
kendo.PDFMixin.extend(TreeList.prototype);
TreeList.prototype._drawPDF = function(progress) {
var treeList = this;
if (treeList.options.pdf.paperSize && treeList.options.pdf.paperSize != "auto") {
return treeList._drawPDF_autoPageBreak(progress);
}
var result = new $.Deferred();
var dataSource = treeList.dataSource;
var allPages = treeList.options.pdf.allPages;
this._initPDFProgress(progress);
// This group will be our document containing all pages
var doc = new kendo.drawing.Group();
var startingPage = dataSource.page();
function resolve() {
if (allPages && startingPage !== undefined$1) {
dataSource.unbind("change", exportPage);
dataSource.one("change", function() {
result.resolve(doc);
});
dataSource.page(startingPage);
} else {
result.resolve(doc);
}
}
function exportPage() {
treeList._drawPDFShadow({
width: treeList.wrapper.width()
}, {
avoidLinks: treeList.options.pdf.avoidLinks
})
.done(function(group) {
var pageNum = dataSource.page();
var totalPages = allPages ? dataSource.totalPages() : 1;
var args = {
page: group,
pageNumber: pageNum,
progress: pageNum / totalPages,
totalPages: totalPages
};
progress.notify(args);
doc.append(args.page);
if (pageNum < totalPages) {
dataSource.page(pageNum + 1);
} else {
resolve();
}
})
.fail(function(err) {
result.reject(err);
});
}
if (allPages) {
dataSource.bind("change", exportPage);
dataSource.page(1);
} else {
exportPage();
}
return result.promise();
};
TreeList.prototype._initPDFProgress = function(deferred) {
var loading = $("<div class='k-loading-pdf-mask'><div class='k-loading-color'></div></div>");
loading.prepend(this.wrapper.clone().css({
position: "absolute", top: 0, left: 0
}));
this.wrapper.append(loading);
var progressBar = $("<div class='k-loading-pdf-progress'>")
.appendTo(loading)
.kendoProgressBar({
type: "chunk",
chunkCount: 10,
min: 0,
max: 1,
value: 0
}).data("kendoProgressBar");
deferred.progress(function(e) {
progressBar.value(e.progress);
})
.always(function() {
kendo.destroy(loading);
loading.remove();
});
};
TreeList.prototype._drawPDF_autoPageBreak = function(progress) {
var treeList = this;
var result = new $.Deferred();
var dataSource = treeList.dataSource;
var allPages = treeList.options.pdf.allPages;
var origBody = treeList.wrapper.find('table[role="treeList"] > tbody');
var cont = $("<div>")
.css({ position: "absolute", left: -1e4, top: -1e4 });
var clone = treeList.wrapper.clone().css({
height: "auto", width: "auto"
}).appendTo(cont);
clone.find(".k-grid-content").css({ height: "auto", width: "auto", overflow: "visible" });
clone.find('table[role="treeList"], .k-grid-footer table').css({ height: "auto", width: "100%", overflow: "visible" });
clone.find(".k-grid-pager, .k-grid-toolbar, .k-grouping-header").remove();
clone.find(".k-grid-header, .k-grid-footer").css({ paddingRight: 0 });
this._initPDFProgress(progress);
var body = clone.find('table[role="treeList"] > tbody').empty();
var startingPage = dataSource.page();
function resolve() {
if (allPages && startingPage !== undefined$1) {
dataSource.one("change", draw);
dataSource.page(startingPage);
} else {
treeList.refresh();
draw();
}
}
function draw() {
cont.appendTo(document.body);
var options = $.extend({}, treeList.options.pdf, {
_destructive: true,
progress: function(p) {
progress.notify({
page: p.page,
pageNumber: p.pageNum,
progress: 0.5 + p.pageNum / p.totalPages / 2,
totalPages: p.totalPages
});
}
});
kendo.drawing.drawDOM(clone, options)
.always(function() {
cont.remove();
})
.then(function(group) {
result.resolve(group);
})
.fail(function(err) {
result.reject(err);
});
}
function renderPage() {
var pageNum = dataSource.page();
var totalPages = allPages ? dataSource.totalPages() : 1;
body.append(origBody.find("tr"));
if (pageNum < totalPages) {
dataSource.page(pageNum + 1);
} else {
dataSource.unbind("change", renderPage);
resolve();
}
}
if (allPages) {
dataSource.bind("change", renderPage);
dataSource.page(1);
} else {
renderPage();
}
return result.promise();
};
}
extend(true, kendo.data, {
TreeListDataSource: TreeListDataSource,
TreeListModel: TreeListModel
});
extend(kendo.ui.treelist, {
editor: Editor,
defaultBodyContextMenu: defaultBodyContextMenu,
defaultHeadContextMenu: defaultHeadContextMenu,
});
ui.plugin(TreeList);
ui.plugin(TreeListPager);
})(window.kendo.jQuery);
var kendo$1 = kendo;
exports.__meta__ = __meta__;
exports.default = kendo$1;