@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
17,439 lines • 671 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.data.js');
require('./kendo.columnsorter.js');
require('./kendo.editable.js');
require('./kendo.window.js');
require('./kendo.badge.js');
require('./kendo.filtermenu.js');
require('./kendo.filtercell.js');
require('./kendo.columnmenu.js');
require('./kendo.groupable.js');
require('./kendo.pager.js');
require('./kendo.selectable.js');
require('./kendo.sortable.js');
require('./kendo.reorderable.js');
require('./kendo.resizable.js');
require('./kendo.ooxml.js');
require('./mixins-RbnksPfz.js');
require('./kendo.pane.js');
require('./kendo.core.js');
require('./html-sdnHcjkh.js');
require('./mixins-D385O08Q.js');
require('./kendo.dialog.js');
require('./kendo.switch.js');
require('./kendo.html.button.js');
require('./kendo.textbox.js');
require('./kendo.form.js');
require('./kendo.toolbar.js');
require('./kendo.icons.js');
require('./kendo.menu.js');
require('./kendo.loader.js');
require('./kendo.html.loadercontainer.js');
var loaderContainer = require('./loaderContainer-_4RtKBV7.js');
require('./kendo.data.odata.js');
require('./kendo.licensing.js');
require('@progress/kendo-licensing');
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.actionsheet.view.js');
require('./kendo.button.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.progressbar.js');
require('./kendo.buttongroup.js');
require('./kendo.togglebutton.js');
require('./kendo.autocomplete.js');
require('./kendo.combobox.js');
require('./kendo.tabstrip.js');
require('./kendo.expansionpanel.js');
require('./kendo.view.js');
require('./kendo.chip.js');
require('./kendo.html.chip.js');
require('./kendo.chiplist.js');
require('./kendo.html.chiplist.js');
require('@progress/kendo-ooxml');
require('@progress/kendo-drawing');
require('./kendo.color.js');
require('./kendo.splitbutton.js');
require('./kendo.button.menu.js');
require('./kendo.dropdownbutton.js');
(function($, undefined$1) {
var kendo = window.kendo,
ui = kendo.ui,
ContextMenu = ui.ContextMenu,
extend = $.extend,
encode = kendo.htmlEncode;
var ACTION = "action";
var GridContextMenu = 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" },
"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" },
{ name: "clearSelection", text: "Clear selection", icon: "table-unmerge", softRules: "hasSelection", command: "ClearSelectionCommand" },
] },
"copySelection": { name: "copySelection", text: "Copy selection", icon: "page-header-section", rules: "isSelectable", softRules: "hasSelection", command: "CopySelectionCommand", options: "withHeaders" },
"copySelectionNoHeaders": { name: "copySelectionNoHeaders", text: "Copy selection (No Headers)", icon: "file-txt", rules: "isSelectable", softRules: "hasSelection", command: "CopySelectionCommand" },
"paste": { name: "paste", text: "Paste (use CTRL/⌘ + V)", rules: "allowPaste", softRules: "alwaysDisabled", icon: "clipboard" },
"reorderRow": { name: "reorderRow", text: "Reorder row", icon: "caret-alt-expand", rules: "isRowReorderable", softRules: "isSorted", items: [
{ name: "reorderRowUp", text: "Up", icon: "caret-alt-up", command: "ReorderRowCommand", options: "dir:up" },
{ name: "reorderRowDown", text: "Down", icon: "caret-alt-down", command: "ReorderRowCommand", options: "dir:down" },
{ name: "reorderRowTop", text: "Top", icon: "caret-alt-to-top", command: "ReorderRowCommand", options: "dir:top" },
{ name: "reorderRowBottom", text: "Bottom", icon: "caret-alt-to-bottom", command: "ReorderRowCommand", options: "dir:bottom" }
] },
"exportPDF": { name: "exportPDF", text: "Export to PDF", icon: "file-pdf", command: "ExportPDFCommand" },
"exportExcel": { name: "exportExcel", text: "Export to Excel", icon: "file-excel", items: [
{ name: "exportToExcelAll", text: "All", command: "ExportExcelCommand" },
{ name: "exportToExcelSelection", text: "Selection", command: "ExportExcelCommand", softRules: "hasSelection", options: "selection,withHeaders" },
{ name: "exportToExcelSelectionNoHeaders", text: "Selection (No Headers)", softRules: "hasSelection", command: "ExportExcelCommand", options: "selection" }
] },
"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" },
"moveGroupPrevious": { name: "moveGroupPrevious", text: "Move previous", icon: "arrow-left", rules: "isGroupable", softRules: "canMoveGroupPrev", command: "MoveGroupCommand", options: "dir:prev" },
"moveGroupNext": { name: "moveGroupNext", text: "Move next", icon: "arrow-right", rules: "isGroupable", softRules: "canMoveGroupNext", command: "MoveGroupCommand", options: "dir:next" }
// "filter": { name: "filter", text: "Filter", icon: "filter", attr: { [kendo.attr("is-filter")]: true }, items: [
// { content: '<div class="k-columnmenu-item-wrapper"><div class="k-columnmenu-item-content k-column-menu-filter"><div class="k-filterable"></div></div></div>' }
// ] },
},
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.grid = kendo.ui.grid || {};
extend(kendo.ui.grid, {
ContextMenu: GridContextMenu
});
})(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.grid = options.grid;
}
});
var MoveGroupCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
groupable = grid.groupable,
options = that.options,
target = options.target.closest(".k-chip"),
method = options.dir === "next" ? "after" : "before",
position = options.dir === "next" ? target.next() : target.prev();
position[method](target);
groupable._change();
},
});
var SortCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
dataSource = grid.dataSource,
sort = dataSource.sort() || [],
options = that.options,
dir = options.dir,
field = grid._getCellField(options.target),
multipleMode = grid.options.sortable.mode && grid.options.sortable.mode === "multiple",
compare = grid.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,
grid = that.grid;
grid.addRow();
}
});
var EditCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
inCellMode = grid._editMode() === "incell",
target = inCellMode ? that.options.target : that.options.target.closest("tr");
if (inCellMode) {
grid.editCell(target);
} else {
grid.editRow(target);
}
}
});
var DeleteCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
target = that.options.target.closest("tr");
grid.removeRow(target);
}
});
var CopySelectionCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
withHeaders = that.options.withHeaders;
grid.copySelectionToClipboard(withHeaders);
}
});
var SelectRowCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
selectMode = kendo.ui.Selectable.parseOptions(grid.options.selectable),
target = that.options.target.closest("tr");
grid.select(selectMode.cell ? target.find('td') : target);
}
});
var SelectAllRowsCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
selectMode = kendo.ui.Selectable.parseOptions(grid.options.selectable),
rows = grid.items();
grid.select(selectMode.cell ? rows.find('td') : rows);
}
});
var ClearSelectionCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid;
grid.clearSelection();
}
});
var ReorderRowCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid,
dir = that.options.dir,
target = that.options.target.closest("tr"),
index = target.index(),
newIndex;
switch (dir) {
case "up":
newIndex = index - 1;
break;
case "down":
newIndex = index + 2;
break;
case "top":
newIndex = 0;
break;
case "bottom":
newIndex = grid.items().length;
break;
}
grid.reorderRowTo(target, newIndex);
}
});
var ExportPDFCommand = Command.extend({
exec: function() {
var that = this,
grid = that.grid;
grid.saveAsPDF();
}
});
var ExportExcelCommand = Command.extend({
exec: function() {
var that = this,
selection = that.options.selection,
withHeaders = that.options.withHeaders,
grid = that.grid;
if (selection) {
grid.exportSelectedToExcel(withHeaders);
} else {
grid.saveAsExcel();
}
}
});
kendo.ui.grid = kendo.ui.grid || {};
extend(kendo.ui.grid, {
GridCommand: Command,
commands: {
SortCommand: SortCommand,
AddCommand: AddCommand,
EditCommand: EditCommand,
DeleteCommand: DeleteCommand,
CopySelectionCommand: CopySelectionCommand,
SelectRowCommand: SelectRowCommand,
SelectAllRowsCommand: SelectAllRowsCommand,
ClearSelectionCommand: ClearSelectionCommand,
ReorderRowCommand: ReorderRowCommand,
ExportPDFCommand: ExportPDFCommand,
ExportExcelCommand: ExportExcelCommand,
MoveGroupCommand: MoveGroupCommand
}
});
})(window.kendo.jQuery);
const __meta__ = {
id: "grid",
name: "Grid",
category: "web",
description: "The Grid widget displays tabular data and offers rich support for interacting with data,including paging, sorting, grouping, and selection.",
depends: ["data", "columnsorter", "sortable", "toolbar", "html.button", "icons", "menu", "loader", "html.loadercontainer", "badge"],
features: [{
id: "grid-editing",
name: "Editing",
description: "Support for record editing",
depends: ["editable", "window", "textbox", "form"]
}, {
id: "grid-filtering",
name: "Filtering",
description: "Support for record filtering",
depends: ["filtermenu"]
}, {
id: "grid-columnmenu",
name: "Column menu",
description: "Support for header column menu",
depends: ["columnmenu"]
}, {
id: "grid-grouping",
name: "Grouping",
description: "Support for grid grouping",
depends: ["groupable"]
}, {
id: "grid-filtercell",
name: "Row filter",
description: "Support for grid header filtering",
depends: ["filtercell"]
}, {
id: "grid-paging",
name: "Paging",
description: "Support for grid paging",
depends: ["pager"]
}, {
id: "grid-selection",
name: "Selection",
description: "Support for row selection",
depends: ["selectable"]
}, {
id: "grid-column-reorder",
name: "Column reordering",
description: "Support for column reordering",
depends: ["reorderable"]
}, {
id: "grid-column-resize",
name: "Column resizing",
description: "Support for column resizing",
depends: ["resizable"]
}, {
id: "grid-mobile",
name: "Grid adaptive rendering",
description: "Support for adaptive rendering",
depends: ["dialog", "pane", "switch"]
}, {
id: "grid-excel-export",
name: "Excel export",
description: "Export grid data as Excel spreadsheet",
depends: ["excel"]
}, {
id: "grid-pdf-export",
name: "PDF export",
description: "Export grid data as PDF",
depends: ["pdf", "drawing"]
}]
};
(function($, undefined$1) {
let kendo = window.kendo,
ui = kendo.ui,
DataSource = kendo.data.DataSource,
ObservableObject = kendo.data.ObservableObject,
tbodySupportsInnerHtml = kendo.support.tbodyInnerHtml,
activeElement = kendo._activeElement,
Widget = ui.Widget,
outerWidth = kendo._outerWidth,
outerHeight = kendo._outerHeight,
keys = kendo.keys,
getType = kendo.type,
isPlainObject = $.isPlainObject,
extend = $.extend,
map = $.map,
grep = $.grep,
isArray = Array.isArray,
inArray = $.inArray,
push = Array.prototype.push,
isFunction = kendo.isFunction,
encode = kendo.htmlEncode,
isEmptyObject = $.isEmptyObject,
contains = $.contains,
math = Math,
DOT = ".",
PROGRESS = "progress",
ERROR = "error",
HIERARCHY_CELL_CLASS = "k-hierarchy-cell",
DATA_CELL = ":not(.k-group-cell):not([" + kendo.attr("virtual") + "]):not(.k-hierarchy-cell:not(:has(.k-icon.k-i-caret-alt-down,.k-icon.k-i-caret-alt-right,.k-svg-icon.k-svg-i-caret-alt-down,.k-svg-icon.k-svg-i-caret-alt-right,.k-svg-icon.k-svg-i-caret-alt-left,.k-icon.k-i-caret-alt-left))):visible",
DATA_CELL_HIDDENINCLUDED = ":not([" + kendo.attr("virtual") + "]):not(.k-hierarchy-cell:not(:has(.k-icon.k-i-caret-alt-down,.k-icon.k-i-caret-alt-right,.k-svg-icon.k-svg-i-caret-alt-down,.k-svg-icon.k-svg-i-caret-alt-right,.k-svg-icon.k-svg-i-caret-alt-left,.k-icon.k-i-caret-alt-left)))",
SELECTION_CELL_SELECTOR = "tbody>tr:not(.k-grouping-row):not(.k-detail-row):not(.k-group-footer):not([data-skeleton-row]) > td:not(.k-group-cell):not(.k-hierarchy-cell)",
NAVROW = "tr:not(.k-footer-template):visible",
NAVCELL = ":not(.k-group-cell):not(.k-detail-cell):not(.k-hierarchy-cell):visible",
ITEMROW = "tr:not(.k-grouping-row):not(.k-detail-row):not(.k-footer-template):not(.k-group-footer):visible",
COLGROUP = "col:not(.k-group-col, .k-hierarchy-col)",
HEADERCELLS = "th.k-header:not(.k-group-cell):not(.k-hierarchy-cell)",
CARET_ALT_DOWN = "a[class*='-i-caret-alt-down']",
CARET_ALT_RIGHT = "a[class*='-i-caret-alt-right']",
CARET_ALT_RIGHT_CACHE = CARET_ALT_RIGHT,
CARET_ALT_LEFT = "a[class*='-i-caret-alt-left']",
WRAPPER = ".k-grid",
NS = ".kendoGrid",
CONTENTRLOCKEDCONTAINER = "k-grid-content-locked",
GROUPCELLCLASS = "k-group-cell",
INPUT_SELECTORS = ":button,a,:input,a>.k-icon,a>.k-svg-icon,textarea,span.k-select,span.k-icon,span.k-svg-icon,span.k-svg-icon>svg,span.k-svg-icon>svg>path,span.k-link,label.k-checkbox-label,.k-input,.k-multiselect-wrap,.k-picker-wrap,.k-picker-wrap>.k-selected-color,.k-tool-icon,.k-dropdownlist,.k-switch-thumb,.k-switch-track,.k-switch-label-off,.k-switch-label-on",
EDIT = "edit",
BEFOREEDIT = "beforeEdit",
SAVE = "save",
REMOVE = "remove",
DETAILINIT = "detailInit",
FILTERMENUINIT = "filterMenuInit",
COLUMNMENUINIT = "columnMenuInit",
FILTERMENUOPEN = "filterMenuOpen",
COLUMNMENUOPEN = "columnMenuOpen",
CELLCLOSE = "cellClose",
CHANGING = "changing",
CHANGE = "change",
COLUMNHIDE = "columnHide",
COLUMNSHOW = "columnShow",
SAVECHANGES = "saveChanges",
DATABOUND = "dataBound",
DETAILEXPAND = "detailExpand",
DETAILCOLLAPSE = "detailCollapse",
ITEM_CHANGE = "itemchange",
PAGE = "page",
PAGING = "paging",
PASTE = "paste",
SCROLL = "scroll",
SYNC = "sync",
LOAD_START = "loadStart",
LOAD_END = "loadEnd",
REQUESTEND = "requestEnd",
FOCUSED = "k-focus",
HOVER = "k-hover",
ACTIVE = "k-active",
FOCUSABLE = ":kendoFocusable",
FOCUSABLE_GRID_ELEMENT_SELECTORS = ".k-command-cell,.k-select-checkbox",
SELECTED = "k-selected",
CHECKBOX = "k-checkbox",
CHECKBOXINPUT = "input[data-role='checkbox'].k-select-checkbox." + CHECKBOX,
NORECORDSCLASS = "k-grid-norecords",
LINK_CLASS = "k-link",
ICON_CLASS = "k-icon",
SVG_ICON_CLASS = "k-svg-icon",
ORDER_CLASS = "k-sort-order",
SORTED_CLASS = "k-sorted",
HEADER_CLASS = "k-header",
HEADER_COLUMN_MENU_CLASS = "k-grid-column-menu",
FILTER_MENU_CLASS = "k-grid-filter-menu",
STICKY_CELL_CLASS = "k-grid-content-sticky",
STICKY_HEADER_CLASS = "k-grid-header-sticky",
STICKY_FOOTER_CLASS = "k-grid-footer-sticky",
STICKY_HEADER_NO_BORDER_CLASS = "k-grid-no-left-border",
ROW_RESIZER = "k-row-resizer",
ROW_RESIZER_WRAP = "k-resizer-wrap",
GROUPING_ROW = "k-grouping-row",
RESIZE = "resize",
ROWRESIZE = "rowResize",
COLUMNRESIZE = "columnResize",
COLUMNREORDER = "columnReorder",
COLUMNLOCK = "columnLock",
COLUMNUNLOCK = "columnUnlock",
COLUMNSTICK = "columnStick",
COLUMNUNSTICK = "columnUnstick",
ROWREORDER = "rowReorder",
NAVIGATE = "navigate",
CLICK = "click",
MOUSEDOWN = "mousedown",
MOUSEUP = "mouseup",
MOUSEENTER = "mouseenter",
MOUSELEAVE = "mouseleave",
MOUSEMOVE = "mousemove",
DUBLECLICK = "dblclick",
HEIGHT = "height",
WIDTH = "width",
AUTO = "auto",
TABINDEX = "tabIndex",
FUNCTION = "function",
STRING = "string",
BOTTOM = "bottom",
CONTAINER_FOR = "container-for",
FIELD = "field",
INPUT = "input",
INCELL = "incell",
INLINE = "inline",
UNIQUE_ID = "uid",
MINCOLSPANVALUE = 1,
COLSPAN = "colSpan",
OVERFLOW = "overflow",
HIDDEN = "hidden",
SORT = "sort",
GROUP_SORT = "group-sort",
DELETECONFIRM = "Are you sure you want to delete this record?",
NORECORDS = "No records available.",
CONFIRMDELETE = "Delete",
CANCELDELETE = "Cancel",
COLLAPSE = "Collapse",
EXPAND = "Expand",
ID = "id",
PX = "px",
TR = "tr",
TH = "th",
TD = "td",
DIV = "div",
ARIA_LABEL = "aria-label",
ARIA_OWNS = "aria-owns",
ARIA_ROWCOUNT = "aria-rowcount",
ARIA_COLCOUNT = "aria-colcount",
ARIA_CONTROLS = "aria-controls",
ARIA_COLINDEX = "aria-colindex",
ARIA_ROWINDEX = "aria-rowindex",
ARIA_EXPANDED = "aria-expanded",
ARIA_CHECKED = "aria-checked",
ARIA_ACTIVEDESCENDANT = "aria-activedescendant",
ROLE = "role",
NONE = "none",
ROW = "row",
ROWGROUP = "rowgroup",
COLUMNHEADER = "columnheader",
GRIDCELL = "gridcell",
formatRegExp = /(\}|\#)/ig,
whitespaceRegExp = "[\\x20\\t\\r\\n\\f]",
nonDataCellsRegExp = new RegExp("(^|" + whitespaceRegExp + ")" + "(k-group-cell|k-hierarchy-cell)" + "(" + whitespaceRegExp + "|$)"),
filterRowRegExp = new RegExp("(^|" + whitespaceRegExp + ")" + "(k-filter-row)" + "(" + whitespaceRegExp + "|$)"),
COMMANDBUTTONTMPL = ({ className, attr, text }) => `<button type="button" class="${className}" ${attr}>${kendo.htmlEncode(text)}</button>`,
DEFAULTSELECTCOLUMNTMPL = (size, ariaLabel) => `<span class="k-checkbox-wrap"><input tabindex="-1" class="k-select-checkbox ${CHECKBOX} ${size} k-rounded-md" data-role="checkbox" aria-label="${ariaLabel}" aria-checked="false" type="checkbox"></span>`,
SELECTCOLUMNTMPL = ({ size }) => DEFAULTSELECTCOLUMNTMPL(size, "Select row"),
SELECTCOLUMNHEADERTMPL = ({ size }) => DEFAULTSELECTCOLUMNTMPL(size, "Select all rows"),
DRAGHANDLECOLUMNTMPL = () => kendo.ui.icon("reorder"),
DEFAULTHEADERTEMPLATE = ({ text }) => `<span class="k-cell-inner"><span class="k-link"><span class="k-column-title">${text}</span></span></span>`,
isRtl = false,
browser = kendo.support.browser;
var isIE11 = browser.msie && browser.version === 11;
var isMac = /Mac OS/.test(navigator.userAgent);
var classNames = {
content: "k-content",
scrollContainer: "k-scroll-container",
headerCellInner: "k-cell-inner"
};
var GroupsPager;
var defaultBodyContextMenu = [
"copySelection",
"copySelectionNoHeaders",
"paste",
"separator",
"create",
"edit",
"destroy",
"select",
"separator",
"reorderRow",
"exportPDF",
"exportExcel",
"separator"
];
var defaultHeadContextMenu = [
"sortAsc",
"sortDesc",
"separator"
];
var defaultGroupsContextMenu = [
"moveGroupPrevious",
"moveGroupNext",
"separator"
];
const defaultActionSheetFooterButtons = {
sort: [
{
command: "clear-sort",
text: "Clear Sorting",
size: "large",
fillMode: "solid",
themeColor: "base",
icon: "x"
},
{
command: "done",
text: "Done",
size: "large",
themeColor: "primary",
icon: "check"
}
],
group: [
{
command: "clear-group",
text: "Clear Grouping",
size: "large",
fillMode: "solid",
themeColor: "base",
icon: "x"
},
{
command: "done",
text: "Done",
size: "large",
themeColor: "primary",
icon: "check"
}
],
filter: [
{
command: "clear-filter",
text: "Clear All Filters",
size: "large",
fillMode: "solid",
themeColor: "base",
icon: "filter-clear"
},
],
"column-chooser": [
{
text: "Reset",
icon: "arrow-rotate-ccw",
},
{
text: "Apply",
themeColor: "primary",
icon: "check",
},
],
};
if (ui.Pager) {
GroupsPager = ui.Pager.extend({
init: function(element, options) {
ui.Pager.fn.init.call(this, element, extend(true, {}, options));
this.dataSource.options.useRanges = true;
this.dataSource._omitPrefetch = true;
},
options: {
name: "GroupsPager"
},
totalPages: function() {
var that = this;
return Math.ceil((that._collapsedTotal() || 0) / (that.pageSize() || 1));
},
_collapsedTotal: function() {
var dataSource = this.dataSource;
return dataSource ? (dataSource.groupsTotal(true) || 0) : 0;
}
});
}
var VirtualScrollable = Widget.extend({
init: function(element, options) {
var that = this;
Widget.fn.init.call(that, element, options);
that._refreshHandler = that.refresh.bind(that);
that.setDataSource(options.dataSource);
that.wrap();
},
setDataSource: function(dataSource) {
var that = this;
if (that.dataSource) {
that.dataSource.unbind(CHANGE, that._refreshHandler);
}
that.dataSource = dataSource;
that.dataSource.bind(CHANGE, that._refreshHandler);
that.dataSource.options.useRanges = true;
that.dataSource.options.virtual = true;
},
options: {
name: "VirtualScrollable",
itemHeight: $.noop,
prefetch: true,
maxScrollHeight: 250000
},
events: [
PAGING,
PAGE,
SCROLL,
LOAD_START,
LOAD_END
],
destroy: function() {
var that = this;
Widget.fn.destroy.call(that);
that.dataSource.unbind(CHANGE, that._refreshHandler);
that.wrapper.add(that.verticalScrollbar).off(NS);
clearTimeout(that._timeout);
if (that._scrollingTimeout) {
clearTimeout(that._scrollingTimeout);
}
if (that.drag) {
that.drag.destroy();
that.drag = null;
}
that.wrapper = that.element = that.verticalScrollbar = null;
that._refreshHandler = null;
},
wrap: function() {
var that = this,
// workaround for IE issue where scroll is not raised if container is same width as the scrollbar
scrollbar = kendo.support.scrollbar() + 1,
element = that.element,
wrapper;
element.css({
width: AUTO,
overflow: "hidden"
}).css((isRtl ? "padding-left" : "padding-right"), scrollbar);
that.content = element.children().first();
wrapper = that.wrapper = that.content.wrap('<div class="k-virtual-scrollable-wrap"/>')
.parent()
.on("DOMMouseScroll" + NS + " mousewheel" + NS, that._wheelScroll.bind(that));
that._wrapper();
if (kendo.support.kineticScrollNeeded || kendo.support.touch) {
that.wrapper.css("touch-action", NONE);
that.drag = new kendo.UserEvents(that.wrapper, {
global: true,
allowSelection: true,
start: function(e) {
e.sender.capture();
},
move: function(e) {
that.verticalScrollbar.scrollTop(that.verticalScrollbar.scrollTop() - e.y.delta);
kendo.scrollLeft(wrapper, kendo.scrollLeft(wrapper) - e.x.delta);
e.preventDefault();
}
});
}
that.verticalScrollbar = $('<div class="k-scrollbar k-scrollbar-vertical" tabindex="-1"/>')
.css({
width: scrollbar
}).appendTo(element)
.on("scroll" + NS, that._scroll.bind(that));
},
_wrapper: function() {
var that = this;
if (isIE11) {
//scrolling the virtual scrollbar to the bottom and then
//scrolling the horizontal content scrollbar does not fire the "scroll" event
//seems like a problem in IE 11 only (after version 11.0.9600.18860)
//https://github.com/telerik/kendo-ui-core/issues/3779
that.wrapper.css({
"overflow-y": SCROLL
});
//hide the wrapper behind the virtual scrollbar
that.element.css((isRtl ? "padding-left" : "padding-right"), 0);
}
},
_wheelScroll: function(e) {
if (e.ctrlKey) {
return;
}
var scrollbar = this.verticalScrollbar,
scrollTop = scrollbar.scrollTop(),
delta = kendo.wheelDeltaY(e);
if (delta && !(delta > 0 && scrollTop === 0) && !(delta < 0 && scrollTop + scrollbar[0].clientHeight == scrollbar[0].scrollHeight)) {
e.preventDefault();
this.verticalScrollbar.scrollTop(scrollTop + (-delta));
}
},
_scroll: function(e) {
var that = this,
delayLoading = !that.options.prefetch,
scrollTop = e.currentTarget.scrollTop,
dataSource = that.dataSource,
rowHeight = that.itemHeight,
skip = dataSource.skip() || 0,
start = that._rangeStart || skip,
height = that.element.innerHeight(),
isScrollingUp = !!(that._scrollbarTop && that._scrollbarTop > scrollTop),
firstItemIndex = math.max(math.floor(scrollTop / rowHeight), 0),
lastItemOffset = isScrollingUp ? math.ceil(height / rowHeight) : math.floor(height / rowHeight),
lastItemIndex = math.max(firstItemIndex + lastItemOffset, 0);
if (that._preventScroll) {
that._preventScroll = false;
return;
}
that._prevScrollTop = that._scrollTop;
that._scrollTop = scrollTop - (start * rowHeight);
that._scrollbarTop = scrollTop;
that._scrolling = delayLoading;
if (!that._fetch(firstItemIndex, lastItemIndex, isScrollingUp)) {
that.wrapper[0].scrollTop = that._scrollTop;
}
that.trigger(SCROLL);
if (delayLoading) {
if (that._scrollingTimeout) {
clearTimeout(that._scrollingTimeout);
}
that._scrollingTimeout = setTimeout(function() {
that._scrolling = false;
that._page(that._rangeStart, that.dataSource.take());
}, 100);
}
},
scrollToTop: function() {
this._scrollTo(0);
},
scrollToBottom: function() {
var scrollbar = this.verticalScrollbar;
this._scrollTo(scrollbar[0].scrollHeight - scrollbar.height());
},
_scrollWrapperToTop: function() {
this.wrapper.scrollTop(0);
},
_scrollWrapperToBottom: function() {
this.wrapper.scrollTop(this.wrapper[0].scrollHeight);
},
_scrollWrapperOnColumnResize: function() {
var that = this;
var wrapper = this.wrapper;
var initialScrollTop = wrapper.scrollTop();
if (wrapper[0].scrollWidth > wrapper[0].clientWidth) {
if ((!that._wrapperScrolled && initialScrollTop) || that._isScrolledToBottom()) {
wrapper.scrollTop(initialScrollTop + kendo.support.scrollbar());
that._scrollTop = wrapper.scrollTop();
that._wrapperScrolled = true;
}
} else if (that._wrapperScrolled) {
if (!that._isWrapperScrolledToBottom()) {
wrapper.scrollTop(initialScrollTop - kendo.support.scrollbar());
that._scrollTop = wrapper.scrollTop();
}
that._wrapperScrolled = false;
}
},
_scrollTo: function(scrollTop, programmaticScrollPosition) {
var that = this;
var scrollbar = that.verticalScrollbar;
if (scrollbar.scrollTop() !== scrollTop) {
that._preventScroll = true;
}
that.wrapper.scrollTop(scrollTop);
that._scrollTop = that.wrapper.scrollTop();
scrollbar.scrollTop(programmaticScrollPosition ?? scrollTop);
that._scrollbarTop = scrollbar.scrollTop();
},
_isScrolledToTop: function() {
return this.verticalScrollbar.scrollTop() === 0;
},
_isScrolledToBottom: function() {
var scrollbar = this.verticalScrollbar;
var scrollTop = scrollbar.scrollTop();
return (scrollTop > 0 && scrollTop >= parseInt(scrollbar[0].scrollHeight - scrollbar.height(), 10));
},
_isWrapperScrolledToBottom: function() {
var wrapper = this.wrapper;
return (wrapper.scrollTop() >= parseInt(wrapper[0].scrollHeight - wrapper.height(), 10));
},
itemIndex: function(rowIndex) {
var rangeStart = this._rangeStart || this.dataSource.skip() || 0;
return rangeStart + rowIndex;
},
position: function(index) {
var rangeStart = this._rangeStart || this.dataSource.skip() || 0;
var pageSize = this.dataSource.pageSize();
var result;
if (index > rangeStart) {
result = index - rangeStart;
} else {
result = rangeStart - index - 1;
}
return result > pageSize ? pageSize : result;
},
scrollIntoView: function(row) {
var container = this.wrapper[0];
var containerHeight = container.clientHeight;
var containerScroll = !this._isScrolledToBottom() ? (this._scrollTop || container.scrollTop) : container.scrollTop;
var elementOffset = row[0].offsetTop;
var elementHeight = row[0].offsetHeight;
if (containerScroll > elementOffset) {
this.verticalScrollbar[0].scrollTop -= containerHeight / 2;
} else if (elementOffset + elementHeight >= containerScroll + containerHeight) {
this.verticalScrollbar[0].scrollTop += containerHeight / 2;
}
},
_fetch: function(firstItemIndex, lastItemIndex, scrollingUp) {
var that = this,
dataSource = that.dataSource,
itemHeight = that.itemHeight,
take = dataSource.take(),
rangeStart = that._rangeStart || dataSource.skip() || 0,
currentSkip = math.floor(firstItemIndex / take) * take,
fetching = false,
prefetchAt = 0.33;
var scrollbar = that.verticalScrollbar;
var webkitCorrection = browser.webkit ? 1 : 0;
var total = dataSource._isGroupPaged() ? dataSource.groupsTotal(true) : dataSource.total();
if (firstItemIndex < rangeStart) {
fetching = true;
if (that._alwaysScrollTop) {
rangeStart = math.min(firstItemIndex, total - take);
that._scrollTop = 0;
} else {
rangeStart = math.max(0, lastItemIndex - take);
that._scrollTop = scrollbar.scrollTop() - (rangeStart * itemHeight);
}
that._page(rangeStart, take);
} else if (lastItemIndex >= rangeStart + take && !scrollingUp) {
fetching = true;
rangeStart = math.min(firstItemIndex, total - take);
//ensure the scrollbar can be scrolled to bottom with mouse drag
if (scrollbar.scrollTop() >= scrollbar[0].scrollHeight - scrollbar[0].offsetHeight - webkitCorrection) {
that._scrollTop = that.wrapper[0].scrollHeight - that.wrapper[0].offsetHeight;
} else if (that.dataSource._isGroupPaged() && firstItemIndex >= total - take) {
that._scrollTop = that.wrapper[0].scrollHeight - that.wrapper[0].offsetHeight - (that._scrollTop - that._prevScrollTop);
} else if (that._alwaysScrollTop) {
that._scrollTop = 0;
} else {
that._scrollTop = itemHeight;
}
that._page(rangeStart, take);
} else if (!that._fetching && that.options.prefetch) {
if (firstItemIndex < (currentSkip + take) - take * prefetchAt && firstItemIndex > take) {
dataSource.prefetch(currentSkip - take, take, $.noop);
}
if (lastItemIndex > currentSkip + take * prefetchAt) {
dataSource.prefetch(currentSkip + take, take, $.noop);
}
}
return fetching;
},
fetching: function() {
return this._fetching;
},
_page: function(skip, take, callback) {
var that = this,
delayLoading = !that.options.prefetch,
dataSource = that.dataSource,
isGroupPaged = dataSource._isGroupPaged();
callback = isFunction(callback) ? callback : $.noop;
if (that.trigger(PAGING, { skip: skip, take: take })) {
return;
}
clearTimeout(that._timeout);
that._fetching = true;
that._rangeStart = skip;
if ((isGroupPaged && dataSource._groupRangeExists(skip, skip + take)) || (!isGroupPaged && dataSource.inRange(skip, take))) {
that.trigger(LOAD_START);
dataSource.range(skip, take, function() {
that.trigger(LOAD_END);
callback();
that.trigger(PAGE);
}, "page");
} else {
if (!delayLoading) {
that.trigger(LOAD_START);
}
that._timeout = setTimeout(function() {
if (!that._scrolling) {
if (delayLoading) {
that.trigger(LOAD_START);
}
dataSource.range(skip, take, function() {
that.trigger(LOAD_END);
callback();
that.trigger(PAGE);
});
}
}, 100);
}
},
repaintScrollbar: function(shouldScrollWrapper) {
var that = this,
maxHeight = that.options.maxScrollHeight,
dataSource = that.dataSource,
scrollbar = !kendo.support.kineticScrollNeeded ? kendo.support.scrollbar() : 0,
wrapperElement = that.wrapper[0],
totalHeight,
itemHeight;
var wasScrolledToBottom = that._isScrolledToBottom();
itemHeight = that.itemHeight = that.options.itemHeight() || 0;
var addScrollBarHeight = (wrapperElement.scrollWidth > wrapperElement.offsetWidth) ? scrollbar : 0;
totalHeight = (dataSource._isGroupPaged() ? dataSource.groupsTotal(true) : dataSource.total()) * itemHeight + addScrollBarHeight;
var divElements = $(new Array(math.floor(totalHeight / maxHeight) + 1).join('<div></div>'))
.css({
width: "1px",
height: `${maxHeight}px`
});
if (totalHeight % maxHeight) {
divElements = divElements.add($("<div></div>").css({
width: "1px",
height: `${(totalHeight % maxHeight)}px`
}));
}
that.verticalScrollbar.empty().append(divElements);
if (wasScrolledToBottom && !that._isScrolledToBottom() && !that.dataSource._isGroupPaged()) {
that.scrollToBottom();
}
if (typeof (that._scrollTop) !== "undefined" && !!shouldScrollWrapper) {
wrapperElement.scrollTop = that._scrollTop;
that._scrollWrapperOnColumnResize();
}
},
refresh: function(e) {
var that = this,
dataSource = that.dataSource,
rangeStart = that._rangeStart;
var action = (e || {}).action;
var shouldScrollWrapper = that._isScrolledToBottom() || !action || (action !== ITEM_CHANGE && action !== REMOVE && action !== SYNC);
that.trigger(LOAD_END);
clearTimeout(that._timeout);
that.repaintScrollbar(shouldScrollWrapper);
if (that.drag) {
that.drag.cancel();
}
if (typeof (rangeStart) !== "undefined" && !that._fetching) { // we are rebound from outside local range should be reset
if (!action || (action !== SYNC && action !== ITEM_CHANGE && action !== "expandGroup")) {
that._rangeStart = dataSource.skip();
}
if (dataSource.page() === 1 && (!action || (action !== SYNC && action !== ITEM_CHANGE && action !== "expandGroup" && action !== "collapseGroup"))) {
// reset the scrollbar position if datasource is filtered
that.verticalScrollbar[0].scrollTop = 0;
}
}
if (that._programmaticallyScrolling && that._programmaticallyScrolling.state() !== 'resolved') {
that._programmaticallyScrolling.resolve();
}
if (that._alwaysScrollTop) {
delete that._alwaysScrollTop;
}
that._fetching = false;
}
});
function attrEquals(attrName, attrValue) {
return "[" + kendo.attr(attrName) + "=" + attrValue + "]";
}
function groupCells(count) {
return new Array(count + 1).join('<td class="k-group-cell k-table-group-td k-table-td"> </td>');
}
function cellsExcludingSpecialColumns(cells) {
return cells.filter((i, cell) => {
const $cell = $(cell);
const hasCheckbox = $cell.children(".k-select-checkbox").length > 0;
const hasWrappedCheckbox = $cell.find("> .k-checkbox-wrap > .k-select-checkbox").length > 0;
return $cell.attr("[ref-grid-drag-cell]") === undefined$1 && !$cell.hasClass("k-command-cell") && !hasCheckbox && !hasWrappedCheckbox;
});
}
function stringifyAttributes(attributes) {
var attr,
result = " ";
if (attributes) {
if (typeof attributes === STRING) {
return attributes;
}
for (attr in attributes) {
if (attributes[attr] !== '') {
result += attr + '="' + attributes[attr] + '"';
}
}
}
return result;
}
var defaultCommands = {
create: {
text: "Add",
className: "k-grid-add",
iconClass: "k-i-plus"
},
cancel: {
text: "Cancel changes",
className: "k-grid-cancel-changes",
iconClass: "k-i-cancel"
},
save: {
text: "Save changes",
className: "k-grid-save-changes",
iconClass: "k-i-check"
},
destroy: {
text: "Delete",
className: "k-grid-remove-command",
iconClass: "k-i-trash"
},
edit: {
text: "Edit",
className: "k-grid-edit-command",
iconClass: "k-i-pencil",
},
update: {
text: "Save",
className: "k-grid-save-command",
iconClass: "k-i-save",
},
canceledit: {
text: "Cancel",
className: "k-grid-cancel-command",
iconClass: "k-i-cancel"
},
excel: {
text: "Export to Excel",
className: "k-grid-excel",
iconClass: "k-i-file-excel"
},
pdf: {
text: "Export to PDF",
className: "k-grid-pdf",
iconClass: "k-i-file-pdf"
},
search: {
text: "Search...",
className: "k-grid-search"
},
columns: {
text: "Columns",
type: "button",
icon: "columns",
fillMode: "flat",
overflow: "never",
className: "k-grid-column-menu",
attr: {
"aria-haspopup": "menu"
}
},
columnchooser: {
text: "Columns",
type: "button",
icon: "columns",
overflow: "never",
className: "k-grid-column-chooser",
attr: {
"aria-haspopup": "menu"
},
},
sort: {
text: "Sort",
type: "button",
icon: "arrows-swap",
overflow: "never",
className: "k-grid-sort-tool",
attr: {
"aria-haspopup": "menu",
},
clearButton: true,
},
filter: {
text: "Filter",
type: "button",
icon: "filter",
overflow: "never",
className: "k-grid-filter-tool",
attr: {
"aria-haspopup": "menu",
},
clearButton: true,
},
group: {
text: "Group",
type: "button",
icon: "group",
overflow: "never",
className: "k-grid-group-tool",
attr: {
"aria-haspopup": "menu",
},
clearButton: true,
},
};
function cursor(context, value) {
$('th, th .k-grid-filter-menu, th .k-link', context)
.add(document.body)
.css('cursor', value);
}
function reorder(selector, source, dest, before, count) {
var sourceIndex = source;
source = $();
count = count || 1;
for (var idx = 0; idx < count; idx++) {
source = source.add(selector.eq(sourceIndex + idx));
}
if (typeof dest == "number") {
source[before ? "insertBefore" : "insertAfter"](selector.eq(dest));
} else {
source.appendTo(dest);
}
}
function elements(lockedContent, content, filter) {
return $(lockedContent).add(content).find(filter);
}
function attachCustomCommandEvent(context, container, commands) {
var idx,
length,
command,
commandName;
commands = !isArray(commands) ? [commands] : commands;
for (idx = 0, length = commands.length; idx < length; idx++) {
command = commands[idx];
if (isPlainObject(command) && command.click) {
commandName = command.name || command.text;
container.on(CLICK + NS, ".k-grid-" + (commandName || "").replace(/\s/g, ""), { commandName: commandName }, command.click.bind(context));
}
}
}
function normalizeColumns(columns, encoded, hide, locked, parentIds) {
return map(columns, function(column) {
column = typeof column === STRING ? { field: column } : column;
var hidden;
column.parentIds = parentIds;
if (column.attributes instanceof Function) {
column._attributesFunction = column.attributes;
}
if (!isVisible(column) || hide) {
column.attributes = addHiddenStyle(column.attributes);
column.footerAttributes = addHiddenStyle(column.footerAttributes);
column.headerAttributes = addHiddenStyle(column.headerAttributes);
hidden = true;
} else if (isVisible(column) || !hide) {
column.attributes = removeHiddenStyle(column.attributes);
column.footerAttributes = removeHiddenStyle(column.footerAttributes);
column.headerAttributes = removeHiddenStyle(column.headerAttributes);
hidden = undefined$1;
}
var uid = kendo.guid();
if (locked && !column.locked) {
column.locked = locked;
}
column.headerAttributes = extend({ headers: parentIds }, column.headerAttributes);
if (!column.headerAttributes.id) {
column.headerAttributes = extend({ id: uid }, column.headerAttributes);
column.uid = uid;
} else {
column.uid = uid = column.headerAttributes.id;
}
if (column.columns) {
column.columns = normalizeColumns(column.columns, encoded, hidden, column.locked, parentIds ? (parentIds + " " + uid) : uid);
}
return extend({ encoded: encoded, hidden: hidden, locked: locked }, column);
});
}
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 setColumnVisibility(column, visible) {
setVisibility(column, visible, visible);
}
function setVisibility(column, visible, show) {
var method = show ? removeHiddenStyle : addHiddenStyle;
column.hidden = !visible;
column.attributes = method(column.attributes);
column.footerAttributes = method(column.footerAttributes);
column.headerAttributes = method(column.headerAttributes);
}
function setColumnMediaVisibility(column, visible) {
setColumnMatchesMedia(column);
var hideByMedia = column._hideByMedia;
setVisibility(column, visible, hideByMedia ? column.matchesMedia : visible);
}
function setColumnMatchesMedia(column) {
column.matchesMedia = columnMatchesMedia(column);
}
function columnMatchesMedia(column) {
return column && (isUndefined(column.media) || (!isUndefined(column.media) && kendo.matchesMedia(column.media)));
}
function isCellVisible() {
return this.style.display !== NONE && !this.classList.contains("k-hidden");
}
function isElementVisible(element) {
return $(element)[0].style.display !== NONE && !$(element)[0].classList.contains("k-hidden");
}
function isVisible(column) {
return visibleColumns([column]).length > 0;
}
function visibleColumns(columns) {
return grep(columns, function(column) {
var result = !column.hidden && column.matchesMedia !== false;
if (result && column.columns) {
result = visibleColumns(column.columns).length > 0;
}
return result;
});
}
function columnsWithMedia(columns) {
var result = [];
var column;
for (var i = 0; i < columns.length; i++) {
column = columns[i];
if (!isUndefined(column.media)) {
if (!isUndefined(column.minScreenWidth)) {
throw new Error("Using 'media' and 'minScreenWidth' options at the same time is not supported.");
}
result.push(column);
}
if (column.columns) {
result = result.concat(columnsWithMedia(column.columns));
}
}
return result;
}
function isUndefined(value) {
return typeof value === "undefined";
}
function toJQuery(elements) {
return $(elements).map(function() { return this.toArray(); });
}
function updateCellRowSpan(cell, columns, sourceLockedColumnsCount) {
var lockedColumnDepth = depth(lockedColumns(columns));
var nonLockedColumnDepth = depth(nonLockedColumns(columns));
var rowSpan = cell.rowSpan;
if (sourceLockedColumnsCount) {
if (lockedColumnDepth > nonLockedColumnDepth) {
cell.rowSpan = (rowSpan - (lockedColumnDepth - nonLockedColumnDepth)) || 1;
} else {
cell.rowSpan = rowSpan + (nonLockedColumnDepth - lockedColumnDepth);
}
} else {
if (lockedColumnDepth > nonLockedColumnDepth) {
cell.rowSpan = rowSpan + (lockedColumnDepth - nonLockedColumnDepth);
} else {
cell.rowSpan = (rowSpan - (nonLockedColumnDepth - lockedColumnDepth)) || 1;
}
}
}
function findColumnByField(columns, field) {
for (var i = 0; i < columns.length; i++) {
if (columns[i].field == field) {
return columns[i];
}
}
}
function getToolbarRegex({ mode, hasSelected, hasChanges, editContainerVisible, differentSelectionThanEditing, _editableIsClosing, _isEditableEnabled, options }) {
const editableCommands = /\b(k-grid-edit-command|k-grid-remove-command|k-grid-save-changes|k-grid-cancel-changes|k-grid-cancel-command|k-grid-save-command)\b/;
const commands = [];
if (!_isEditableEnabled || !options.editable) {
return editableCommands;
}
if (!hasSelected) {
commands.push("k-grid-edit-command");
commands.push("k-grid-remove-command");
}
if (hasSelected && (mode === "incell" || (mode === "inline" && !differentSelectionThanEditing))) {
commands.push("k-grid-edit-command");
}
if (!hasChanges) {
commands.push("k-grid-save-changes");
commands.push("k-grid-cancel-changes");
}
if (mode !== "inline" || (!editContainerVisible || (editContainerVisible && _editableIsClosing))) {
commands.push("k-grid-save-command");
commands.push("k-grid-cancel-command");
}
let regex = "";
if (commands.length) {
regex = commands.join("|");
regex = `\\b(${regex})\\b`;
return new RegExp(regex);
}
return regex;
}
function moveCellsBetweenContainers(sources, target, leafs, columns, container, destination, groups, action) {
var sourcesDepth = depth(sources);
var targetDepth = depth([target]);
if (sourcesDepth > targetDepth) {
var groupCells = new Array(groups + 1).join('<th class="k-group-cell k-header k-table-th" scope="col"> </th>');
var rows = destination.children(":not(.k-filter-row)");
$(new Array((sourcesDepth - targetDepth) + 1).join("<tr class='k-table-row'>" + groupCells + "</tr>")).insertAfter(rows.last());
}
addRowSpanValue(destination, sourcesDepth - targetDepth);
moveCells(leafs, columns, container, destination, action);
}
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(DOT + HEADER_CLASS)
.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 moveCells(leafs, columns, container, destination, action) {
var sourcePosition = columnVisiblePosition(leafs[0], columns);
var ths = container.find(">tr:not(.k-filter-row)").eq(sourcePosition.row).children("th.k-header:not(.k-group-cell)");
var t = $();
var sourceIndex = sourcePosition.cell;
var idx;
for (idx = 0; idx < leafs.length; idx++) {
t = t.add(ths.eq(sourceIndex + idx));
}
destination.find(">tr:not(.k-filter-row)").eq(sourcePosition.row)[action](t);
var children = [];
for (idx = 0; idx < leafs.length; idx++) {
if (leafs[idx].columns) {
children = children.concat(leafs[idx].columns);
}
}
if (children.length) {
moveCells(children, columns, container, destination, action);
}
}
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 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 decorateCellWithClass(html) {
let element = html;
let classes = element.match(/class=["][^"]+/g);
if (classes) {
const cssClasses = classes[0].split('\"').pop();
element = element.replace(cssClasses, cssClasses + " k-table-td");
} else {
element = element.replace("<td", "<td class='k-table-td'");
}
return element;
}
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) {
index++;
} else if ((index == parentColumns.length - 1 && !before) || (!source.locked && !target.columns && !before)) {
index--;
} else if (index > 0 || (index === 0 && !before)) {
index++;
}
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 columnVisiblePosition(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 = columnVisiblePosition(column, columns[idx].columns, row + 1, cellCounts);
if (result) {
break;
}
}
if (!columns[idx].hidden) {
cellCounts[row]++;
}
}
return result;
}
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 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 hiddenLeafColumnsCount(columns) {
var counter = 0;
var column;
for (var idx = 0; idx < columns.length; idx++) {
column = columns[idx];
if (column.columns) {
counter += hiddenLeafColumnsCount(column.columns);
} else if (column.hidden) {
counter++;
}
}
return counter;
}
function sumWidths(cols) {
var width = 0;
for (var idx = 0, length = cols.length; idx < length; idx++) {
if (!cols[idx].hidden) {
width += parseInt(cols[idx].width, 10);
}
}
return width;
}
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 removeRowSpanValue(container, count) {
var cells = container.find("tr:not(.k-filter-row) th:not(.k-group-cell,.k-hierarchy-cell)");
var rowSpan;
for (var idx = 0; idx < cells.length; idx++) {
rowSpan = cells[idx].rowSpan;
if (rowSpan > 1) {
cells[idx].rowSpan = (rowSpan - count) || 1;
}
}
}
function addRowSpanValue(container, count) {
var cells = container.find("tr:not(.k-filter-row) th:not(.k-group-cell,.k-hierarchy-cell)");
for (var idx = 0; idx < cells.length; idx++) {
cells[idx].rowSpan += count;
}
}
function removeEmptyRows(container) {
var rows = container.find("tr:not(.k-filter-row)");
var emptyRowsCount = rows.filter(function() {
return !$(this).children().length;
}).remove().length;
var cells = rows.find("th:not(.k-group-cell,.k-hierarchy-cell)");
for (var idx = 0; idx < cells.length; idx++) {
if (cells[idx].rowSpan > 1) {
cells[idx].rowSpan -= emptyRowsCount;
}
}
return rows.length - emptyRowsCount;
}
function mapColumnToCellRows(columns, cells, rows, rowIndex, offset) {
var idx, row, length, children = [];
for (idx = 0, length = columns.length; idx < length; idx++) {
row = rows[rowIndex] || [];
row.push(cells.eq(offset + idx));
rows[rowIndex] = row;
if (columns[idx].columns) {
children = children.concat(columns[idx].columns);
}
}
if (children.length) {
mapColumnToCellRows(children, cells, rows, rowIndex + 1, offset + columns.length);
}
}
function setLeftAndRightStyles(element, left, right) {
element.css({
"left": left,
"right": right
});
}
function createColumnAttribute(column, attribute, property) {
column[attribute] = column[attribute] || {};
column[attribute][property] = column[attribute][property] || "";
}
function addColumnAttribute(column, attribute, property, value) {
createColumnAttribute(column, attribute, property);
if (column[attribute][property] !== "") {
column[attribute][property] += " " + value;
} else {
column[attribute][property] = value;
}
}
function removeColumnAttribute(column, attribute, property, value, removeAttributeProperty) {
createColumnAttribute(column, attribute, property);
if (removeAttributeProperty) {
delete column[attribute][property];
} else {
column[attribute][property] = column[attribute][property].replace(value, "");
}
}
function lockedColumns(columns) {
return grep(columns, function(column) {
return column.locked;
});
}
function nonLockedColumns(columns) {
return grep(columns, function(column) {
return !column.locked;
});
}
function stickyColumns(columns) {
return grep(columns, function(column) {
return column.sticky && !column.locked;
});
}
function visibleStickyColumns(columns) {
return grep(columns, function(column) {
return column.sticky && !column.locked && isVisible(column);
});
}
function visibleNonLockedColumns(columns) {
return grep(columns, function(column) {
return !column.locked && isVisible(column);
});
}
function visibleLockedColumns(columns) {
return grep(columns, function(column) {
return column.locked && isVisible(column);
});
}
function visibleLeafColumns(columns) {
var result = [];
for (var idx = 0; idx < columns.length; idx++) {
if (columns[idx].hidden) {
continue;
}
if (columns[idx].columns) {
result = result.concat(visibleLeafColumns(columns[idx].columns));
} else {
result.push(columns[idx]);
}
}
return result;
}
function visibleLeafExportColumns(columns) {
var result = [];
for (var idx = 0; idx < columns.length; idx++) {
if (columns[idx].hidden) {
continue;
}
if (columns[idx].columns) {
result = result.concat(visibleLeafColumns(columns[idx].columns));
} else {
result.push({
field: columns[idx].field,
width: columns[idx].width,
values: columns[idx].values,
title: columns[idx].title
});
}
}
return result;
}
function childColumns(columns) {
var result = [];
for (var idx = 0; idx < columns.length; idx++) {
if (columns[idx].columns) {
result = result.concat(columns[idx].columns);
}
}
return result;
}
function visibleChildColumns(columns) {
var result = childColumns(columns);
result = result.filter(function(e) {
return !e.hidden;
});
return result;
}
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 editField(column, adaptive) {
return {
field: column.field,
title: column.title,
format: column.format,
editor: column.editor,
values: column.values,
editorOptions: extend(true, { format: column.format, adaptiveMode: adaptive }, column.editorOptions),
label: column.title || column.field || ""
};
}
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")
.filter(filter)
.filter(function() { return this.rowSpan > 1; });
}
cells = cells.add(rows.last().find("th").filter(filter));
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 parentColumnsCells(cell) {
var container = cell.closest("table");
var result = $().add(cell);
var row = cell.closest(TR);
var headerRows = container.find("tr:not(.k-filter-row)");
var level = headerRows.index(row);
if (level > 0) {
var parent = headerRows.eq(level - 1);
var parentCellsWithChildren = parent.find("th:not(.k-group-cell,.k-hierarchy-cell)").filter(function() {
return !$(this).attr("rowspan");
});
var offset = 0;
var index = row.find("th:not(.k-group-cell,.k-hierarchy-cell)").index(cell);
var prevCells = cell.prevAll(":not(.k-group-cell,.k-hierarchy-cell)").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:not(.k-filter-row)");
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(":not(.k-group-cell,.k-hierarchy-cell)");
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:not(.k-group-cell,.k-hierarchy-cell)");
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 appendContent(tbody, table, html, size) {
var placeholder,
tmp = tbody;
if (tbodySupportsInnerHtml) {
let $html = $(html);
kendo.applyStylesFromKendoAttributes($html, ["display", "left", "right"]);
tbody.empty();
$html.each((_, el) => tbody[0].appendChild(el));
} else {
placeholder = document.createElement(DIV);
placeholder.innerHTML = "<table class='k-grid-table k-table'><tbody class='k-table-tbody'>" + html + "</tbody></table>";
$(placeholder).find("table").addClass(kendo.getValidCssClass("k-table-", "size", size));
tbody = placeholder.firstChild.firstChild;
table[0].replaceChild(tbody, tmp[0]);
tbody = $(tbody);
}
return tbody;
}
function addHiddenStyle(attr) {
attr = attr || {};
let kendoStyleAttrObject = {};
kendoStyleAttrObject[kendo.attr("style-display")] = "none";
return extend({}, attr, kendoStyleAttrObject);
}
function hasHiddenStyle(attr) {
attr = attr || {};
return !!attr[kendo.attr("style-display")];
}
function removeHiddenStyle(attr) {
attr = attr || {};
delete attr[kendo.attr("style-display")];
return attr;
}
function normalizeCols(table, visibleColumns, hasDetails, groups) {
var colgroup = table.find(">colgroup"),
width,
cols = map(visibleColumns, function(column) {
width = column.width;
if (width && parseInt(width, 10) !== 0) {
return kendo.format(`<col ${kendo.attr('style-width')}="{0}" ${column.draggable ? 'class=k-drag-col' : ''} />`, typeof width === STRING ? width : width + PX);
}
if (column.draggable) {
return "<col class='k-drag-col' />";
}
return "<col />";
});
if (hasDetails || colgroup.find(".k-hierarchy-col").length) {
cols.splice(0, 0, '<col class="k-hierarchy-col" />');
}
if (colgroup.length) {
colgroup.remove();
}
colgroup = $(new Array(groups + 1).join('<col class="k-group-col">') + cols.join(""));
kendo.applyStylesFromKendoAttributes(colgroup, ["width"]);
if (!colgroup.is("colgroup")) {
colgroup = $("<colgroup/>").append(colgroup);
}
table.prepend(colgroup);
}
function normalizeHeaderCells(container, columns) {
var lastIndex = 0;
var idx, len;
var th = container.find("th:not(.k-group-cell)");
for (idx = 0, len = columns.length; idx < len; idx++) {
if (columns[idx].locked) {
th.eq(idx).insertBefore(th.eq(lastIndex));
th = container.find("th:not(.k-group-cell)");
lastIndex++;
}
}
}
function convertToObject(array) {
var result = {},
item,
idx,
length;
for (idx = 0, length = array.length; idx < length; idx++) {
item = array[idx];
result[item.value] = item.text;
}
return result;
}
function formatGroupValue(value, format, columnValues, encoded) {
let isForeignKey = columnValues && columnValues.length && isPlainObject(columnValues[0]) && "value" in columnValues[0],
groupValue = isForeignKey ? convertToObject(columnValues)[value] : value;
groupValue = groupValue != null ? groupValue : "";
let usedValue = encoded === false ? groupValue : kendo.htmlEncode(groupValue);
return format ? kendo.format(format, usedValue) : usedValue;
}
function setCellVisibility(cells, index, visible) {
var pad = 0,
state,
cell = cells[pad];
while (cell) {
state = visible ? true : cell.style.display !== NONE;
if (visible && cell.classList.contains("k-hidden")) {
cell.classList.remove("k-hidden");
}
if (state && !nonDataCellsRegExp.test(cell.className) && --index < 0) {
cell.style.display = visible ? "" : NONE;
break;
}
cell = cells[++pad];
}
}
function hideColumnCells(rows, columnIndex) {
var idx = 0,
length = rows.length,
cell, row;
for (; idx < length; idx += 1) {
row = rows.eq(idx);
if (row.is(".k-grouping-row,.k-detail-row")) {
cell = row.children(":not(.k-group-cell):first,.k-detail-cell").last();
cell.attr("colspan", parseInt(cell.attr("colspan"), 10) - 1);
} else {
if (row.hasClass("k-grid-edit-row") && (cell = row.children(".k-edit-container")[0])) {
cell = $(cell);
cell.attr("colspan", parseInt(cell.attr("colspan"), 10) - 1);
cell.find("col").eq(columnIndex).remove();
row = cell.find(TR).first();
}
setCellVisibility(row[0].cells, columnIndex, false);
}
}
}
function groupRows(data) {
var result = [];
var item;
for (var idx = 0; idx < data.length; idx++) {
item = data[idx];
if (!("field" in item && "value" in item && "items" in item)) {
break;
}
result.push(item);
if (item.hasSubgroups) {
result = result.concat(groupRows(item.items));
}
}
return result;
}
function showColumnCells(rows, columnIndex) {
var idx = 0,
length = rows.length,
cell, row, columns;
for (; idx < length; idx += 1) {
row = rows.eq(idx);
if (row.is(".k-grouping-row,.k-detail-row")) {
cell = row.children(":not(.k-group-cell):first,.k-detail-cell").last();
cell.attr("colspan", parseInt(cell.attr("colspan"), 10) + 1);
} else {
if (row.hasClass("k-grid-edit-row") && (cell = row.children(".k-edit-container")[0])) {
cell = $(cell);
cell.attr("colspan", parseInt(cell.attr("colspan"), 10) + 1);
normalizeCols(cell.find(">form>table"), visibleColumns(columns), false, 0);
row = cell.find(TR).first();
}
setCellVisibility(row[0].cells, columnIndex, true);
}
}
}
function updateColspan(toAdd, toRemove, num) {
num = num || 1;
var item, idx, length;
for (idx = 0, length = toAdd.length; idx < length; idx++) {
item = toAdd.eq(idx).children(":not([hidden])").last();
item.attr("colspan", parseInt(item.attr("colspan"), 10) + num);
item = toRemove.eq(idx).children(":not([hidden])").last();
item.attr("colspan", parseInt(item.attr("colspan"), 10) - num);
}
}
function tableWidth(table) {
var idx, length, width = 0;
var cols = table.find(">colgroup>col");
for (idx = 0, length = cols.length; idx < length; idx += 1) {
width += parseInt(cols[idx].style.width, 10);
}
return width;
}
var Grid = kendo.ui.DataBoundWidget.extend({
init: function(element, options, events) {
var that = this;
options = isArray(options) ? { dataSource: options } : options;
Widget.fn.init.call(that, element, options);
if (events) {
that._events = events;
}
isRtl = kendo.support.isRtl(element);
CARET_ALT_RIGHT = isRtl ? CARET_ALT_LEFT : CARET_ALT_RIGHT_CACHE;
that._element();
that._ariaId();
that._columns($.extend(true, [], that.options.columns));
that._bindMediaQueries();
if (that._foreignKeyPromises) {
$.when.apply(null, that._foreignKeyPromises)
.then(function() {
that._foreignKeyPromises = null;
that._continueInit();
});
} else {
that._continueInit();
}
},
_continueInit: function() {
var that = this;
that._dataSource();
that._stickyColumns();
that._tbody();
that._thead();
that._rowResizing();
that._groupable();
that._toolbar();
that._initToolbarItemsPopups();
that._pageable();
that._setContentHeight();
that._templates();
that._navigatable();
that._initSelectableAggregates();
that._selectable();
that._statusBar();
that._clipboard();
that._paste();
that._details();
that._editable();
that._attachCustomCommandsEvent();
that._adaptiveColumns();
that._minScreenSupport();
if (that.options.autoBind) {
that.dataSource.fetch();
} else {
that._group = that._groups() > 0;
that._footer();
}
that._setInitialRtlScrollPosition();
if (that.options.contextMenu) {
that._initContextMenu();
}
if (that.lockedContent) {
that.wrapper.addClass("k-grid-lockedcolumns");
that._resizeHandler = function() {
that.resize();
};
$(window).on("resize" + NS, that._resizeHandler);
}
that._initLoader();
kendo.notify(that);
if (that._showWatermarkOverlay) {
that._showWatermarkOverlay(that.wrapper[0]);
}
},
events: [
CHANGE,
CHANGING,
"dataBinding",
"cancel",
DATABOUND,
DETAILEXPAND,
DETAILCOLLAPSE,
DETAILINIT,
FILTERMENUINIT,
FILTERMENUOPEN,
COLUMNMENUINIT,
COLUMNMENUOPEN,
EDIT,
BEFOREEDIT,
SAVE,
REMOVE,
SAVECHANGES,
CELLCLOSE,
ROWRESIZE,
COLUMNRESIZE,
COLUMNREORDER,
COLUMNSHOW,
COLUMNHIDE,
COLUMNLOCK,
COLUMNUNLOCK,
COLUMNSTICK,
COLUMNUNSTICK,
ROWREORDER,
NAVIGATE,
PASTE,
"page",
"sort",
"filter",
"group",
"groupExpand",
"groupCollapse",
"kendoKeydown"
],
setDataSource: function(dataSource) {
var that = this;
var scrollable = that.options.scrollable;
var scrollableContent;
that.options.dataSource = dataSource;
that._dataSource();
that._pageable();
that._thead();
that._rowResizing();
if (scrollable) {
if (scrollable.virtual) {
scrollableContent = that.content.find(">.k-virtual-scrollable-wrap");
kendo.scrollLeft(scrollableContent, leftMostPosition(scrollableContent, isRtl));
} else {
scrollableContent = that.tbody;
kendo.scrollLeft(that.content, leftMostPosition(scrollableContent, isRtl));
}
}
if (that.options.groupable) {
that._groupable();
}
if (that.virtualScrollable) {
that.virtualScrollable.setDataSource(that.options.dataSource);
}
if (that.options.navigatable) {
that._navigatable();
}
if (that.options.selectable) {
that._selectable();
}
if (that.options.autoBind) {
that.dataSource.fetch();
} else {
that._footer();
}
},
options: {
name: "Grid",
adaptiveMode: "none",
columns: [],
toolbar: null,
autoBind: true,
filterable: false,
scrollable: true,
sortable: false,
selectable: false,
allowCopy: false,
allowPaste: false,
navigatable: false,
pageable: false,
persistSelection: false,
editable: false,
encodeTitles: false,
groupable: false,
rowTemplate: "",
altRowTemplate: "",
statusBarTemplate: null,
search: false,
noRecords: false,
dataSource: {},
height: null,
resizable: false,
reorderable: false,
columnMenu: false,
detailTemplate: null,
contextMenu: false,
columnResizeHandleWidth: 3,
size: "medium",
mobile: "",
loaderType: "loadingPanel",
messages: {
loader: {
loading: "Loading...",
exporting: "Exporting...",
},
editable: {
cancelDelete: CANCELDELETE,
confirmation: DELETECONFIRM,
confirmDelete: CONFIRMDELETE
},
commands: {
create: defaultCommands.create.text,
cancel: defaultCommands.cancel.text,
save: defaultCommands.save.text,
destroy: defaultCommands.destroy.text,
edit: defaultCommands.edit.text,
update: defaultCommands.update.text,
canceledit: defaultCommands.canceledit.text,
excel: defaultCommands.excel.text,
pdf: defaultCommands.pdf.text,
search: defaultCommands.search.text,
columns: defaultCommands.columns.text,
select: "Select",
sort: defaultCommands.sort.text,
filter: defaultCommands.filter.text,
group: defaultCommands.group.text,
columnchooser: defaultCommands.columnchooser.text,
selectRow: "Select Row",
selectAllRows: "All rows",
clearSelection: "Clear selection",
copySelection: "Copy selection",
copySelectionNoHeaders: "Copy selection (No Headers)",
paste: "Paste (use CTRL/⌘ + V)",
reorderRow: "Reorder row",
reorderRowUp: "Up",
reorderRowDown: "Down",
reorderRowTop: "Top",
reorderRowBottom: "Bottom",
exportPdf: "Export to PDF",
exportExcel: "Export to Excel",
exportToExcelAll: "All",
exportToExcelSelection: "Selection",
exportToExcelSelectionNoHeaders: "Selection (No Headers)",
sortAsc: "Sort Ascending",
sortDesc: "Sort Descending",
moveGroupPrevious: "Move previous",
moveGroupNext: "Move next",
},
noRecords: NORECORDS,
expandCollapseColumnHeader: "",
groupHeader: "Press ctrl + space to group",
ungroupHeader: "Press ctrl + space to ungroup",
itemsSelected: "items selected",
dragHandleLabel: "Drag row",
toolbarLabel: "grid toolbar",
groupingHeaderLabel: "grid grouping header",
filterCellTitle: "filter cell"
},
width: null
},
destroy: function() {
var that = this,
element,
reorderableInstance;
that._destroyColumnAttachments();
Widget.fn.destroy.call(that);
if (this._navigatableTables) {
this._navigatableTables.off(NS);
this._navigatableTables = null;
this._headertables = null;
}
if (that._resizeHandler) {
$(window).off("resize" + NS, that._resizeHandler);
}
if (that.pager && that.pager.element) {
that.pager.destroy();
}
if (that.timer) {
clearTimeout(that.timer);
}
if (that._progressTimeOut) {
clearTimeout(that._progressTimeOut);
}
if (that._collapseGroupsTimeOut) {
clearTimeout(that._collapseGroupsTimeOut);
}
if (that._endlessFetchTimeOut) {
clearTimeout(that._endlessFetchTimeOut);
}
that.pager = null;
that._destroyGroupable();
reorderableInstance = that.wrapper.data("kendoReorderable");
if (reorderableInstance) {
reorderableInstance.destroy();
}
reorderableInstance = that.tbody ? that.tbody.data("kendoReorderable") : null;
if (reorderableInstance) {
reorderableInstance.destroy();
}
if (that.allowPaste) {
const container = that.content || that.table;
container.off(PASTE + NS, that.pasteHandler);
that.unbind(that.pasteHandler);
}
if (that.pasteActionsDropDownList) {
that.pasteActionsDropDownList.destroy();
that.pasteActionsDropDownList = null;
}
if (that.selectable && that.selectable.element) {
that.selectable.destroy();
that.clearArea();
that._selectedIds = null;
if (that.copyHandler) {
that.wrapper.off("keydown", that.copyHandler);
that.unbind(that.copyHandler);
}
if (that.updateClipBoardState) {
that.unbind(that.updateClipBoardState);
that.updateClipBoardState = null;
}
if (that.clearAreaHandler) {
that.wrapper.off("keyup", that.clearAreaHandler);
}
}
that.selectable = null;
that._selectableAggregatesOptions = null;
if (that.resizable) {
that.resizable.destroy();
if (that._resizeUserEvents) {
if (that._resizeHandleDocumentClickHandler) {
$(document).off("click", that._resizeHandleDocumentClickHandler);
}
that._resizeUserEvents.destroy();
that._resizeUserEvents = null;
}
that.resizable = null;
}
that._destroyRowResizing();
that._destroyVirtualScrollable();
if (that.editableUserEvents) {
that.editableUserEvents.destroy();
that.editableUserEvents = null;
}
if (that._lockedContentUserEvents) {
that._lockedContentUserEvents.destroy();
that._lockedContentUserEvents = null;
}
that._destroyEditable();
if (that.dataSource) {
that.dataSource.unbind(CHANGE, that._refreshHandler)
.unbind(PROGRESS, that._progressHandler)
.unbind(ERROR, that._errorHandler)
.unbind(SORT, that._clearSortClasses);
that._refreshHandler = that._progressHandler = that._errorHandler = that._sortHandler = null;
}
element = that.element
.add(that.wrapper)
.add(that.table)
.add(that.thead)
.add(that.wrapper.find(">.k-grid-toolbar"));
if (that.content) {
element = element
.add(that.content)
.add(that.content.find(">.k-virtual-scrollable-wrap"));
}
if (that.scrollables && that.scrollables.first()) {
element = element.add(that.scrollables.first());
}
if (that.lockedHeader) {
that._removeLockedContainers();
}
if (that.pane) {
that.pane.destroy();
}
if (that._isMobile) {
that.wrapper.off("transitionend" + NS);
that.wrapper.off("contextmenu" + NS);
}
if (that.minScreenResizeHandler) {
$(window).off("resize", that.minScreenResizeHandler);
}
that._detachColumnMediaResizeHandler();
if (that._draggableInstance && that._draggableInstance.element) {
that._draggableInstance.destroy();
}
that._draggableInstance = null;
if (that._draggableRowsInstance && that._draggableRowsInstance.element) {
that._draggableRowsInstance.destroy();
}
if (that.tbodyContextMenu) {
that.tbodyContextMenu.destroy();
}
if (that.theadContextMenu) {
that.theadContextMenu.destroy();
}
if (that.loader) {
that.loader.destroy();
}
that._draggableRowsInstance = null;
element.off(NS);
element[0].kendoBindingTarget = null;
kendo.destroy(that.wrapper);
that.rowTemplate =
that.altRowTemplate =
that.lockedRowTemplate =
that.lockedAltRowTemplate =
that.detailTemplate =
that.footerTemplate =
that.groupFooterTemplate =
that.lockedGroupFooterTemplate =
that.noRecordsTemplate = null;
that.scrollables =
that.thead =
that.tbody =
that.element =
that.table =
that.content =
that.statusBar =
that.footer =
that.wrapper =
that.lockedTable =
that.lockedContent =
that.lockedHeader =
that.lockedFooter =
that._groupableClickHandler =
that._groupRows =
that._setContentWidthHandler =
that.loaderOverlay =
that.wrapperClone = null;
},
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(),
element = this.element;
if (currentOptions.size) {
const size = kendo.getValidCssClass("k-grid-", "size", currentOptions.size);
element.removeClass(size);
}
kendo.deepExtend(currentOptions, options);
if (!options.dataSource) {
currentOptions.dataSource = this.dataSource;
} else {
if (options.dataSource.filter) {
currentOptions.dataSource.filter = options.dataSource.filter;
}
}
var wrapper = this.wrapper;
var events = this._events;
this.destroy();
this.options = null;
if (this._isMobile) {
var mobileWrapper = wrapper.closest(kendo.roleSelector("pane")).parent();
mobileWrapper.after(wrapper);
mobileWrapper.remove();
wrapper.removeClass("k-grid-mobile");
}
if (wrapper[0] !== element[0]) {
wrapper.before(element);
wrapper.remove();
}
element.empty();
this.init(element, currentOptions, events);
this._setEvents(currentOptions);
},
items: function() {
if (this.lockedContent) {
return this._items(this.tbody).add(this._items(this.lockedTable.children("tbody")));
} else {
return this._items(this.tbody);
}
},
_items: function(container, includeGroupRows) {
return container.children().filter(function() {
var tr = $(this);
return (includeGroupRows ? !tr.hasClass("k-detail-row") : !tr.hasClass(GROUPING_ROW)) && !tr.hasClass("k-detail-row") && !tr.hasClass("k-group-footer");
});
},
dataItems: function() {
var dataItems = kendo.ui.DataBoundWidget.fn.dataItems.call(this);
if (this.lockedContent) {
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;
},
_destroyColumnAttachments: function() {
var that = this;
that.resizeHandle = null;
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();
}
});
},
_setInitialRtlScrollPosition: function() {
const that = this;
if (isRtl && that.scrollables) {
kendo.scrollLeft(that.scrollables, 0);
}
},
_attachCustomCommandsEvent: function() {
var that = this,
columns = leafColumns(that.columns || []),
command,
idx,
length;
for (idx = 0, length = columns.length; idx < length; idx++) {
command = columns[idx].command;
if (command) {
attachCustomCommandEvent(that, that.wrapper, command);
}
}
},
_bindMediaQueries: function() {
const that = this;
const isAdaptive = that.options.adaptiveMode === "auto";
if (isAdaptive) {
that.largeMQL = kendo.mediaQuery("large");
that.mediumMQL = kendo.mediaQuery("medium");
that.smallMQL = kendo.mediaQuery("small");
const handler = (fullscreen, handler) => {
if (that._editMode() !== "popup") {
return;
}
const checkActionSheet = fullscreen === true || fullscreen === false;
let popup;
if (that._editContainer) {
popup = that._editContainer && that._editContainer.data(handler);
}
if (!popup) {
const reverseHandler = handler === "kendoActionSheet" ? "kendoWindow" : "kendoActionSheet";
popup = that._editContainer && that._editContainer.data(reverseHandler);
}
if (checkActionSheet) {
if (popup && popup.fullscreen && popup.visible()) {
that._showAdaptiveView = true;
popup.fullscreen(fullscreen);
} else if (popup) {
that._showAdaptiveView = false;
that._destroyEditable(true);
}
} else {
if (popup && popup.fullscreen) {
popup.close();
}
}
};
that.smallMQL
.onEnter(() => {
handler(true, "kendoActionSheet");
});
that.mediumMQL
.onEnter(() => {
handler(false, "kendoActionSheet");
});
that.largeMQL
.onEnter(() => {
handler(null, "kendoWindow");
});
} else {
that.smallMQL && that.smallMQL.destroy();
that.mediumMQL && that.mediumMQL.destroy();
that.largeMQL && that.largeMQL.destroy();
that._showAdaptiveView = false;
}
},
_aria: function() {
var wrapper = this.wrapper,
gridRole = this._hasDetails() ? "treegrid" : this.options.navigatable ? "grid" : null,
table = this.table,
toolbar = wrapper.find(".k-grid-toolbar"),
groupingHeader = wrapper.find(".k-grouping-header"),
gridId = this._ariaGridId(),
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(TABINDEX, tableTabindex >= 0 ? tableTabindex : 0);
if (gridRole) {
table.attr(ROLE, gridRole);
}
const tbody = table.find("tbody");
const thead = table.find("thead");
const tfoot = table.find("tfoot");
const tr = table.find(TR);
if (tbody.find(TR).length > 0) {
tbody.attr(ROLE, ROWGROUP);
}
if (thead.find(`${TR} ${TH}`).length > 0) {
thead.attr(ROLE, ROWGROUP);
}
if (tfoot.find(TR).length > 0) {
tfoot.attr(ROLE, ROWGROUP);
}
if (tr.children().length > 0) {
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 if (this._hasDetails()) {
rowsCount = numberOfFixedRows + (this.dataSource.total() * 2);
} else {
rowsCount = numberOfFixedRows + this.dataSource.total();
}
table.attr(ARIA_ROWCOUNT, rowsCount);
} else if (this._hasDetails()) {
if (this._groups() > 0) {
rowsCount = -1;
} else {
rowsCount = numberOfFixedRows + (this.dataSource.total() * 2);
}
table.attr(ARIA_ROWCOUNT, rowsCount);
}
if (rowsCount && rowsCount > 0) {
this._ariaRowIndex();
}
if ((virtual && virtual.columns) ||
(!table.attr(ARIA_COLCOUNT) &&
(table.find("td:not([group-header-spanned-hidden]):hidden").length > 0 ||
wrapper.find(".k-grid-content-locked td:not([group-header-spanned-hidden]):hidden").length > 0))) {
table.attr(ARIA_COLCOUNT, trailingColumns + leafColumns(this.columns).length);
this._ariaColumnIndex();
}
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);
}
if (this.options.groupable) {
this._ariaGroupTitles();
}
},
_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);
}
},
_ariaGroupTitles: function() {
var that = this,
groups = that.dataSource.group(),
ths = that.wrapper.find(".k-grid-header th");
ths.each(function(i, el) {
if (el.getAttribute("title") === that.options.messages.ungroupHeader) {
el.setAttribute("title", that.options.messages.groupHeader);
}
});
if (groups && groups.length > 0) {
groups.forEach(function(group) {
var field = group.field,
el = ths.filter("[" + kendo.attr("field") + "='" + field + "']");
if (el.attr("title") === that.options.messages.groupHeader) {
el.attr("title", that.options.messages.ungroupHeader);
}
});
}
},
_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);
const tr = table.find(TR);
if (tr.children().length > 0) {
tr.attr(ROLE, ROW);
rowGroup.attr(ROLE, ROWGROUP);
}
table.find(el).attr(ROLE, role);
rowGroup.attr({
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";
}
},
_ariaGridId: function() {
var table = this.table,
gridId = table.attr(ID);
if (!gridId) {
gridId = kendo.guid();
table.attr(ID, gridId);
}
return gridId;
},
_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,
leafColsCount = 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,
previousMaster = false,
i, currentRow;
if (this._hasDetails()) {
totalNumberOfItems = totalNumberOfItems * 2;
previousItems = previousItems * 2;
}
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);
if (this._hasDetails() && currentRow.hasClass("k-master-row")) {
if (previousMaster) {
currentIndex = currentIndex + 2;
} else {
currentIndex = currentIndex + 1;
}
previousMaster = true;
} else {
currentIndex = currentIndex + 1;
previousMaster = false;
}
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 = [],
gridId = this._ariaGridId();
elements.each(function(j, cell) {
var id = cell.getAttribute(ID) || gridId + "_" + prefix + "_" + i + "_" + j;
cell.setAttribute(ID, id);
ownedCells.push(id);
});
return ownedCells;
},
_trailingColumns: function() {
return this._groups() + (this._hasDetails() ? 1 : 0);
},
_element: function() {
const that = this;
let table = that.element;
if (!table.is("table")) {
if (that.options.scrollable) {
table = that.element.find("> .k-grid-content > table");
} else {
table = that.element.children("table");
}
if (!table.length) {
table = $("<table />").appendTo(that.element);
}
}
table.addClass("k-grid-table k-table");
table.addClass(kendo.getValidCssClass("k-table-", "size", that.options.size));
that.table = table;
that._wrapper();
},
_createResizeHandle: function(container, th) {
var that = this;
var indicatorWidth = that.options.columnResizeHandleWidth;
var scrollable = that.options.scrollable;
var resizeHandle = that.resizeHandle;
var halfResizeHandle = (indicatorWidth * 3) / 2;
var rtlCorrection = 0;
var headerWrap;
var ieCorrection;
var webkitCorrection;
var firefoxCorrection;
var leftMargin;
var leftBorderWidth;
var scrollLeft;
var left;
var top;
if (resizeHandle && that.lockedContent && resizeHandle.data("th")[0] !== th[0]) {
resizeHandle.off(NS).remove();
resizeHandle = null;
}
if (!resizeHandle) {
resizeHandle = that.resizeHandle = $('<div class="k-resize-handle"><div class="k-resize-handle-inner"></div></div>');
container.append(resizeHandle);
}
scrollLeft = kendo.scrollLeft(container);
if (isRtl && (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);
if (!isRtl) {
left += th[0].offsetWidth;
} else {
if (scrollable) {
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");
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 = -rtlCorrection;
firefoxCorrection = browser.mozilla ? leftBorderWidth - leftMargin - rtlCorrection : 0;
left -= webkitCorrection + firefoxCorrection + ieCorrection;
}
}
top = th.offset().top - parseFloat(th.css("marginTop")) - (container.offset().top + parseFloat(container.css("borderTopWidth")));
resizeHandle.css({
top: top, //scrollable ? 0 : heightAboveHeader(that.wrapper),
left: left - halfResizeHandle,
height: outerHeight(th),
width: indicatorWidth * 3 - rtlCorrection
})
.data("th", th)
.show();
resizeHandle.off(DUBLECLICK + NS).on(DUBLECLICK + NS, function() {
that._autoFitLeafColumn(parseInt(th.attr(kendo.attr("index")), 10));
});
},
_positionColumnResizeHandle: function() {
var that = this,
lockedHead = that.lockedHeader ? that.lockedHeader.find("thead").first() : $();
that.thead.add(lockedHead).on(MOUSEMOVE + NS, "tr:not(.k-filter-row) > th:not([data-resizable=false])", function(e) {
var button = typeof e.buttons !== "undefined" ? e.buttons : (e.which || e.button);
var th = $(this);
if (th.hasClass("k-group-cell") || th.hasClass("k-hierarchy-cell")) {
return;
}
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 (th[0].hasAttribute(kendo.attr(COLSPAN))) {
// resizing multi-column headers is not supported
return;
}
that._createResizeHandle(th.closest(DIV), th);
});
},
_resizeHandleDocumentClick: function(e) {
if ($(e.target).closest(".k-column-active").length) {
return;
}
$(document).off(e);
this._resetResizeHandleHeader();
this._hideResizeHandle();
},
_resetResizeHandleHeader: function() {
var th;
if (!this.resizeHandle) {
return;
}
th = $(this.resizeHandle).data("th");
if (th) {
th.find(DOT + LINK_CLASS).find(DOT + ICON_CLASS + "," + DOT + SVG_ICON_CLASS).show();
th.find(DOT + ORDER_CLASS).show();
th.find(DOT + HEADER_COLUMN_MENU_CLASS).show();
th.find(DOT + FILTER_MENU_CLASS).show();
}
},
_hideResizeHandle: function() {
if (this.resizeHandle) {
this.resizeHandle.data("th")
.removeClass("k-column-active");
if (this.lockedContent && !this._isMobile) {
this.resizeHandle.off(NS).remove();
this.resizeHandle = null;
} else {
this.resizeHandle.hide();
}
}
},
_positionColumnResizeHandleTouch: function() {
var that = this,
lockedHead = that.lockedHeader ? that.lockedHeader.find("thead").first() : $();
that._resizeUserEvents = new kendo.UserEvents(lockedHead.add(that.thead), {
filter: "th:not(.k-group-cell):not(.k-hierarchy-cell)",
threshold: 10,
minHold: 500,
hold: function(e) {
var th = $(e.target);
e.preventDefault();
if (that.resizeHandle) {
that.resizeHandle.data("th")
.removeClass("k-column-active");
that._resetResizeHandleHeader();
}
th.addClass("k-column-active");
th.find(DOT + LINK_CLASS).find(DOT + ICON_CLASS + "," + DOT + SVG_ICON_CLASS).hide();
th.find(DOT + ORDER_CLASS).hide();
th.find(DOT + HEADER_COLUMN_MENU_CLASS).hide();
th.find(DOT + FILTER_MENU_CLASS).hide();
that._createResizeHandle(th.closest(DIV), th);
if (!that._resizeHandleDocumentClickHandler) {
that._resizeHandleDocumentClickHandler = that._resizeHandleDocumentClick.bind(that);
}
$(document).on("click", that._resizeHandleDocumentClickHandler);
}
});
},
resizeColumn: function(column, columnWidth) {
var that = this;
var isLocked = !!column.locked;
var isHidden = !!column.hidden;
var options = this.options;
var scrollbar = !kendo.support.mobileOS ? kendo.support.scrollbar() : 0;
var index = isLocked ? inArray(column, visibleLockedColumns(visibleLeafColumns(that.columns))) : inArray(column, visibleNonLockedColumns(visibleLeafColumns(that.columns)));
var contentTable = isLocked ? that.lockedTable : that.table;
var footer = that.footer || $();
var header = isLocked ? that.lockedHeader.find("table") : that.thead.closest("table");
var columnMinWidth = column.minResizableWidth || 10;
var gridWidth = isLocked ? outerWidth(contentTable.find("tbody")) : outerWidth(that.tbody); // IE returns 0 if grid is empty and scrolling is enabled
var col;
if (isHidden) {
column.width = columnWidth > columnMinWidth ? columnWidth : columnMinWidth;
return;
}
if (that.footer && that.lockedContent) {
footer = isLocked ? that.footer.children(".k-grid-footer-locked") : that.footer.children(".k-grid-footer-wrap");
}
if (options.scrollable) {
col = header.find("col:not(.k-group-col,.k-hierarchy-col)").eq(index)
.add(contentTable.children("colgroup").find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index))
.add(footer.find("colgroup").find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index));
} else {
col = contentTable.find("colgroup").find("col:not(.k-group-col):not(.k-hierarchy-col)").eq(index);
}
if (options.scrollable) {
var constrain = false;
var totalWidth = that.wrapper.width() - scrollbar;
var width = columnWidth = columnWidth > columnMinWidth ? columnWidth : columnMinWidth;
if (isLocked && gridWidth - columnWidth + width > totalWidth) {
width = columnWidth + (totalWidth - gridWidth - scrollbar * 2);
if (width < 0) {
width = columnWidth;
}
constrain = true;
}
if (width > 10 && width >= columnMinWidth) {
col.css('width', width);
if (gridWidth) {
if (constrain) {
width = totalWidth - scrollbar * 2;
} else {
width = gridWidth + (columnWidth - column.width);
}
contentTable
.add(header)
.add(footer)
.css('width', width);
if (!isLocked) {
that._footerWidth = width;
}
}
}
that._scrollVirtualWrapperOnColumnResize();
} else if (columnWidth > 10 && columnWidth >= columnMinWidth) {
col.css('width', columnWidth);
}
column.width = columnWidth;
that._applyLockedContainersWidth();
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
that._updateStickyColumns();
},
_adjustColWidths: function(contentTable, header, footer, gridWidth) {
const colWidths = {};
contentTable
.add(header)
.add(footer)
.css('width', gridWidth);
contentTable
.add(header)
.add(footer)
.find("col")
.each((i, col) => {
// Retrieve the actual widths of the elements.
colWidths[i] = $(col).css("width");
});
contentTable
.add(header)
.add(footer)
.find("col")
.each((i, col) => {
// Ensure that the style="width" attribute on the col elements matches the real width of the columns.
$(col).css("width", colWidths[i]);
});
},
_resizable: function() {
var that = this,
options = that.options,
container,
columnStart,
columnWidth,
columnMinWidth,
gridWidth,
isMobile = this._isMobile,
scrollbar = !kendo.support.mobileOS ? kendo.support.scrollbar() : 0,
isLocked,
col, th;
if (options.resizable === true || (options.resizable && options.resizable.columns === true)) {
container = options.scrollable ? that.wrapper.find(".k-grid-header-wrap").first() : that.wrapper;
if (isMobile) {
that._positionColumnResizeHandleTouch(container);
} else {
that._positionColumnResizeHandle(container);
}
if (that.resizable) {
that.resizable.destroy();
}
that.resizable = new ui.Resizable(container.add(that.lockedHeader), {
handle: (!!options.scrollable ? "" : ">") + ".k-resize-handle",
hint: function(handle) {
return $('<div class="k-grid-resize-indicator" />').css({
height: outerHeight(handle.data("th")) + that.tbody.attr("clientHeight")
});
},
start: function(e) {
th = $(e.currentTarget).data("th");
if (isMobile) {
that._hideResizeHandle();
}
let header = th.closest("table"),
index = $.inArray(th[0], leafDataCells(th.closest("thead")).filter(":visible"));
isLocked = header.parent().hasClass("k-grid-header-locked");
let 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");
}
let footerTable = footer.find("table");
cursor(that.wrapper, 'col-resize');
if (options.scrollable) {
col = header.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(footer.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);
}
let columns = $.map(that.columns, function(a) {
return !a.hidden && ((isLocked && a.locked) || ((!isLocked && !a.locked))) ? a : null;
});
columnStart = e.x.location;
columnWidth = outerWidth(th);
columnMinWidth = leafColumns(columns)[index].minResizableWidth || 10;
gridWidth = isLocked ? outerWidth(contentTable.children("tbody")) : outerWidth(that.tbody); // IE returns 0 if grid is empty and scrolling is enabled
// fix broken UI in Chrome38+
if (browser.webkit) {
that.wrapper.addClass("k-grid-column-resizing");
}
that._adjustColWidths(contentTable, header, footerTable, gridWidth);
},
resize: function(e) {
var rtlMultiplier = isRtl ? -1 : 1,
currentWidth = columnWidth + (e.x.location * rtlMultiplier) - (columnStart * rtlMultiplier);
if (options.scrollable) {
var footer;
if (isLocked && that.lockedFooter) {
footer = that.lockedFooter.children("table");
} else if (that.footer) {
footer = that.footer.find(">.k-grid-footer-wrap>table");
}
if (!footer || !footer[0]) {
footer = $();
}
var header = th.closest("table");
var contentTable = isLocked ? that.lockedTable : that.table;
var constrain = false;
var totalWidth = that.wrapper.width() - scrollbar;
var width = currentWidth;
if (isLocked && gridWidth - columnWidth + width > totalWidth) {
width = columnWidth + (totalWidth - gridWidth - scrollbar * 2);
if (width < 0) {
width = currentWidth;
}
constrain = true;
}
if (width > 10 && width >= columnMinWidth) {
col.css('width', width);
if (gridWidth) {
if (constrain) {
width = totalWidth - scrollbar * 2;
} else {
width = gridWidth + (e.x.location * rtlMultiplier) - (columnStart * rtlMultiplier);
}
contentTable
.add(header)
.add(footer)
.css('width', width);
if (!isLocked) {
that._footerWidth = width;
}
}
}
that._scrollVirtualWrapperOnColumnResize();
} else if (currentWidth > 10 && currentWidth >= columnMinWidth) {
col.css('width', currentWidth);
}
},
resizeend: function() {
var newWidth = outerWidth(th),
column,
header;
cursor(that.wrapper, "");
if (browser.webkit) {
that.wrapper.removeClass("k-grid-column-resizing");
}
if (th && columnWidth != newWidth) {
header = that.lockedHeader ? that.lockedHeader.find("thead").first().find(TR).first().add(that.thead.find(TR).first()) : th.parent();
var index = th.attr(kendo.attr("index"));
if (!index) {
index = header.find("th:not(.k-group-cell):not(.k-hierarchy-cell)").index(th);
}
column = leafColumns(that.columns)[index];
column.width = newWidth;
that.trigger(COLUMNRESIZE, {
column: column,
oldWidth: columnWidth,
newWidth: newWidth
});
that._applyLockedContainersWidth(true);
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
that._updateStickyColumns();
}
that._resetResizeHandleHeader();
that._hideResizeHandle();
th = null;
}
});
}
},
// Row resizing functionality below
_addLockedRowResizing: function(tr) {
var index = tr.index();
return this.lockedTable.find(TR).eq(index)
.add(this.tbody.find(TR).eq(index));
},
_getMinRowHeight: function(row) {
var minHeight = 0;
row.each((i, el) => {
var currentMinHeight;
el.style.height = '';
currentMinHeight = outerHeight(el);
if (currentMinHeight > minHeight) {
minHeight = currentMinHeight;
}
});
return minHeight;
},
_cacheRowHeight: function(rows, height) {
var that = this;
if (!that._cachedRowsHeight) {
that._cachedRowsHeight = {};
}
rows.each((i, el) => {
var uid = el.getAttribute("data-uid");
that._cachedRowsHeight[uid] = height;
});
},
_clearCachedRowsHeight: function(rows) {
var that = this;
if (rows && that._cachedRowsHeight) {
rows.each((i, el) => {
var uid = el.getAttribute("data-uid");
delete that._cachedRowsHeight[uid];
});
} else {
that._cachedRowsHeight = null;
}
},
_mapCachedRowsHeight: function(method, target) {
var input = this._cachedRowsHeight,
ds = this.dataSource,
output = {};
Object.keys(input).forEach((key) => {
var item = ds[method](key);
output[item[target]] = input[key];
});
this._cachedRowsHeight = output;
},
_rowResizerDblClick: function() {
var that = this,
resizer = that.rowResizer,
row = resizer.data(TR),
oldHeight = outerHeight(row),
newHeight, rows;
if (row.hasClass(SELECTED)) {
rows = that.select();
} else {
rows = row;
}
if (that.lockedTable) {
row = that._addLockedRowResizing(row);
if (row.hasClass(SELECTED)) {
rows = that.lockedTable.find(DOT + SELECTED);
} else {
rows = that.lockedTable.find(TR).eq(row.index());
}
rows.each((i, el) => {
var rowIndex = el.rowIndex,
rowPair = $(el).add(that.tbody.find(TR).eq(rowIndex)),
pairMinHeight = that._getMinRowHeight(rowPair);
rowPair.css(HEIGHT, pairMinHeight);
});
} else {
rows.css(HEIGHT, AUTO);
}
that._clearCachedRowsHeight(rows);
resizer.removeClass(HOVER);
resizer.removeClass(ACTIVE);
newHeight = outerHeight(row);
if (oldHeight != newHeight) {
that.trigger(ROWRESIZE, {
row,
rows,
oldHeight,
newHeight
});
}
},
_setupRowResizer(resizer, row, top) {
resizer
.data(TR, row)
.css({
top: top
});
},
_attachRowResizerEvents: function() {
var rowResizer = this.rowResizer,
delay = 200,
isIn = false;
rowResizer
.on(MOUSEDOWN + NS, (e) => {
if (e.button === 0) {
rowResizer.removeClass(HOVER);
rowResizer.addClass(ACTIVE);
}
})
.on(MOUSEUP + NS, (e) => {
if (e.button === 0) {
rowResizer.removeClass(ACTIVE);
rowResizer.addClass(HOVER);
}
})
.on(MOUSEENTER + NS, () => {
isIn = true;
setTimeout(() => {
if (isIn) {
rowResizer.addClass(HOVER);
}
}, delay);
})
.on(MOUSELEAVE + NS, () => {
isIn = false;
rowResizer.removeClass(HOVER);
});
},
_getResizerTop: function(tr, container) {
var resizer = this.rowResizer,
inner = resizer.find(DOT + ROW_RESIZER)[0],
paddingTop = parseInt(getComputedStyle(resizer[0]).paddingTop);
return tr.offset().top -
parseFloat(tr.css("marginTop")) -
(container.offset().top + parseFloat(container.css("borderTopWidth"))) -
inner.clientHeight -
paddingTop +
container.scrollTop();
},
_getResizerContainer: function() {
var container = this.tbody.closest(DIV);
if (this.lockedTable) {
container = container.closest(DOT + "k-grid-container");
}
return container;
},
_createRowResizer: function(e) {
var that = this,
tr = $(e.currentTarget),
targetHeight = e.currentTarget.clientHeight,
positionIntarget = e.offsetY,
rowResizer = that.rowResizer,
previousRow = tr.prev(TR + ":visible"),
container = that._getResizerContainer(),
top;
if (!rowResizer) {
rowResizer = that.rowResizer = $('<div class="k-resizer-wrap"><div class="k-row-resizer"></div></div>');
container.append(rowResizer);
that._attachRowResizerEvents();
rowResizer.off(DUBLECLICK + NS).on(DUBLECLICK + NS, that._rowResizerDblClick.bind(that));
}
top = that._getResizerTop(tr, container);
if (previousRow.length !== 0 && targetHeight / 2 > positionIntarget) {
if (!previousRow.hasClass(GROUPING_ROW)) {
that._setupRowResizer(rowResizer, previousRow, top);
}
} else {
if (!tr.hasClass(GROUPING_ROW)) {
that._setupRowResizer(rowResizer, tr, top + targetHeight);
}
}
},
_detachRowResizerEvents: function() {
var rowResizer = this.rowResizer;
rowResizer
.off(MOUSEDOWN + NS)
.off(MOUSEUP + NS)
.off(MOUSEENTER + NS)
.off(MOUSELEAVE + NS);
},
_mapResizedRows: function(rows, multiSelectionLocked, newHeight) {
var that = this;
rows.each((i, el) => {
var minHeight;
if (multiSelectionLocked) {
var rowIndex = el.rowIndex,
pairNew = newHeight,
pairMin = 0,
rowPair = $(el).add(that.tbody.find(TR).eq(rowIndex));
rowPair.each((i, r) => {
var currentMinHeight;
r.style.height = '';
currentMinHeight = outerHeight(r);
if (currentMinHeight > pairMin) {
pairMin = currentMinHeight;
}
});
if (pairNew < pairMin) {
pairNew = pairMin;
that._clearCachedRowsHeight(rowPair.eq(0));
} else {
that._cacheRowHeight(rowPair.eq(0), pairNew);
}
rowPair.css(HEIGHT, pairNew);
} else {
el.style.height = '';
minHeight = outerHeight(el);
if (newHeight > minHeight) {
el.style.height = newHeight + PX;
that._cacheRowHeight($(el), newHeight);
} else {
that._clearCachedRowsHeight($(el));
}
}
});
},
_rowResizing: function() {
var that = this,
options = that.options,
container, rowStart, rowHeight, tr;
if (options.resizable && options.resizable.rows === true) {
that.tbody
.parent()
.add(that.lockedTable)
.on(MOUSEMOVE + NS, ".k-grid-footer tr, .k-table-tbody tr", that._createRowResizer.bind(that));
if (that.rowResizing) {
that.rowResizing.destroy();
}
container = that._getResizerContainer();
that.rowResizing = new ui.Resizable(container, {
handle: DOT + ROW_RESIZER_WRAP,
start: function(e) {
tr = $(e.currentTarget).data(TR);
if (that.lockedTable) {
tr = that._addLockedRowResizing(tr);
}
tr.addClass(HOVER);
that._detachRowResizerEvents();
rowStart = e.y.location;
rowHeight = outerHeight(tr);
},
resize: function(e) {
var newHeight = rowHeight + e.y.location - rowStart,
minHeight = 0;
if (tr.length > 1) {
minHeight = that._getMinRowHeight(tr);
}
if (newHeight < minHeight) {
newHeight = minHeight;
}
tr.css('height', newHeight);
that._setupRowResizer(that.rowResizer, tr, that._getResizerTop(tr, container) + newHeight);
},
resizeend: function() {
var newHeight = outerHeight(tr),
multiSelectionLocked = false,
rows;
if (tr.hasClass(SELECTED)) {
rows = that.select();
if (tr.length > 1 && rows.length > tr.length) {
rows = that.lockedTable.find(DOT + SELECTED).not(tr);
multiSelectionLocked = true;
}
} else {
rows = tr;
}
that._mapResizedRows(rows, multiSelectionLocked, newHeight);
tr.removeClass(HOVER);
that.rowResizer.removeClass(ACTIVE);
that.rowResizer.addClass(HOVER);
that._attachRowResizerEvents();
if (multiSelectionLocked) {
rows = that.select();
}
if (rowHeight != newHeight) {
that.trigger(ROWRESIZE, {
row: tr,
rows,
oldHeight: rowHeight,
newHeight
});
}
tr = null;
}
});
}
},
_draggable: function() {
var that = this,
reorderable = that.options.reorderable;
if (reorderable === true || (reorderable && reorderable.columns)) {
if (that._draggableInstance) {
that._draggableInstance.destroy();
}
var header = that.wrapper.children(".k-grid-header");
header.addClass("k-grid-draggable-header");
header.attr("draggable", true);
that._draggableInstance = that.wrapper.kendoDraggable({
group: kendo.guid(),
autoScroll: true,
filter: that.content ? ".k-grid-header:first " + HEADERCELLS : "table:first>.k-grid-header " + HEADERCELLS,
dragstart: function() {
header.children(".k-grid-header-wrap").off("scroll" + NS + "scrolling").on("scroll" + NS + "scrolling", function(e) {
if (that.virtualScrollable) {
kendo.scrollLeft(that.content.find(">.k-virtual-scrollable-wrap"), this.scrollLeft);
} else {
kendo.scrollLeft(that.scrollables.not(e.currentTarget), this.scrollLeft);
}
});
},
dragend: function() {
that._resetResizeHandleHeader();
header.children(".k-grid-header-wrap").off("scroll" + NS + "scrolling");
},
drag: function() {
that._hideResizeHandle();
},
hint: function(target) {
var title = target.attr(kendo.attr("title"));
if (title) {
title = kendo.htmlEncode(title);
}
return $('<div class="k-reorder-clue k-drag-clue" />')
.html(title || target.attr(kendo.attr("field")) || target.text())
.prepend(kendo.ui.icon({ icon: "cancel", iconClass: "k-drag-status" }));
}
}).data("kendoDraggable");
}
},
_reorderable: function() {
let that = this,
reorderable = that.options.reorderable;
if (reorderable === true || (reorderable && reorderable.columns)) {
if (that.wrapper.data("kendoReorderable")) {
that.wrapper.data("kendoReorderable").destroy();
}
that.wrapper.kendoReorderable({
draggable: that._draggableInstance,
dropFilter: HEADERCELLS,
allowDropAfterLastItem: true,
dragOverContainers: function(sourceIndex, targetIndex) {
let columns = flatColumnsInDomOrder(that.columns);
return columns[sourceIndex].lockable !== false && targetParentContainerIndex(columns, that.columns, sourceIndex, targetIndex) > -1;
},
inSameContainer: function(e) {
let sourceParent = $(e.source).parent()[0],
targetParent = $(e.target).parent()[0],
sourceIndex = e.sourceIndex,
targetIndex = e.targetIndex,
flatColumns = flatColumnsInDomOrder(that.columns),
lockable = flatColumns && flatColumns[sourceIndex] && !!flatColumns[sourceIndex].lockable;
/* If there are locked columns, check if the grid header is the same instead.
Otherwise the locked/unlocked headers are treated as separate(in the case of column reordering they shouldn't be). */
if (that._isLocked() && lockable) {
sourceParent = $(e.source.closest(".k-grid-header"))[0];
targetParent = $(e.target.closest(".k-grid-header"))[0];
}
return sourceParent === targetParent && targetParentContainerIndex(flatColumns, that.columns, sourceIndex, targetIndex) > -1;
},
change: function(e) {
let columns = flatColumnsInDomOrder(that.columns);
let column = columns[e.oldIndex];
let 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");
}
});
}
},
_reorderHeader: function(sources, target, before, container) {
var that = this;
var sourcePosition = columnPosition(sources[0], that.columns);
var destPosition = columnPosition(target, that.columns);
var action;
var ths;
var leafs = [];
for (var idx = 0; idx < sources.length; idx++) {
if (sources[idx].columns) {
leafs = leafs.concat(sources[idx].columns);
}
}
if (container) {
ths = elements(container, container, "tr:eq(" + sourcePosition.row + ")>th.k-header:not(.k-group-cell,.k-hierarchy-cell)");
} else {
ths = elements(that.lockedHeader, that.thead, "tr:eq(" + sourcePosition.row + ")>th.k-header:not(.k-group-cell,.k-hierarchy-cell)");
}
var sourceLockedColumns = lockedColumns(sources).length;
var targetLockedColumns = lockedColumns([target]).length;
if (leafs.length) {
if (sourceLockedColumns > 0 && targetLockedColumns === 0) {
action = "prepend";
moveCellsBetweenContainers(sources, target, leafs, that.columns, that.lockedHeader.find("thead"), that.thead, this._groups(), action);
} else if (sourceLockedColumns === 0 && targetLockedColumns > 0) {
action = destPosition.cell === 0 && sources[0].columns && !target.columns && !that._group ? "prepend" : "append";
moveCellsBetweenContainers(sources, target, leafs, nonLockedColumns(that.columns), that.thead, that.lockedHeader.find("thead"), this._groups(), action);
}
if (target.columns || sourcePosition.cell - destPosition.cell > 1 || destPosition.cell - sourcePosition.cell > 1) {
target = findReorderTarget(that.columns, target, sources[0], before, that.columns);
if (target) {
if (sourceLockedColumns > 0 && targetLockedColumns === 0) {
that._reorderHeader(leafs, target, before, that.thead);
} else if (sourceLockedColumns === 0 && targetLockedColumns > 0) {
that._reorderHeader(leafs, target, before, that.lockedHead);
} else {
that._reorderHeader(leafs, target, before);
}
}
}
} else if (sourceLockedColumns !== targetLockedColumns) { // move between containers
updateCellRowSpan(ths[sourcePosition.cell], that.columns, sourceLockedColumns);
}
reorder(ths, sourcePosition.cell, destPosition.cell, before, sources.length);
},
_reorderContent: function(sources, destination, before) {
var that = this;
var lockedRows = $();
var source = sources[0];
var visibleSources = visibleColumns(sources);
var sourceIndex = inArray(source, leafColumns(that.columns));
var destIndex = inArray(destination, leafColumns(that.columns));
var colSourceIndex = inArray(visibleSources[0], visibleLeafColumns(that.columns));
var colDest = inArray(destination, visibleLeafColumns(that.columns));
var lockedCount = lockedColumns(that.columns).length;
var isLocked = !!destination.locked;
var footer = that.footer || that.wrapper.find(".k-grid-footer");
var headerCol, footerCol, beforeVisibleColumn;
headerCol = footerCol = colDest;
if (destination.hidden) {
var columnsArray = isLocked ? lockedColumns(that.columns) : nonLockedColumns(that.columns);
if (visibleColumns(columnsArray).length > 0) {
headerCol = footerCol = colDest = this._findClosestVisibleColumnIndex(columnsArray, destIndex);
beforeVisibleColumn = visibleColumns(columnsArray.slice(destIndex)).length > 0;
}
else {
if (isLocked) {
colDest = that.lockedTable.find("colgroup");
headerCol = that.lockedHeader.find("colgroup");
footerCol = $(that.lockedFooter).find(">table>colgroup");
} else {
colDest = that.tbody.prev();
headerCol = that.thead.prev();
footerCol = footer.find(".k-grid-footer-wrap").find(">table>colgroup");
}
}
}
if (that._hasFilterRow()) {
reorder(that.wrapper.find(".k-filter-row td:not(.k-group-cell,.k-hierarchy-cell)"), sourceIndex, destIndex, before, sources.length);
}
if (colSourceIndex >= 0) {
reorder(elements(that.lockedHeader, that.thead.prev(), COLGROUP), colSourceIndex, headerCol, beforeVisibleColumn ? beforeVisibleColumn : before, visibleSources.length);
}
if (that.options.scrollable) {
if (colSourceIndex >= 0 && !that._hasVirtualColumns()) {
reorder(elements(that.lockedTable, that.tbody.prev(), COLGROUP), colSourceIndex, colDest, beforeVisibleColumn ? beforeVisibleColumn : before, visibleSources.length);
}
}
if (footer && footer.length) {
if (colSourceIndex >= 0) {
reorder(elements(that.lockedFooter, footer.find(".k-grid-footer-wrap"), ">table>colgroup>col:not(.k-group-col,.k-hierarchy-col)"), colSourceIndex, footerCol, beforeVisibleColumn ? beforeVisibleColumn : before, visibleSources.length);
}
reorder(footer.find(".k-footer-template>td:not(.k-group-cell,.k-hierarchy-cell)"), sourceIndex, destIndex, before, sources.length);
}
var rows = that.tbody.children(":not(.k-grouping-row,.k-detail-row)");
if (that.lockedTable) {
if (lockedCount > destIndex) {
if (lockedCount <= sourceIndex) {
updateColspan(
that.lockedTable.find(">tbody>tr.k-grouping-row:not([hidden])"),
that.table.find(">tbody>tr.k-grouping-row:not([hidden])"),
sources.length
);
}
} else if (lockedCount > sourceIndex) {
updateColspan(
that.table.find(">tbody>tr.k-grouping-row:not([hidden])"),
that.lockedTable.find(">tbody>tr.k-grouping-row:not([hidden])"),
sources.length
);
}
lockedRows = that.lockedTable.find(">tbody>tr:not(.k-grouping-row,.k-detail-row)");
}
for (var idx = 0, length = rows.length; idx < length; idx += 1) {
reorder(elements(lockedRows[idx], rows[idx], ">td:not(.k-group-cell,.k-hierarchy-cell)"), sourceIndex, destIndex, before, sources.length);
}
},
_findClosestVisibleColumnIndex: function(columns, columnIndex) {
var columnsArray = visibleColumns(columns.slice(columnIndex)).length > 0 ? columns.slice(columnIndex) : columns.slice(0, columnIndex + 1).reverse(),
closestVisibleColumn = visibleColumns(columnsArray)[0];
return inArray(closestVisibleColumn, visibleColumns(this.columns));
},
_autoFitLeafColumn: function(leafIndex) {
this.autoFitColumn(leafColumns(this.columns)[leafIndex]);
},
_hasReorderableRows: function() {
return this.options.reorderable && this.options.reorderable.rows;
},
_draggableRows: function() {
var that = this,
selectable = that._checkBoxSelection ||
(that.options.selectable && !kendo.ui.Selectable.parseOptions(that.options.selectable).cell),
clickMoveClick = false,
isMobile = !!(that._isMobile || kendo.support.mobileOS);
if (that._draggableRowsInstance) {
that._draggableRowsInstance.destroy();
}
if (this.options.reorderable.rows.clickMoveClick !== false && this._hasDragHandleColumn) {
clickMoveClick = true;
}
that._draggableRowsInstance = that.tbody.kendoDraggable({
holdToDrag: isMobile,
showHintOnHold: isMobile,
preventOsHoldFeatures: isMobile,
group: "row-draggable",
autoScroll: true,
filter: (selectable ? " > .k-selected" : " > " + ITEMROW) + (that._hasDragHandleColumn ? " > [ref-grid-drag-cell]" : ""),
hint: function(target) {
var hint = $('<div class="k-reorder-clue k-drag-clue">' + kendo.ui.icon({ icon: "cancel", iconClass: "k-drag-status" }) + '</div>');
if (selectable && that.select().length > 1 && that.lockedContent) {
hint.append("<span>" + that.select().length / 2 + " " + encode(that.options.messages.itemsSelected) + "</span>");
} else if (selectable && that.select().length > 1 && !that.lockedContent) {
hint.append("<span>" + that.select().length + " " + encode(that.options.messages.itemsSelected) + "</span>");
} else {
var clone = target.closest(ITEMROW).clone();
clone.find("td.k-command-cell").remove();
clone.find("td").each(function(index, elm) {
hint.append("<span>" + elm.innerText.replace(/<(\/?)script([^>]*)>/ig, "") + " </span>");
});
}
return hint;
},
clickMoveClick: clickMoveClick,
cursorOffset: { top: 0, left: 0 }
}).data("kendoDraggable");
},
_reorderableRows: function() {
var that = this,
selectable = that._checkBoxSelection ||
(that.options.selectable && !kendo.ui.Selectable.parseOptions(that.options.selectable).cell);
if (that.tbody.data("kendoReorderable")) {
that.tbody.data("kendoReorderable").destroy();
}
that.tbody.kendoReorderable({
smartPosition: false,
draggable: that._draggableRowsInstance,
dragOverContainers: function(sourceIndex, targetIndex) {
var result = true,
target = $(ITEMROW, that.content).eq(targetIndex);
if (selectable) {
result = !target.is(".k-selected");
}
return result;
},
inSameContainer: function(e) {
if (selectable) {
return !$(e.target).is(".k-selected");
}
return true;
},
dropFilter: "> " + ITEMROW,
allowIcon: "insert-middle",
orientation: "vertical",
reorderDropCue: $('<div class="k-drop-hint k-drop-hint-h"><div class="k-drop-hint-start"></div><div class="k-drop-hint-line"></div></div>'),
positionDropCue: function(reorderDropCue, dropTarget) {
var firstCellLeft = kendo.getOffset(dropTarget.children(DATA_CELL).eq(0)).left;
reorderDropCue.css({
transform: "translate(0,-50%)",
left: firstCellLeft
});
},
externalDraggable: function(e) {
var draggable = e.draggable;
if (draggable) {
return draggable;
}
},
change: function(e) {
that._triggerRowRorder(e);
}
});
},
_triggerRowRorder: function(e) {
var that = this,
args = {
newIndex: e.position === "after" ? e.newIndex + 1 : e.newIndex,
oldIndex: e.oldIndex
},
row = e.element,
selectable = that._checkBoxSelection ||
(that.options.selectable && !kendo.ui.Selectable.parseOptions(that.options.selectable).cell);
if (selectable && that.select().length > 1) {
args = extend(args, {
rows: that.select()
});
} else {
args = extend(args, {
row: row
});
}
if (!that.trigger(ROWREORDER, args)) {
that.reorderRows(selectable ? that.select() : row, args.newIndex);
}
},
reorderRowTo: function(row, index) {
var that = this,
item = that.dataItem(row),
oldIndex = row.index();
if (index < 0 || index === oldIndex) {
return;
}
if (!that.trigger(ROWREORDER, {
row: row,
oldIndex: row.index(),
newIndex: index
})) {
that.dataSource.pushMove(index, [item]);
}
},
reorderRows: function(rows, index) {
var that = this,
dataSource = that.dataSource,
rowsLength = that.tbody.children(ITEMROW).length,
targetItem = that.dataItem(that.tbody.children(ITEMROW).eq(index)),
items = rows.toArray().map(function(row) {
let dataItem = that.dataItem(row);
dataItem._isMoved = true;
return dataItem;
});
if (!targetItem) {
// If index is after last row dataItem wouldn't exist
targetItem = that.dataItem(that.tbody.children(ITEMROW).eq(rowsLength - 1));
index = dataSource.indexOf(targetItem) + 1;
} else {
index = dataSource.indexOf(targetItem);
}
if (index >= 0) {
that._rowDropping = true;
dataSource.pushMove(index, items);
that._rowDropping = false;
}
},
autoFitColumns: function(columns) {
var that = this;
columns = columns || that.columns;
for (var i = 0; i < columns.length; i++) {
var column = columns[i];
if (column.columns) {
that.autoFitColumns(column.columns);
} else {
that.autoFitColumn(column);
}
}
},
autoFitColumn: function(column) {
var that = this,
options = that.options,
columns = that.columns,
index,
th,
headerTable,
leafCols,
isLocked,
visibleLocked = that.lockedHeader ? leafDataCells(that.lockedHeader.find(">table>thead")).filter(isCellVisible).length : 0,
col,
minWidth,
contentDiv, scrollLeft,
notGroupOrHierarchyCol = "col:not(.k-group-col):not(.k-hierarchy-col)",
notGroupOrHierarchyVisibleCell = "td:visible:not(.k-group-cell):not(.k-hierarchy-cell)",
thWidth;
// retrieve the column object, depending on the method argument
if (typeof column == "number") {
column = columns[column];
} else if (isPlainObject(column)) {
column = grep(flatColumns(columns), function(item) {
return item === column;
})[0];
} else {
column = grep(flatColumns(columns), function(item) {
return item.field === column;
})[0];
}
if (!column || !isVisible(column)) {
return;
}
leafCols = leafColumns(columns);
minWidth = column.minResizableWidth;
index = inArray(column, leafCols);
isLocked = column.locked;
if (isLocked) {
headerTable = that.lockedHeader.children("table");
} else {
headerTable = that.thead.parent();
}
th = headerTable.find("[data-index='" + index + "']");
th.find('a.k-grid-column-menu, a.k-grid-filter-menu');
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 && !isLocked) {
index -= visibleLocked;
}
// adjust column index, depending on previous hidden columns
for (var j = 0; j < leafCols.length; j++) {
if (leafCols[j] === column) {
break;
} else {
if (leafCols[j].hidden) {
index--;
}
}
}
// get col elements
if (options.scrollable) {
col = headerTable.find(notGroupOrHierarchyCol).eq(index)
.add(contentTable.children("colgroup").find(notGroupOrHierarchyCol).eq(index))
.add(footerTable.find("colgroup").find(notGroupOrHierarchyCol).eq(index));
if (!isLocked) {
contentDiv = contentTable.parent();
scrollLeft = kendo.scrollLeft(contentDiv);
}
if (that._hasVirtualColumns()) {
index = inArray(column, that.virtualCols);
}
} else {
col = contentTable.children("colgroup").find(notGroupOrHierarchyCol).eq(index);
}
var tables = headerTable.add(contentTable).add(footerTable);
if (browser.safari) {
th.css("white-space", "initial");
}
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", "");
thWidth = outerWidth(th);
// +1 is required by IE, regardless of the border widths, otherwise unexpected wrapping may occur with hyphenated text
var newColumnWidth = Math.ceil(Math.max(
thWidth,
outerWidth(contentTable.find("tr:not(.k-grouping-row)").eq(0).children(notGroupOrHierarchyVisibleCell).eq(index)),
outerWidth(footerTable.find(TR).eq(0).children(notGroupOrHierarchyVisibleCell).eq(index))
)) + 1;
if (minWidth && minWidth > newColumnWidth) {
newColumnWidth = minWidth;
}
col.width(newColumnWidth);
column.width = newColumnWidth;
if (browser.safari) {
th.css("white-space", "");
}
// 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 if (cols.eq(idx).hasClass("k-group-col")) {
totalWidth += parseInt(cols.eq(idx).width(), 10);
} else {
totalWidth = 0;
break;
}
}
if (totalWidth) {
tables.each(function() {
this.style.width = totalWidth + PX;
});
}
}
tables.removeClass("k-autofitting");
if (scrollLeft) {
kendo.scrollLeft(contentDiv, scrollLeft);
}
that.trigger(COLUMNRESIZE, {
column: column,
oldWidth: oldColumnWidth,
newWidth: newColumnWidth
});
that._applyLockedContainersWidth();
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
that._updateStickyColumns();
},
reorderColumn: function(destIndex, column, before) {
var that = this,
parent = columnParent(column, that.columns),
columns = parent ? parent.columns : that.columns,
sourceIndex = inArray(column, columns),
destColumn = columns[destIndex],
virtualScroll = that.virtualScroll || {},
lockChanged,
isLocked = !!destColumn.locked,
lockedCount = lockedColumns(that.columns).length,
groupHeaderColumnTemplateColumns = grep(leafColumns(that.columns), function(column) { return column.groupHeaderColumnTemplate; });
if (sourceIndex === destIndex) {
return;
}
if (!column.locked && isLocked && nonLockedColumns(that.columns).length == 1) {
return;
}
if (column.locked && !isLocked && lockedCount == 1) {
return;
}
that._hideResizeHandle();
if (before === undefined$1) {
before = destIndex < sourceIndex;
}
var sourceColumns = [column];
that._reorderHeader(sourceColumns, destColumn, before);
if (that.lockedHeader) {
removeEmptyRows(that.thead);
removeEmptyRows(that.lockedHeader);
}
if (destColumn.columns) {
destColumn = leafColumns(destColumn.columns);
destColumn = destColumn[before ? 0 : destColumn.length - 1];
}
if (column.columns) {
sourceColumns = leafColumns(column.columns);
}
that._reorderContent(sourceColumns, destColumn, 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);
that._updateLockedCols();
that._updateCols();
that._templates();
that._updateColumnCellIndex();
that._updateColumnSorters();
if (groupHeaderColumnTemplateColumns.length > 0) {
that._renderGroupRows();
}
that._updateTablesWidth();
that._applyLockedContainersWidth();
that._syncLockedHeaderHeight();
that._syncLockedContentHeight();
that._updateFirstColumnClass();
that._updateStickyColumns();
if (virtualScroll.columns) {
that.refresh();
}
if (!lockChanged) {
return;
}
if (isLocked) {
that.trigger(COLUMNLOCK, {
column: column
});
} else {
that.trigger(COLUMNUNLOCK, {
column: column
});
}
},
_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);
},
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.locked || column.hidden) {
return;
}
if (column.sticky) {
this.unstickColumn(columns.indexOf(column));
}
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.locked || column.hidden) {
return;
}
var index = lockedColumns(columns).length;
this.reorderColumn(index, column, true);
},
stickColumn: 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.sticky || column.hidden) {
return;
}
if (column.locked) {
this.unlockColumn(columns.indexOf(column));
if (column.locked) {
return;
}
}
column.sticky = true;
this._updateStickyColumns();
},
unstickColumn: 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.sticky || column.locked || column.hidden) {
return;
}
this._removeStickyAttributes([column]);
this._removeStickyStyles(stickyColumns(columns));
column.sticky = false;
this._updateStickyColumns();
if (this._anyStickyColumns() === 0) {
this._templates();
if (this._hasFilterRow()) {
this._updateStickyFilterCells();
}
}
},
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('td:not(.k-group-cell,.k-hierarchy-cell)').index(td) + lockedColumnOffset;
},
_modelForContainer: function(container) {
container = $(container);
if (!container.is(TR) && this._editMode() !== "popup") {
container = container.closest(TR);
}
var id = container.attr(kendo.attr("uid")) || container.find("[ref='popup-edit-form']").attr(kendo.attr("uid"));
return this.dataSource.getByUid(id);
},
_calculateColumnIndex: function(cell) {
var cellIndex = this.cellIndex(cell);
var virtualOffset = 0;
if (this._hasVirtualColumns()) {
virtualOffset = parseInt($(cell).closest(TR).find("td").first().attr("colspan"), 10);
virtualOffset = (virtualOffset > 1 ? virtualOffset - 1 : 0);
}
return cellIndex + virtualOffset;
},
_editable: function() {
let that = this,
editable = that.options.editable,
handler = function() {
let target = activeElement(),
cell = that._editContainer;
if (cell && cell[0] && !$.contains(cell[0], target) && cell[0] !== target && !$(target).closest(".k-animation-container").length) {
if (that.editable.end()) {
that.closeCell();
that._toggleToolbarEditingItemsVisibility();
} else {
that._scrollVirtualWrapper();
}
}
},
mobileOS = kendo.support.mobileOS,
useDoubleTapEditing = !!(that._isMobile || mobileOS),
/*
https://github.com/telerik/kendo-ui-core/issues/7817
*/
userEventsPreventDefault = mobileOS && mobileOS.ios && (mobileOS.browser === "chrome" || mobileOS.browser === "edge");
that._isEditableEnabled = that._isEditableEnabled !== undefined$1 ? that._isEditableEnabled : !editable.readonly;
if (!that._isEditableEnabled) {
that._removeEditableClickHandlers();
}
if (editable && that._isEditableEnabled) {
let mode = that._editMode();
if (mode === "incell") {
that.table.add(that.lockedTable)
.on(MOUSEDOWN + NS, NAVROW + ">" + NAVCELL, function(e) {
let target = $(e.target);
if (that._editMode() === "incell" && target.hasClass("k-checkbox") && target.prev().attr(kendo.attr("bind"))) {
e.preventDefault();
}
});
if (editable.update !== false) {
if (isMac) {
that.wrapper
.on(CLICK + NS, ".k-edit-cell > input[type='checkbox']", function(e) {
// checking /unchecking a checkbox does not change the document.activeElement to be the checkbox
// this is necessary for the "focusout" event to be fired
$(e.target).trigger("focus");
})
.on(CLICK + NS, ".k-edit-cell", function(e) {
if (!$(e.target).is("input")) {
$(e.currentTarget).find("input[type='checkbox']").trigger("focus");
}
})
.on(MOUSEDOWN + NS, "tr:not(.k-grouping-row) > td", function(e) {
var editContainer = that._editContainer;
if (editContainer && editContainer[0] && ($.contains(editContainer[0], e.target) || editContainer[0] === e.target)) {
that._mousedownOnEditCell = true;
} else {
that._mousedownOnEditCell = false;
}
});
}
that.editableUserEvents = new kendo.UserEvents(that.wrapper, {
filter: "tr:not(.k-grouping-row) > td",
allowSelection: true,
preventDefault: userEventsPreventDefault,
supportDoubleTap: useDoubleTapEditing,
fastTap: useDoubleTapEditing,
[useDoubleTapEditing ? 'doubleTap' : 'tap']: function(e) {
var td = $(e.target),
isLockedCell = that.lockedTable && td.closest("table")[0] === that.lockedTable[0];
that._mousedownOnEditCell = false;
if (td.hasClass("k-hierarchy-cell") ||
td.hasClass("k-detail-cell") ||
td.hasClass("k-group-cell") ||
td.hasClass("k-edit-cell") ||
td.has(".k-grid-remove-command").length ||
(td.closest("tbody")[0] !== that.tbody[0] && !isLockedCell) ||
$(e.target).is(":input")) {
return;
}
if (that.editable) {
if (that.editable.end()) {
$(activeElement()).trigger("blur");
that.closeCell();
if (!that._requestInProgress) {
that.editCell(td);
}
} else {
that._scrollVirtualWrapper();
}
} else {
that.editCell(td);
}
}
});
that.wrapper.on("focusin" + NS, function() {
// fix focus issue in IE
if (!$.contains(this, activeElement())) {
clearTimeout(that.timer);
that.timer = null;
}
})
.on("focusout" + NS, function(e) {
var shouldCloseCell = true;
if ((isMac && that._mousedownOnEditCell) || that._virtualColScroll) {
shouldCloseCell = false;
}
that._mousedownOnEditCell = false;
if (shouldCloseCell) {
that.timer = setTimeout(function() {
handler();
}, 1);
}
});
}
} else {
if (editable.update !== false) {
that._editCommandClickHandler = that._editCommandClick.bind(that);
that.wrapper.on(CLICK + NS, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible .k-grid-edit-command", that._editCommandClickHandler);
if (that._isVirtualInlineEditable()) {
that.wrapper.on("focusout" + NS, "tr:not(.k-grouping-row) > td", function() {
if (that.editable && !that.editable.end()) {
that._scrollVirtualWrapper();
}
});
}
}
}
that._removeCommandClickHandler = that._removeCommandClick.bind(that);
that.wrapper.on(CLICK + NS, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible .k-grid-remove-command", that._removeCommandClickHandler);
}
},
_getLastSelectedItemModel: function() {
const that = this;
const isSelectable = that.options.selectable;
if (!isSelectable) {
return;
}
const selectedData = that.getSelectedData();
if (!selectedData || !selectedData.length) {
return;
}
const selected = selectedData[selectedData.length - 1];
const model = that.dataSource.getByUid(selected.uid);
return model;
},
_removeToolbarClick: function(e) {
if (e.event) {
e.event.preventDefault();
e.event.stopPropagation();
} else {
e.preventDefault();
}
const that = this;
const model = this._getLastSelectedItemModel();
if (!model) {
return;
}
const row = that.tbody.children("[" + kendo.attr("uid") + "=" + model.uid + "]");
that.removeRow(row);
that.one(DATABOUND, () => {
that._toggleToolbarEditingItemsVisibility();
});
},
_editToolbarClick: function(e) {
if (e.event) {
e.event.preventDefault();
e.event.stopPropagation();
} else {
e.preventDefault();
}
const that = this;
const isIncellEditing = that._editMode() === "incell";
if (isIncellEditing) {
return;
}
const model = this._getLastSelectedItemModel();
if (!model) {
return;
}
that.editRow(model);
},
_editCommandClick: function(e) {
let that = this,
element = $(e.currentTarget);
if (!that._belongsToGrid(element)) {
return;
}
e.preventDefault();
that.editRow(element.closest(TR));
},
_removeCommandClick: function(e) {
let that = this,
editable = that.options.editable,
element = $(e.currentTarget);
if (!that._belongsToGrid(element)) {
return;
}
if (editable.destroy !== false) {
e.preventDefault();
e.stopPropagation();
that.removeRow(element.closest(TR));
} else {
//Required for the MVC server wrapper delete button.
e.stopPropagation();
if (!that._confirmation()) {
e.preventDefault();
}
}
that._toggleToolbarEditingItemsVisibility();
},
editCell: function(cell) {
cell = $(cell);
let that = this,
column = leafColumns(that.columns)[that._calculateColumnIndex(cell)],
model = that._modelForContainer(cell);
that.closeCell();
if (model && isColumnEditable(column, model) && !column.command) {
if (that.trigger(BEFOREEDIT, { model: model })) {
return;
}
that._attachModelChange(model);
that._editContainer = cell;
if (that._shouldClearEditableState) {
that._clearEditableState();
}
that.editable = cell.addClass("k-edit-cell")
.kendoEditable({
fields: editField(column, that._isAdaptive() ? "auto" : "none"),
model: model,
size: that.options.size,
target: that,
change: function(e) {
if (that.trigger(SAVE, { values: e.values, container: cell, model: model })) {
e.preventDefault();
}
},
skipFocus: (that._isVirtualIncellEditable() || that._hasVirtualColumns()) && that._editableState ? true : false
}).data("kendoEditable");
let tr = cell.parent().addClass("k-grid-edit-row");
if (model.new === true) {
tr.addClass("k-grid-add-row");
delete model.new;
}
if (that.lockedContent) {
adjustRowHeight(tr[0], that._relatedRow(tr).addClass("k-grid-edit-row")[0]);
if (tr.hasClass("k-grid-add-row")) {
that._relatedRow(tr).addClass("k-grid-add-row");
}
that._syncLockedScroll();
}
that.trigger(EDIT, { container: cell, model: model });
that._toggleToolbarEditingItemsVisibility();
}
},
enableEditing: function() {
let that = this,
toolbar = that.wrapper.find(".k-grid-toolbar");
if (!that._isEditableEnabled) {
that._isEditableEnabled = true;
that._editable();
let addButton = toolbar.find(".k-grid-add").getKendoButton();
let editButton = toolbar.find(".k-grid-edit-command").getKendoButton();
let removeButton = toolbar.find(".k-grid-remove-command").getKendoButton();
let cancelChangesButton = toolbar.find(".k-grid-cancel-changes").getKendoButton();
let saveChangesButton = toolbar.find(".k-grid-save-changes").getKendoButton();
let cancelButton = toolbar.find(".k-grid-cancel-command").getKendoButton();
let saveButton = toolbar.find(".k-grid-save-command").getKendoButton();
if (addButton) {
addButton.bind("click", that._createClickHandler);
}
if (editButton) {
editButton.bind("click", that._editClickHandler);
}
if (removeButton) {
removeButton.bind("click", that._destroyClickHandler);
}
if (cancelChangesButton) {
cancelChangesButton.bind("click", that._cancelClickHandler);
}
if (saveChangesButton) {
saveChangesButton.bind("click", that._saveClickHandler);
}
if (cancelButton) {
cancelButton.bind("click", that._editCancelClickHandler);
}
if (saveButton) {
saveButton.bind("click", that._updateClickHandler);
}
}
that._toggleToolbarEditingItemsVisibility();
},
disableEditing: function() {
let that = this;
if (that._isEditableEnabled) {
if (that._editMode() === "incell") {
that.closeCell();
} else {
that.cancelRow();
}
that._clearEditableState();
that._destroyEditable();
if (that.editableUserEvents) {
that.editableUserEvents.destroy();
that.editableUserEvents = null;
}
that._removeEditableClickHandlers();
that._isEditableEnabled = false;
that._toggleToolbarEditingItemsVisibility();
}
},
_removeEditableClickHandlers: function() {
let that = this,
toolbar = that.wrapper.find(".k-grid-toolbar");
that.wrapper.off(CLICK + NS, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible .k-grid-edit-command", that._editCommandClickHandler);
that.wrapper.off(CLICK + NS, "tbody>tr:not(.k-detail-row,.k-grouping-row):visible .k-grid-remove-command", that._removeCommandClickHandler);
toolbar.off(CLICK + NS, ".k-grid-add", that._createClickHandler);
toolbar.off(CLICK + NS, ".k-grid-edit-command", that._editClickHandler);
toolbar.off(CLICK + NS, ".k-grid-remove-command", that._destroyClickHandler);
let addButton = toolbar.find(".k-grid-add").getKendoButton();
let editButton = toolbar.find(".k-grid-edit-command").getKendoButton();
let removeButton = toolbar.find(".k-grid-remove-command").getKendoButton();
let cancelChangesButton = toolbar.find(".k-grid-cancel-changes").getKendoButton();
let saveChangesButton = toolbar.find(".k-grid-save-changes").getKendoButton();
let cancelButton = toolbar.find(".k-grid-cancel-command").getKendoButton();
let saveButton = toolbar.find(".k-grid-save-command").getKendoButton();
if (addButton) {
addButton.unbind("click");
}
if (editButton) {
editButton.unbind("click");
}
if (removeButton) {
removeButton.unbind("click");
}
if (cancelChangesButton) {
cancelChangesButton.unbind("click");
}
if (saveChangesButton) {
saveChangesButton.unbind("click");
}
if (cancelButton) {
cancelButton.unbind("click");
}
if (saveButton) {
saveButton.unbind("click");
}
that._editCommandClickHandler = null;
that._removeCommandClickHandler = null;
},
_adjustLockedHorizontalScrollBar: function() {
var table = this.table,
content = table.parent();
var scrollbar = table[0].offsetWidth > content[0].clientWidth ? kendo.support.scrollbar() : 0;
this.lockedContent.height(content[0].offsetHeight - scrollbar);
},
_syncLockedScroll: function() {
this.lockedContent[0].scrollTop = this.content[0].scrollTop;
if (this.virtualScrollable) {
this.lockedContent[0].scrollTop = this.wrapper.find(".k-virtual-scrollable-wrap")[0].scrollTop;
}
},
_syncLockedContentHeight: function() {
if (this.lockedTable) {
if (!this.touchScroller) {
this._adjustLockedHorizontalScrollBar();
}
this._adjustRowsHeight(this.table, this.lockedTable);
}
},
_syncLockedHeaderHeight: function() {
if (this.lockedHeader) {
var lockedTable = this.lockedHeader.children("table");
var table = this.thead.parent();
this._adjustRowsHeight(lockedTable, table);
syncTableHeight(lockedTable, table);
}
},
_syncLockedFooterHeight: function() {
if (this.lockedFooter && this.footer && this.footer.length) {
this._adjustRowsHeight(this.lockedFooter.children("table"), this.footer.find(".k-grid-footer-wrap > table"));
}
},
_destroyEditable: function() {
let that = this;
const component = that._editContainer && that._editContainer.length && that._editContainer.closest(".k-window").length ? "kendoWindow" : "kendoActionSheet";
let destroy = function() {
if (that.editable) {
let container = that.editView ? that.editView.element : that._editContainer;
let window = that._editContainer.data(component);
if (container) {
if (window) {
container = window.wrapper;
}
container.off(CLICK + NS, ".k-grid-cancel-command, button[ref-cancel-button], [ref-actionsheet-action-button]:not(.k-button-solid-primary)", that._editCancelClickHandler);
container.off(CLICK + NS, ".k-grid-save-command, button[ref-update-button], [ref-actionsheet-action-button].k-button-solid-primary", that._editUpdateClickHandler);
}
that._detachModelChange();
that.editable.destroy();
that.editable = null;
if (window) {
window.destroy();
}
that._editContainer = null;
that._destroyEditView();
that._editableIsClosing = null;
}
};
if (that.editable) {
if (that._editMode() === "popup" && !that._isMobile) {
if (that._editableIsClosing) {
that._editContainer.data(component).bind("deactivate", destroy);
}
else {
that._editableIsClosing = true;
that._editContainer.data(component).bind("deactivate", destroy).close();
}
} else {
destroy();
}
}
if (that._confirmDialog) {
that._confirmDialog.close();
that._confirmDialog.destroy();
that._confirmDialog = null;
}
},
_destroyEditView: function() {
if (this.editView) {
this.editView.purge();
this.editView = null;
this.pane.navigate("");
}
},
_attachModelChange: function(model) {
var that = this;
that._modelChangeHandler = function(e) {
that._modelChange({ field: e.field, model: this });
};
model.bind("change", that._modelChangeHandler);
},
_detachModelChange: function() {
var that = this,
container = that._editContainer,
model = that._modelForContainer(container);
if (model) {
model.unbind(CHANGE, that._modelChangeHandler);
}
},
closeCell: function(isCancel) {
let that = this,
cell = that._editContainer,
column,
tr,
model,
errors;
if (!cell) {
return;
}
model = that._modelForContainer(cell);
if (isCancel && that.trigger("cancel", { container: cell, model: model })) {
return;
}
that.trigger(CELLCLOSE, { type: isCancel ? "cancel" : "save", model: model, container: cell });
cell.removeClass("k-edit-cell");
column = leafColumns(that.columns)[that._calculateColumnIndex(cell)];
errors = that.editable && that.editable.validatable && that.editable.validatable.errors();
if (isCancel && model.dirtyFields && model.dirtyFields[column.field] && errors.length) {
delete model.dirtyFields[column.field];
}
tr = cell.parent().removeClass("k-grid-edit-row");
if (tr.hasClass("k-grid-add-row")) {
tr.removeClass("k-grid-add-row");
}
if (that.lockedContent) {
const relatedTr = that._relatedRow(tr);
relatedTr.removeClass("k-grid-edit-row");
if (relatedTr.hasClass("k-grid-add-row")) {
relatedTr.removeClass("k-grid-add-row");
}
}
that._destroyEditable(); // editable should be destroyed before content of the container is changed
that._displayCell(cell, column, model);
if (that._shouldClearEditableState) {
that._clearEditableState();
}
that.trigger("itemChange", { item: tr, data: model, ns: ui });
if (that.lockedContent) {
const rowUID = tr && tr.data("uid");
const heightValue = (that._cachedRowsHeight && that._cachedRowsHeight[rowUID]) ?? "";
adjustRowHeight(tr.css(HEIGHT, heightValue)[0], that._relatedRow(tr).css(HEIGHT, heightValue)[0]);
}
},
_displayCell: function(cell, column, dataItem) {
var that = this,
state = { storage: {}, count: 0 },
settings = extend({}, kendo.Template, that.options.templateSettings),
tmpl = kendo.template(that._cellTmpl(column, state), settings);
if (state.count > 0) {
tmpl = tmpl.bind(state.storage);
}
cell.empty().html(tmpl(dataItem));
},
removeRow: function(row) {
if (!this._confirmation(row)) {
return;
}
this._removeRow(row);
},
_removeRow: function(row) {
var that = this,
model,
modelId,
key,
schema,
mode = that._editMode();
if (mode !== "incell") {
that.cancelRow();
}
row = $(row);
if (that.lockedContent) {
row = row.add(that._relatedRow(row));
}
row = row.hide();
if (that.dataSource._isGroupPaged()) {
that._removeGroupIfEmpty(row);
}
model = that._modelForContainer(row);
if (model != undefined$1 && model.hasOwnProperty("_isMoved")) {
delete model._isMoved;
}
if (model && !that.trigger(REMOVE, { row: row, model: model })) {
schema = that.dataSource.options.schema;
if (that._selectedIds && schema && schema.model) {
modelId = that._getSchemaIdField();
key = model[modelId];
delete that._selectedIds[key];
}
that.dataSource.remove(model);
if (mode === "inline" || mode === "popup") {
that.dataSource.sync();
}
} else if (mode === "incell") {
that._destroyEditable();
}
},
_editMode: function() {
let mode = "incell",
editable = this.options.editable;
if (editable !== true) {
if (typeof editable == "string") {
mode = editable;
} else {
mode = editable.mode || mode;
}
}
return mode;
},
editRow: function(row) {
let model,
that = this;
if (row instanceof ObservableObject) {
model = row;
} else {
row = $(row);
model = that._modelForContainer(row);
}
let mode = that._editMode();
let container;
that.cancelRow();
if (model) {
row = that.tbody.children("[" + kendo.attr("uid") + "=" + model.uid + "]");
that._attachModelChange(model);
if (mode === "popup") {
that._createPopupEditor(model);
} else if (mode === "inline") {
that._createInlineEditor(row, model);
} else if (mode === "incell") {
$(row).children(DATA_CELL).each(function() {
let cell = $(this);
let column = leafColumns(that.columns)[that._calculateColumnIndex(cell)];
model = that._modelForContainer(cell);
if (model && (!model.editable || model.editable(column.field)) && column.field && !column.selectable) {
that.editCell(cell);
return false;
}
});
}
container = that.editView ? that.editView.element : mode === "popup" ? that._editContainer.parent() : that._editContainer;
if (container) {
if (!this._editCancelClickHandler) {
this._editCancelClickHandler = this._editCancelClick.bind(this);
}
container.on(CLICK + NS, ".k-grid-cancel-command, button[ref-cancel-button], [ref-actionsheet-action-button]:not(.k-button-solid-primary)", this._editCancelClickHandler);
if (!this._editUpdateClickHandler) {
this._editUpdateClickHandler = this._editUpdateClick.bind(this);
}
container.on(CLICK + NS, ".k-grid-save-command, button[ref-update-button], [ref-actionsheet-action-button].k-button-solid-primary", this._editUpdateClickHandler);
}
that._toggleToolbarEditingItemsVisibility();
}
},
_editUpdateClick: function(e) {
e.preventDefault();
if (e.stopPropagation) {
e.stopPropagation();
} else if (e.event && e.event.stopPropagation) {
e.event.stopPropagation();
}
this.saveRow();
this._preventOnCloseEditableChanges = this._editMode() === "popup";
this.one(DATABOUND, () => {
this._toggleToolbarEditingItemsVisibility();
});
},
_editCancelClick: function(e) {
var that = this;
var navigatable = that.options.navigatable;
var model = that.editable.options.model;
var container = that.editView ? that.editView.element : that._editContainer;
e.preventDefault();
if (e.stopPropagation) {
e.stopPropagation();
} else if (e.event && e.event.stopPropagation) {
e.event.stopPropagation();
}
if (that.trigger("cancel", { container: container, model: model })) {
return;
}
var currentIndex = that.items().index($(that.current()).parent());
that.cancelRow();
if (navigatable) {
that._setCurrent(that.items().eq(currentIndex).children().filter(NAVCELL).first());
focusTable(that.table, true);
}
this._toggleToolbarEditingItemsVisibility();
},
_editFields: function(columns, model) {
var fields = [];
var column;
for (var idx = 0; idx < columns.length; idx++) {
column = columns[idx];
if (column.selectable || column.command) {
continue;
}
if (isColumnEditable(column, model)) {
fields.push(editField(column, this._isAdaptive() ? "auto" : "none"));
}
}
return fields;
},
_createPopupEditor: function(model) {
var that = this;
var html = '<div ' + kendo.attr("uid") + '="' + model.uid + '" ref="popup-edit-form"><' + (that._isMobile ? 'ul class="k-edit-form-container k-listgroup k-listgroup-flush">' : 'div class="k-edit-form-container">');
var column;
var command;
var idx;
var length;
var tmpl;
var updateText;
var cancelText;
var updateIconClass;
var cancelIconClass;
var tempCommand;
var columns = leafColumns(that.columns);
var attr;
var editMenuGuid = kendo.guid();
var editable = that.options.editable;
var template = editable.template;
var options = isPlainObject(editable) ? editable.window : {};
var settings = extend({}, kendo.Template, that.options.templateSettings);
var state;
var container;
var buttonsHTML;
const isAdaptive = that._isAdaptive();
if (that.trigger(BEFOREEDIT, { model: model })) {
return;
}
options = options || {};
if (template) {
if (typeof template === STRING) {
template = kendo.unescape(template);
}
html += (kendo.template(template, settings))(model);
for (idx = 0, length = columns.length; idx < length; idx++) {
column = columns[idx];
if (column.command) {
tempCommand = getCommand(column.command, "edit");
if (tempCommand) {
command = tempCommand;
}
}
}
} else {
for (idx = 0, length = columns.length; idx < length; idx++) {
column = columns[idx];
if (column.selectable) {
continue;
}
if (!column.command) {
if (that._isMobile) {
html += '<li class="k-item k-listgroup-item">';
if (isColumnEditable(column, model)) {
html += '<label class="k-label k-listgroup-form-row">';
html += '<span class="k-item-title k-listgroup-form-field-label">' + (column.title && (that.options.encodeTitles ? htmlEncode(column.title, true) : column.title) || column.field || "") + '</span>';
html += '<div class="k-listgroup-form-field-wrapper" id="' + column.field + '_' + editMenuGuid + '" ' + kendo.attr("container-for") + '="' + column.field + '"></div>';
html += '</label>';
} else {
state = { storage: {}, count: 0 };
tmpl = kendo.template(that._cellTmpl(column, state), settings);
if (state.count > 0) {
tmpl = tmpl.bind(state.storage);
}
html += '<label class="k-label k-listgroup-form-row k-no-click">';
html += '<span class="k-item-title k-listgroup-form-field-label">' + (column.title && (that.options.encodeTitles ? htmlEncode(column.title, true) : column.title) || column.field || "") + '</span>';
html += '<span class="k-no-editor k-listgroup-form-field-wrapper">' + tmpl(model) + '</span>';
html += '</label>';
}
html += "</li>";
}
} else if (column.command) {
tempCommand = getCommand(column.command, "edit");
if (tempCommand) {
command = tempCommand;
}
}
}
}
if (command) {
if (isPlainObject(command)) {
if (isPlainObject(command.text)) {
updateText = command.text.update;
cancelText = command.text.cancel;
}
if (isPlainObject(command.iconClass)) {
updateIconClass = command.iconClass.update;
cancelIconClass = command.iconClass.cancel;
}
if (command.attr) {
attr = command.attr;
}
}
}
if (!that._isMobile) {
let updateButton = $(that._createButton({ name: "update", text: updateText, attr: attr, iconClass: updateIconClass, size: "medium", skipCommandClass: true },)).attr("ref-update-button", "");
let cancelButton = $(that._createButton({ name: "canceledit", text: cancelText, attr: attr, iconClass: cancelIconClass, size: "medium", skipCommandClass: true })).attr("ref-cancel-button", "");
html += '</div>';
if (isAdaptive) {
container = that._editContainer = $(html)
.appendTo("body").eq(0).kendoActionSheet({
modal: true,
adaptive: true,
title: model.id ? "Edit record" : "Add new record",
fullscreen: that.smallMQL.mediaQueryList.matches,
closeButton: true,
actionButtons: [
{
text: "Cancel",
icon: "cancel",
},
{
text: "Save",
icon: "save",
themeColor: "primary",
}
],
open: function(e) {
e.sender.element.removeClass("k-popup");
that.editable.element.focus();
},
close: function(e) {
e.sender.element.trigger("focus");
if (!that._preventOnCloseEditableChanges) {
if (that.trigger("cancel", { container: container, model: model })) {
e.preventDefault();
return;
}
}
var currentIndex = that.items().index($(that.current()).parent());
if (!that._preventOnCloseEditableChanges) {
that._editableIsClosing = true;
that.cancelRow(false, true);
}
if (that.options.navigatable) {
that._setCurrent(that.items().eq(currentIndex).children().filter(NAVCELL).first());
focusTable(that.table, true);
}
that._toggleToolbarEditingItemsVisibility();
}
});
} else {
container = that._editContainer = $(html)
.appendTo(that.wrapper).eq(0)
.kendoWindow(extend({
modal: true,
resizable: false,
draggable: true,
title: that.options.messages.commands.edit || "Edit",
_footerTemplate: () =>
`<div class="k-actions k-actions-start k-actions-horizontal k-window-actions">` +
updateButton[0].outerHTML +
cancelButton[0].outerHTML +
`</div>`,
visible: false,
close: function(e) {
if (e.userTriggered) {
//The bellow line is required due to: draggable window in IE, change event will be triggered while the window is closing
e.sender.element.trigger("focus");
if (that.trigger("cancel", { container: container, model: model })) {
e.preventDefault();
return;
}
var currentIndex = that.items().index($(that.current()).parent());
that._editableIsClosing = true;
that.cancelRow();
that._toggleToolbarEditingItemsVisibility();
if (that.options.navigatable) {
that._setCurrent(that.items().eq(currentIndex).children().filter(NAVCELL).first());
focusTable(that.table, true);
}
}
}
}, options));
}
} else {
html += "</ul></div>";
let cancelText = encode(that.options.messages.commands.cancel);
let updateText = encode(that.options.messages.commands.update);
that.editView = that.pane.append(
'<div data-' + kendo.ns + 'role="view" class="k-grid-edit-form">' +
'<div data-' + kendo.ns + ' class="k-appbar k-appbar-primary">' +
kendo.html.renderButton(`<button class="k-header-cancel k-grid-cancel-command" title="${cancelText}" aria-label="${cancelText}"></button>`, {
fillMode: "flat",
icon: "chevron-left"
}) +
'<span class="k-spacer"></span>' +
`<span>${encode(that.options.messages.commands.edit || "Edit")}</span>` +
'<span class="k-spacer"></span>' +
kendo.html.renderButton(`<button class="k-header-done k-grid-save-command" title="${updateText}" aria-label="${updateText}"></button>`, {
fillMode: "flat",
icon: "check"
}) +
'</div>' +
'<div data-' + kendo.ns + 'role="content" class="' + classNames.content + '">' +
html +
'</div>' +
'</div>');
container = that._editContainer = that.editView.element.find("[ref='popup-edit-form']");
}
if (!template && !that._isMobile) {
that.editable = new ui.Form(that._editContainer.find(".k-edit-form-container"), {
items: that._editFields(columns, model),
buttonsTemplate: () => '',
formData: model,
size: that._isAdaptive() ? "large" : "medium"
}).editable;
that._editContainer.append(buttonsHTML);
if (isAdaptive) {
that.editable.element.removeClass("k-edit-form-container");
}
} else {
that.editable = that._editContainer
.kendoEditable({
fields: (that._isMobile && !template) ? that._editFields(columns, model) : null,
model: model,
clearContainer: false,
target: that,
skipFocus: true
}).data("kendoEditable");
if (isAdaptive) {
that.editable.element.find(".k-edit-form-container").removeClass("k-edit-form-container");
}
}
that._openPopUpEditor(isAdaptive);
that.trigger(EDIT, { container: container, model: model });
},
_openPopUpEditor: function(isAdaptive) {
var that = this;
const component = isAdaptive ? "kendoActionSheet" : "kendoWindow";
var editor = that._editContainer ? that._editContainer.data(component) : null;
var windowOptions = (that.options.editable || {}).window || {};
if (!this._isMobile) {
if (editor) {
if (!isAdaptive && !windowOptions.position) {
editor.center();
} else if (isAdaptive) {
editor.fullscreen(that.smallMQL.mediaQueryList.matches);
}
editor.open();
}
} else {
this.pane.navigate(this.editView, this._editAnimation);
}
},
_createInlineEditor: function(row, model) {
var that = this;
var column;
var cell;
var command;
var fields = [];
if (that.trigger(BEFOREEDIT, { model: model })) {
return;
}
if (that.lockedContent) {
row = row.add(that._relatedRow(row));
}
row.children(":not(.k-group-cell,.k-hierarchy-cell)").each(function() {
cell = $(this);
column = leafColumns(that.columns)[that._calculateColumnIndex(cell)];
if (!column.command && isColumnEditable(column, model)) {
fields.push(editField(column, that._isAdaptive() ? "auto" : "none"));
cell.attr(kendo.attr("container-for"), column.field);
cell.empty();
} else if (column.command) {
command = getCommand(column.command, "edit");
if (command) {
cell.empty();
var updateText,
cancelText,
updateIconClass,
cancelIconClass,
attr;
if (isPlainObject(command)) {
if (isPlainObject(command.text)) {
updateText = command.text.update;
cancelText = command.text.cancel;
}
if (isPlainObject(command.iconClass)) {
updateIconClass = command.iconClass.update;
cancelIconClass = command.iconClass.cancel;
}
if (command.attr) {
attr = command.attr;
}
}
$(that._createButton({ name: "update", text: updateText, attr: attr, iconClass: updateIconClass, skipTabIndex: true }) +
that._createButton({ name: "canceledit", text: cancelText, attr: attr, iconClass: cancelIconClass, skipTabIndex: true })).appendTo(cell);
}
}
});
that._editContainer = row;
that._editContainer.addClass("k-grid-edit-row");
if (model.new === true) {
that._editContainer.addClass("k-grid-add-row");
delete model.new;
}
if (that._shouldClearEditableState) {
that._clearEditableState();
}
that.editable = new kendo.ui.Editable(that._editContainer, {
target: that,
fields: fields,
size: that.options.size,
model: model,
skipFocus: (that._isVirtualInlineEditable() && that._editableState && (that._editableState.field ? true : false)) || that._hasVirtualColumns(),
clearContainer: false
});
if (row.length > 1) {
adjustRowHeight(row[0], row[1]);
that._applyLockedContainersWidth(true);
}
that.trigger(EDIT, { container: row, model: model });
},
cancelRow: function(notify) {
var that = this,
container = that._editContainer,
model;
if (container) {
model = that._modelForContainer(container);
if (!model || (notify && that.trigger("cancel", { container: container, model: model }))) {
return;
}
that._destroyEditable();
that.dataSource.cancelChanges(model);
that._clearEditableState();
if (that._editMode() !== "popup") {
that._displayRow(container);
} else {
that._displayRow(that.tbody.find("[" + kendo.attr("uid") + "=" + model.uid + "]"));
}
that._aria();
}
},
saveRow: function() {
var that = this;
var container = this._editContainer;
var model = this._modelForContainer(container);
var deferred = $.Deferred();
var valid;
if (!container || !this.editable) {
return deferred.resolve().promise();
}
valid = that.editable && that.editable.end();
if (!valid || this.trigger(SAVE, { container: container, model: model })) {
if (!valid) {
that._scrollVirtualWrapper();
}
return deferred.reject().promise();
}
that._clearEditableState();
return this.dataSource.sync();
},
_displayRow: function(row) {
var that = this,
model = that._modelForContainer(row),
related,
newRow,
nextRow,
isSelected = row.hasClass(SELECTED),
isAlt = row.hasClass("k-table-alt-row");
if (model) {
if (that.lockedContent) {
related = $((isAlt ? that.lockedAltRowTemplate : that.lockedRowTemplate)(model));
kendo.applyStylesFromKendoAttributes(related, ["display"]);
that._relatedRow(row.last()).replaceWith(related);
}
newRow = $((isAlt ? that.altRowTemplate : that.rowTemplate)(model));
if (!row.is(":visible")) {
newRow.hide();
}
kendo.applyStylesFromKendoAttributes(newRow, ["display"]);
if (that._anyStickyColumns()) {
kendo.applyStylesFromKendoAttributes(newRow, ["left", "right"]);
}
row.replaceWith(newRow);
that.trigger("itemChange", { item: newRow, data: model, ns: ui });
if (related && related.length) {
that.trigger("itemChange", { item: related, data: model, ns: ui });
}
if (isSelected && (that.options.selectable || that._checkBoxSelection)) {
that.select(newRow.add(related));
}
if (related) {
adjustRowHeight(newRow[0], related[0]);
}
nextRow = newRow.next();
if (nextRow.hasClass("k-detail-row") && nextRow.is(":visible")) {
kendo.ui.icon(newRow.find(".k-hierarchy-cell .k-icon,.k-hierarchy-cell .k-svg-icon"), { icon: "caret-alt-down" });
}
}
},
_showMessage: function(messages, row) {
var that = this;
if (!that._isMobile) {
// eslint-disable-next-line no-alert
return window.confirm(messages.title);
}
var confirmDialog = that._confirmDialog = new kendo.ui.Confirm($("<div />").appendTo(document.body), {
modal: {
preventScroll: true
},
closable: false,
title: false,
content: messages.title,
messages: {
okText: messages.confirmDelete,
cancel: messages.cancelDelete
},
open: function() {
if (that.content) {
that.content.data(OVERFLOW, that.content.css(OVERFLOW));
that.content.css(OVERFLOW, HIDDEN);
}
},
close: function() {
if (that.content) {
that.content.css(OVERFLOW, that.content.data(OVERFLOW));
}
}
});
confirmDialog.result
.done(function() {
that._removeRow(row);
})
.fail(function() {
var confirmDialog = that._confirmDialog;
if (confirmDialog) {
confirmDialog.close();
confirmDialog.destroy();
}
});
return false;
},
_confirmation: function(row) {
var that = this,
editable = that.options.editable,
confirmation = (editable === true || typeof editable === STRING) ? that.options.messages.editable.confirmation : editable.confirmation;
if (isPlainObject(editable) && typeof editable.mode === STRING && typeof confirmation !== FUNCTION && typeof confirmation !== STRING && confirmation !== false) {
confirmation = that.options.messages.editable.confirmation;
}
if (confirmation !== false && confirmation != null) {
if (typeof confirmation === FUNCTION) {
confirmation = confirmation(that._modelForContainer(row));
}
return that._showMessage({
confirmDelete: editable.confirmDelete || that.options.messages.editable.confirmDelete,
cancelDelete: editable.cancelDelete || that.options.messages.editable.cancelDelete,
title: confirmation === true ? that.options.messages.editable.confirmation : confirmation
}, row);
}
return true;
},
cancelChanges: function() {
var that = this;
if (that._cachedRowsHeight) {
that._mapCachedRowsHeight("getByUid", "id");
that._shouldMapHights = true;
}
that.dataSource.cancelChanges();
if (that._isVirtualEditable()) {
that._virtualPageToTop(function() {
that.virtualScrollable.scrollToTop();
});
}
},
saveChanges: function() {
var that = this;
var valid = that.editable && that.editable.end();
if ((valid || !that.editable) && !that.trigger(SAVECHANGES)) {
that.dataSource.sync();
} else if (!valid) {
that._scrollVirtualWrapper();
}
},
addRow: function() {
var that = this,
index,
dataSource = that.dataSource,
mode = that._editMode(),
createAt = that.options.editable.createAt || "",
pageSize = dataSource.pageSize(),
view = dataSource.view() || [];
var createAtBottom = createAt.toLowerCase() === BOTTOM;
var model;
var virtualEditable = that._isVirtualEditable();
if ((that.editable && that.editable.end()) || !that.editable) {
if (mode != "incell") {
that.cancelRow();
}
index = dataSource.indexOf(view[0]);
if (createAtBottom) {
index += view.length;
if (pageSize && !dataSource.options.serverPaging && pageSize <= view.length) {
index -= 1;
}
}
if (index < 0) {
if (dataSource.page() > dataSource.totalPages()) {
index = (dataSource.page() - 1) * pageSize;
} else {
index = 0;
}
}
if (that.options.navigatable && mode == "incell") {
that._removeCurrent();
}
if (virtualEditable) {
that._virtualAddRow();
} else {
model = dataSource.insert(index, {});
model.new = true;
that._editModel(model);
}
} else {
that._scrollVirtualWrapper();
}
},
_editModel: function(model) {
var that = this;
var createAt = that.options.editable.createAt || "";
var mode = that._editMode();
if (model) {
var id = model.uid,
table = that.lockedContent ? that.lockedTable : that.table,
row = table.find("tr[" + kendo.attr("uid") + "=" + id + "]"),
cell = row.children("td:not(.k-group-cell,.k-hierarchy-cell)").eq(that._firstEditableColumnIndex(row));
if (mode === "inline" && row.length) {
that.editRow(row);
} else if (mode === "popup") {
that.editRow(model);
} else if (cell.length) {
that.editCell(cell);
}
if (createAt.toLowerCase() == "bottom" && that.lockedContent) {
//scroll the containers to the bottom
that.lockedContent[0].scrollTop = that.content[0].scrollTop = that.table[0].offsetHeight;
}
}
},
_virtualAddRow: function() {
var that = this;
var createAtBottom = (that.options.editable.createAt || "").toLowerCase() === BOTTOM;
that._clearEditableState();
if (createAtBottom) {
that._virtualAddRowAtBottom();
} else {
that._virtualAddRowAtTop();
}
},
_virtualAddRowAtTop: function() {
var that = this;
var dataSource = that.dataSource;
var virtualScrollable = that.virtualScrollable;
var model;
if (dataSource.page() === 1) {
model = dataSource.insert(0, {});
model.new = true;
that._editModel(model);
virtualScrollable.scrollToTop();
} else {
that._virtualPageToTop(function() {
model = dataSource.insert(0, {});
model.new = true;
that._editModel(model);
virtualScrollable.scrollToTop();
});
}
},
_virtualAddRowAtBottom: function() {
var that = this;
var dataSource = that.dataSource;
var virtualScrollable = that.virtualScrollable;
var index = dataSource.total();
var model;
if (dataSource.at(index - 1) instanceof ObservableObject) {
model = dataSource.insert(index, {});
model.new = true;
that._virtualPageToBottom(function() {
that._editModel(model);
virtualScrollable.scrollToBottom();
});
} else {
that._virtualPageToBottom(function() {
model = dataSource.insert(index, {});
model.new = true;
that._editModel(model);
virtualScrollable.scrollToBottom();
});
}
},
_virtualPageToTop: function(callback) {
var that = this;
that._virtualPage(0, that.dataSource.take(), function() {
callback();
});
},
_virtualPageToBottom: function(callback) {
var that = this;
var dataSource = that.dataSource;
var take = dataSource.take();
var total = dataSource.total();
var skip = total > take ? (total - take) : 0;
that._virtualPage(skip, take, function() {
callback();
});
},
_virtualPage: function(skip, take, callback) {
var that = this;
if (that._isVirtualEditable()) {
that.virtualScrollable._preventScroll = true;
that.virtualScrollable._page(skip, take, callback);
}
},
_firstEditableColumnIndex: function(container) {
var that = this,
column,
columns = leafColumns(that.columns),
idx,
length,
model = that._modelForContainer(container);
for (idx = 0, length = columns.length; idx < length; idx++) {
column = columns[idx];
if (model && (!model.editable || model.editable(column.field)) && !column.command && column.field && column.hidden !== true) {
return idx;
}
}
return -1;
},
_clickAdd: function(e) {
if (e.preventDefault) {
e.preventDefault();
}
this.addRow();
this._toggleToolbarEditingItemsVisibility();
},
_clickCancel: function(e) {
if (e.preventDefault) {
e.preventDefault();
}
this.cancelChanges();
this._toggleToolbarEditingItemsVisibility();
},
_clickExcel: function(e) {
var that = this;
var deferred = $.Deferred();
if (e.preventDefault) {
e.preventDefault();
}
that._isExport = true;
that._progress(true);
setTimeout(() => {
that.saveAsExcel(deferred);
deferred.always(() => {
that._progress(false);
that._isExport = false;
});
}, 1);
},
_clickPdf: function(e) {
var that = this;
if (e.preventDefault) {
e.preventDefault();
}
that._isExport = true;
that._pdfInitialized = true;
that._progress(true);
var promise = that.saveAsPDF();
if (promise) {
promise.done(function() {
that._progress(false);
that._isExport = false;
that._pdfInitialized = false;
});
} else {
that._progress(false);
that._isExport = false;
that._pdfInitialized = false;
}
},
_clickSave: function(e) {
if (e.preventDefault) {
e.preventDefault();
}
this.saveChanges();
this.one(DATABOUND, () => {
this._toggleToolbarEditingItemsVisibility();
});
},
_searchInput: function(e) {
var that = this,
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 (that.dataSource.options.endless) {
that.dataSource.options.endless = null;
that._endlessPageSize = that.dataSource.options.pageSize;
}
if (value) {
for (var i = 0; i < searchFields.length; i++) {
that._pushExpression(expression.filters, searchFields[i], value);
}
} else {
expression = {};
}
that.dataSource.filter(expression);
}, 300);
},
_pasteToolbarDropDown: function() {
var that = this;
if (that.wrapper.find(".k-grid-paste-action").length) {
that.pasteActionsDropDownList = that.wrapper
.find(".k-grid-paste-action")
.kendoDropDownList({
dataSource: [{ value: "insert", text: "Paste (Insert)" }, { value: "replace", text: "Paste (Replace)" }],
dataTextField: "text",
dataValueField: "value",
_allowFilterPaste: false,
}).data("kendoDropDownList");
}
},
_pushExpression: function(filters, field, value) {
var that = this,
isServerFiltering = that.dataSource.options.serverFiltering,
defaultOperators = {
string: "contains",
number: "gte",
date: "gte",
enums: "eq",
boolean: "eq"
},
name = field.name || field,
operator = field.operator,
modelInfo = that.dataSource.reader.model && that.dataSource.reader.model.fields,
fieldInfo = modelInfo && modelInfo[name],
parseFn = fieldInfo && fieldInfo.parse,
expression = {
field: name,
operator: operator || defaultOperators.string,
value: value
};
if ((operator || isServerFiltering) && fieldInfo && kendo.isFunction(parseFn) && parseFn(value) !== null) {
extend(expression, {
operator: operator || defaultOperators[fieldInfo.type],
value: parseFn(value)
});
}
if (isServerFiltering && fieldInfo && kendo.isFunction(parseFn) && parseFn(value) === null) {
return;
}
filters.push(expression);
},
_hasTool: function(selector) {
const that = this;
const tool = that.wrapper.find(`.k-grid-toolbar ${selector}`);
return {
present: tool.length > 0,
tool: tool
};
},
_initToolbarItemsPopups: function() {
const that = this;
const columnsToolbarButton = that._hasTool(".k-toolbar-button.k-grid-column-menu[ref-toolbar-tool]");
const sortToolbarButton = that._hasTool(".k-toolbar-button.k-grid-sort-tool[ref-toolbar-tool]");
const filterToolbarTool = that._hasTool(".k-toolbar-button.k-grid-filter-tool[ref-toolbar-tool]");
const columnChooserTool = that._hasTool(".k-toolbar-button.k-grid-column-chooser[ref-toolbar-tool]");
const groupToolbarTool = that._hasTool(".k-toolbar-button.k-grid-group-tool[ref-toolbar-tool]");
if (columnsToolbarButton.present) {
that._globalColumnsMenu(columnsToolbarButton.tool);
}
if (columnChooserTool.present) {
that._columnChooserTool(columnChooserTool.tool);
}
if (sortToolbarButton.present) {
that._toggleBadge(sortToolbarButton.tool, that.dataSource.sort());
that._sortToolbarTool(sortToolbarButton.tool);
}
if (filterToolbarTool.present) {
that._toggleBadge(filterToolbarTool.tool, that.dataSource.filter());
that._filterToolbarTool(filterToolbarTool.tool);
}
if (groupToolbarTool.present) {
const groups = that.dataSource.group();
that._toggleBadge(groupToolbarTool.tool, groups && groups.length);
that._groupToolbarTool(groupToolbarTool.tool);
}
},
_toolbar: function() {
var that = this,
wrapper = that.wrapper,
toolbar = that.options.toolbar,
container, items;
if (toolbar) {
that._createClickHandler = that._addClickHandler = that._clickAdd.bind(that);
that._editClickHandler = that._editToolbarClick.bind(that);
that._destroyClickHandler = that._removeToolbarClick.bind(that);
that._editCancelClickHandler = that._editCancelClick.bind(that);
that._updateClickHandler = that._editUpdateClick.bind(that);
that._cancelClickHandler = that._clickCancel.bind(that);
that._saveClickHandler = that._clickSave.bind(that);
that._excelClickHandler = that._clickExcel.bind(that);
that._pdfClickHandler = that._clickPdf.bind(that);
that._serachHandler = that._searchInput.bind(that);
container = that.wrapper.find(".k-grid-toolbar");
if (!container.length) {
container = $('<div class="k-grid-toolbar k-toolbar" />')
.prependTo(wrapper);
if (typeof toolbar === STRING || isFunction(toolbar)) {
if (typeof toolbar === STRING) {
toolbar = kendo.template(toolbar).bind(that);
}
container.html(toolbar({ grid: that }));
that._attachToolbarClicks();
} else if (isArray(toolbar)) {
items = that._processItems(toolbar);
container.kendoToolBar({
navigateOnTab: !that.options.navigatable,
size: that.options.size,
items: items
});
} else if (isPlainObject(toolbar)) {
container.kendoToolBar({
navigateOnTab: !that.options.navigatable,
size: that.options.size,
items: that._processItems(toolbar.items || []),
overflow: toolbar.overflow
});
}
} else {
that._attachToolbarClicks();
}
container.on(INPUT + NS, ".k-grid-search input", this._serachHandler);
if (toolbar.overflow && toolbar.overflow.mode === "section") {
const toolbarElement = container.data("kendoToolBar");
toolbarElement.bind("overflowOpen", function() {
const itemsToCheck = toolbarElement.overflowSection.element.find(".k-toolbar-items-list");
that._toggleToolbarEditingItemsVisibility(itemsToCheck?.children());
});
}
that._toggleToolbarEditingItemsVisibility();
}
},
_toggleToolbarEditingItemsVisibility: function(itemsToCheck) {
const that = this;
const dataSource = that.dataSource;
const hasChanges = dataSource.hasChanges();
const toolbar = that.wrapper.find(".k-grid-toolbar");
if (!toolbar.length) {
return;
}
let toolbarItems;
if (that.options.toolbar && that.options.toolbar.overflow && that.options.toolbar.overflow.mode === "scroll") {
toolbarItems = toolbar.find(".k-toolbar-items").children();
} else if (itemsToCheck) {
toolbarItems = itemsToCheck;
} else {
toolbarItems = toolbar.children();
}
const showInactive = (that.options.toolbar && that.options.toolbar.showInactiveTools) || false;
const mode = that._editMode();
const editContainerVisible = that._editContainer && that._editContainer.length > 0 && that._editContainer.is(":visible");
const method = showInactive ? (element) => {
element.attr("aria-disabled", true);
element.addClass("k-disabled");
} : (element) => element.hide();
const selected = that.select();
const hasSelected = selected.length > 0;
const differentSelectionThanEditing =
hasSelected
&& that._editContainer
&& that._editContainer.length > 0
&& that._editContainer.is(":visible")
&& (that._editContainer[0].getAttribute(kendo.attr("uid")) !== selected[selected.length - 1].getAttribute(kendo.attr("uid")));
const regex = getToolbarRegex({
mode,
hasSelected,
hasChanges,
editContainerVisible,
differentSelectionThanEditing: !differentSelectionThanEditing && differentSelectionThanEditing !== false ? true : differentSelectionThanEditing,
_editableIsClosing: that._editableIsClosing || false,
_isEditableEnabled: that._isEditableEnabled || false,
options: that.options
});
toolbarItems.show().removeClass("k-disabled").attr("aria-disabled", "false");
toolbarItems.each(function() {
const element = $(this);
const identifier = element.attr("class");
if (element.hasClass(FOCUSED)) {
element.removeClass(FOCUSED);
focusTable(that.table);
}
if (identifier && regex && regex.test(identifier)) {
method(element);
}
});
},
_attachToolbarClicks: function() {
var editable = this.options.editable,
container = this.wrapper.find(".k-grid-toolbar");
if (editable && editable.create !== false) {
container.on(CLICK + NS, ".k-grid-add", this._createClickHandler)
.on(CLICK + NS, ".k-grid-cancel-changes", this._cancelClickHandler)
.on(CLICK + NS, ".k-grid-save-changes", this._saveClickHandler);
}
if (editable && editable.update !== false) {
container.on(CLICK + NS, ".k-grid-edit-command", this._editClickHandler)
.on(CLICK + NS, ".k-grid-save-command", this._updateClickHandler)
.on(CLICK + NS, ".k-grid-cancel-command", this._editCancelClickHandler);
}
if (editable.destroy !== false) {
container.on(CLICK + NS, ".k-grid-remove-command", this._destroyClickHandler);
}
container.on(CLICK + NS, ".k-grid-excel", this._excelClickHandler);
container.on(CLICK + NS, ".k-grid-pdf", this._pdfClickHandler);
},
_processItems: function(tools) {
var that = this,
options = that.options,
items = [],
messages = this.options.messages.commands,
itemsCollectionHasSpacer = false;
tools.map(t => {
var command, searchText, icon, className, inputSize, template = "";
if (typeof t === 'string') {
command = t.toLowerCase();
t = {};
t.text = messages[command] || command;
} else {
command = (t.name || t.text || "");
let isPredefinedTool = defaultCommands[command.toLowerCase()];
if (isPredefinedTool) {
command = command.toLowerCase();
}
t.text = t.text === "" ? "" : (t.text || messages[command] || command);
}
if (!itemsCollectionHasSpacer && (command === "search" || command === "columns")) {
itemsCollectionHasSpacer = true;
items.push({
type: "spacer"
});
}
if (command === "search") {
searchText = htmlEncode(t.text || messages.search, true);
icon = t.icon || t.iconClass || "search";
inputSize = kendo.getValidCssClass("k-input-", "size", that.options.size);
template += `<span class='k-searchbox k-input ${inputSize} k-rounded-md k-input-solid k-grid-search'>`;
template += kendo.ui.icon({ icon: icon, iconClass: "k-input-icon" });
template += "<input autocomplete='off' placeholder='" + searchText + "' title='" + searchText + "' aria-label='" + searchText + "' class='k-input-inner' />";
template += "</span>";
items.push({
name: "search",
overflow: "never",
template: template
});
} else if (command === "paste" && options.allowPaste) {
items.push({
template: "<input class='k-grid-paste-action' />"
});
} else {
if (!command && !(isPlainObject(t) && t.template)) {
throw new Error("Custom commands should have name specified");
}
t = extend({ type: "button" }, defaultCommands[command], t);
className = t.className || "k-grid-" + (command || "").replace(/\s/g, "");
t.spriteCssClass = t.icon ? null : t.iconClass;
t.attributes = that._processAttr(t.attr);
delete t.attr;
if (!!className) {
if (t.attributes["class"] === undefined$1) {
t.attributes["class"] = "";
}
t.attributes["class"] += (" " + className);
}
if (t.template) {
delete t.type;
}
if (!!that["_" + command + "ClickHandler"]) {
t.click = that["_" + command + "ClickHandler"];
}
if (command === "canceledit") {
t.click = that._editCancelClickHandler;
}
items.push(t);
}
});
return items;
},
_processAttr: function(attr) {
var attributes = {},
attrArray;
if (typeof attr === STRING && attr.length > 0) {
attrArray = attr.split(" ");
attrArray.map(a => {
var keyValue = a.split("=");
if (keyValue.length === 2) {
attributes[keyValue[0]] = keyValue[1].replaceAll('"', "").replaceAll("'", "");
}
});
} else if (isPlainObject(attr)) {
attributes = attr;
}
return attributes;
},
_createButton: function(command) {
var button,
template = command.template || COMMANDBUTTONTMPL,
commandName = typeof command === STRING ? command : command.name || command.text,
className = defaultCommands[commandName] ? defaultCommands[commandName].className : "k-grid-" + (commandName || "").replace(/\s/g, ""),
options = { className: command.skipCommandClass ? "" : className, text: commandName, attr: command.skipTabIndex ? "" : "tabindex=-1", iconClass: "", size: command.size || this.options.size },
messages = this.options.messages.commands,
attributeClassMatch;
if (!commandName && !(isPlainObject(command) && command.template)) {
throw new Error("Custom commands should have name specified");
}
if (isPlainObject(command)) {
command = extend(true, {}, command);
if (command.className && inArray(options.className, command.className.split(" ")) < 0) {
command.className += " " + options.className;
} else if (command.className === undefined$1) {
command.className = options.className;
}
if (command.className.indexOf("k-primary") > -1) {
command.className = command.className.replace("k-primary", "");
command.themeColor = "primary";
}
if (commandName === "edit") {
command = extend(true, {}, command);
command.text = isPlainObject(command.text) ? command.text.edit : command.text;
command.iconClass = isPlainObject(command.iconClass) ? command.iconClass.edit : command.iconClass;
}
if (command.attr) {
if (isPlainObject(command.attr)) {
command.attr = stringifyAttributes(command.attr);
}
if (command.attr instanceof Function) {
let compiledAttributes = command.attr(command);
command.attr = stringifyAttributes(compiledAttributes);
}
if (typeof command.attr === STRING) {
attributeClassMatch = command.attr.match(/class="(.+?)"/);
if (attributeClassMatch && inArray(attributeClassMatch[1], command.className.split(" ")) < 0) {
command.className += " " + attributeClassMatch[1];
}
}
}
const additionalOptions = { text: messages[commandName] };
if (commandName === "edit" || commandName === "update") {
additionalOptions.themeColor = "primary";
}
if (commandName === "destroy") {
additionalOptions.iconClass = "k-i-x";
}
options = extend(true, options, defaultCommands[commandName], additionalOptions, command);
} else {
const additionalOptions = { text: messages[commandName] };
if (commandName === "edit" || commandName === "update") {
additionalOptions.themeColor = "primary";
}
if (commandName === "destroy") {
additionalOptions.iconClass = "k-i-x";
}
options = extend(true, options, defaultCommands[commandName], additionalOptions);
}
button = kendo.template(template)(options);
if (!command.template) {
return kendo.html.renderButton($(button), options);
} else {
return button;
}
},
_hasFooters: function() {
return !!this.footerTemplate ||
!!this.groupFooterTemplate ||
(this.footer && this.footer.length > 0) ||
this.wrapper.find(".k-grid-footer").length > 0;
},
_groupable: function() {
var that = this;
if (that._groupableClickHandler) {
that.table.add(that.lockedTable).off(CLICK + NS, that._groupableClickHandler);
} else {
that._groupableClickHandler = function(e) {
var element = $(this),
groupRow = element.closest(TR);
var group = that._groupRows ? that._groupRows[that.wrapper.find(DOT + GROUPING_ROW).index(groupRow)] : {};
if (element.is(CARET_ALT_DOWN)) {
if (!that.trigger("groupCollapse", { group: group, element: groupRow })) {
that.collapseGroup(groupRow);
}
} else {
if (!that.trigger("groupExpand", { group: group, element: groupRow })) {
that.expandGroup(groupRow);
}
}
e.preventDefault();
e.stopPropagation();
};
}
if (that._isLocked()) {
that.lockedTable.on(CLICK + NS, ".k-grouping-row " + CARET_ALT_RIGHT + ", .k-grouping-row " + CARET_ALT_DOWN, that._groupableClickHandler);
} else {
that.table.on(CLICK + NS, ".k-grouping-row " + CARET_ALT_RIGHT + ", .k-grouping-row " + CARET_ALT_DOWN, that._groupableClickHandler);
}
that._attachGroupable();
},
_attachGroupable: function() {
var that = this,
wrapper = that.wrapper,
groupable = that.options.groupable,
draggables = HEADERCELLS + "[" + kendo.attr("field") + "]",
filter = that.content ? ".k-grid-header:first " + draggables : "table:first>.k-grid-header " + draggables;
if (groupable && groupable.enabled !== false) {
if (!wrapper.has("div.k-grouping-header")[0]) {
$("<div/>").addClass("k-grouping-header").prependTo(wrapper);
}
if (that.groupable) {
that._destroyGroupable();
}
if (browser.chrome) {
wrapper.find("div.k-grouping-header").css("touch-action", NONE);
wrapper.find(filter).css("touch-action", NONE);
}
let header = that.wrapper.children(".k-grid-header");
header.addClass("k-grid-draggable-header");
header.attr("draggable", true);
that.groupable = new ui.Groupable(wrapper, extend({}, groupable, {
draggable: that._draggableInstance,
groupContainer: ">div.k-grouping-header",
dataSource: that.dataSource,
draggableElements: filter,
filter: filter,
size: that.options.size,
allowDrag: that.options.reorderable,
enableContextMenu: !!that.options.contextMenu,
removeGroup: function(e) {
that._showUngroupedColumn(e);
},
change: function(e) {
if (that.trigger("group", { groups: e.groups })) {
e.preventDefault();
} else {
that._clearEditableState();
that._hideGroupedColumns(e.groups);
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
}
}));
that._addGroupableOptionsToHeader();
}
},
_showUngroupedColumn: function(group) {
var columns = leafColumns(this.columns);
var i;
for (i = 0; i < columns.length; i++) {
if (columns[i].uid == group.colID && columns[i].hideOnGroup) {
this.showColumn(columns[i]);
}
}
},
_hideGroupedColumns: function(groups) {
if (!groups) {
return;
}
var columns = leafColumns(this.columns);
var fields = [];
var i;
for (i = 0; i < groups.length; i++) {
if (groups[i].colID) {
fields.push(groups[i].colID);
}
}
for (i = 0; i < columns.length; i++) {
if (fields.indexOf(columns[i].uid) >= 0 && columns[i].hideOnGroup) {
this.hideColumn(columns[i]);
}
}
},
_resetEndless: function() {
var that = this;
that.dataSource.options.endless = null;
that._endlessPageSize = that.dataSource.options.pageSize;
that.dataSource._skip = 0;
that.dataSource._pageSize = that.dataSource._take = that._endlessPageSize;
that.dataSource._page = 1;
},
_addGroupableOptionsToHeader: function() {
var that = this;
var columns = flatColumns(that.columns);
var columnFieldMap = {};
var headerCells = that._headerCells();
var cellFieldAttr = "";
var headerCell;
var columnOptions;
var i;
for (i = 0; i < columns.length; i++) {
columns[i].field;
columnFieldMap[columns[i].field] = columns[i];
}
for (i = 0; i < headerCells.length; i++) {
headerCell = headerCells.eq(i);
cellFieldAttr = headerCell.attr(kendo.attr(FIELD));
columnOptions = columnFieldMap[cellFieldAttr];
if (columnOptions && columnOptions.groupable && columnOptions.groupable.sort) {
headerCell.data(GROUP_SORT, columnOptions.groupable.sort);
}
}
},
_destroyGroupable: function() {
var that = this;
if (that.groupable && that.groupable.element) {
that.groupable.element.kendoGroupable("destroy");
}
that.groupable = null;
that._removeGroupableOptionsFromHeader();
},
_removeGroupableOptionsFromHeader: function() {
var that = this;
var headerCells = that._headerCells();
for (var i = 0; i < headerCells.length; i++) {
headerCells.eq(i).removeData(GROUP_SORT);
}
},
_continuousItems: function(filter, cell) {
if (!this.lockedContent) {
return;
}
var that = this;
var elements = that.table.add(that.lockedTable);
var lockedItems = $(filter, elements[0]);
var nonLockedItems = $(filter, elements[1]);
var columns = cell ? lockedColumns(leafColumns(that.columns)).length : 1;
var nonLockedColumns = cell ? leafColumns(that.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, [].splice.call(nonLockedItems, 0, nonLockedColumns));
}
return result;
},
_selectable: function() {
var that = this,
multi,
cell,
notString = [],
isLocked = that._isLocked(),
selectable = that.options.selectable,
hasSkeletonLoader = that.options.loaderType === "skeleton";
if (selectable && !selectable.checkboxSelection) {
if (that.selectable) {
that.selectable.destroy();
}
that._selectedIds = {};
selectable = kendo.ui.Selectable.parseOptions(selectable);
multi = selectable.multiple;
cell = selectable.cell;
if (that._hasDetails()) {
notString[notString.length] = ".k-detail-row";
}
if (that.options.groupable || that._hasFooters() || that._groups()) {
notString[notString.length] = ".k-grouping-row,.k-group-footer";
}
if (hasSkeletonLoader) {
notString[notString.length] = "[data-skeleton-row]";
}
notString = notString.join(",");
if (notString !== "") {
notString = ":not(" + notString + ")";
}
var elements = that.table;
if (isLocked) {
elements = elements.add(that.lockedTable);
}
var filter = ">" + (cell ? SELECTION_CELL_SELECTOR : "tbody>tr" + notString);
that.selectable = new kendo.ui.Selectable(elements, {
allowPaste: that.options.allowPaste,
filter: filter,
aria: true,
multiple: multi,
holdToDrag: !!(that._isMobile || kendo.support.mobileOS),
toggleable: !!(that._isMobile || kendo.support.mobileOS),
dragToSelect: that.options.selectable && that.options.selectable.dragToSelect,
changing: function(e) {
if (that.trigger(CHANGING, { target: e.target, originalEvent: e.originalEvent })) {
e.preventDefault();
}
},
change: function(e) {
var selectedValues;
if (!cell) {
that._persistSelectedRows();
}
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);
}
}
that._calculateAggregatesForSelected();
if (that._editMode() !== "incell") {
that._toggleToolbarEditingItemsVisibility();
}
if (e.event) {
that.trigger(CHANGE, { cellAggregates: that._cellAggregates });
}
},
useAllItems: isLocked && multi && cell,
relatedTarget: function(items) {
if (cell || !isLocked) {
return;
}
var related;
var result = $();
for (var idx = 0, length = items.length; idx < length; idx++) {
related = that._relatedRow(items[idx]);
if (inArray(related[0], items) < 0) {
result = result.add(related);
}
}
return result;
},
continuousItems: function() {
return that._continuousItems(filter, cell);
},
ignoreOverlapped: that.options.selectable && that.options.selectable.ignoreOverlapped,
addIdToRanges: true
});
if (that.options.navigatable) {
elements.on("keydown" + NS, function(e) {
var current = that.current();
var target = e.target;
var eventObject = { event: e };
var triggerChange;
var triggerChanging;
var lastSelection;
if (!current) {
return;
}
if (e.keyCode === keys.SPACEBAR && !e.shiftKey && $.inArray(target, elements) > -1 &&
!current.is(".k-edit-cell,.k-header") &&
current.parent().is(":not(.k-grouping-row,.k-detail-row,.k-group-footer)")) {
e.preventDefault();
e.stopPropagation();
current = cell ? current : current.parent();
triggerChange = !current.hasClass(SELECTED) || that.selectable.value().length > 1;
triggerChanging = triggerChange || (multi && current.hasClass(SELECTED) && e.ctrlKey);
if (triggerChanging && that.trigger(CHANGING, { target: current, originalEvent: e })) {
return;
}
if (isLocked && !cell) {
current = current.add(that._relatedRow(current));
}
if (multi) {
if (!e.ctrlKey) {
that.selectable.clear();
} else {
if (current.hasClass(SELECTED)) {
that._deselectCheckRows(current);
that._calculateAggregatesForSelected();
that.trigger(CHANGE, { cellAggregates: that._cellAggregates });
return;
}
}
} else {
that.selectable.clear();
}
if (!cell) {
that.selectable._lastActive = current;
}
that.selectable.value(current);
if (triggerChange) {
that._calculateAggregatesForSelected();
that.trigger(CHANGE, { cellAggregates: that._cellAggregates });
}
} else if (!cell &&
($(target).is("td") || ($(target).is("table") && inArray(target, this._navigatableTables))) &&
((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 (that.trigger(CHANGING, { target: current, originalEvent: e })) {
return;
}
lastSelection = that.selectable.value();
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);
if (!compareElements(lastSelection, that.selectable.value())) {
that.trigger(CHANGE, eventObject);
}
} else if (!current.hasClass(SELECTED)) {
that.selectable.clear();
that.selectable.value(current);
that._calculateAggregatesForSelected();
that.trigger(CHANGE, { cellAggregates: that._cellAggregates });
}
}
});
}
}
},
_pasteReplaceHandler: function(plain) {
var that = this,
rows,
current,
currentRow,
currentRowUid,
currentField,
uids = [];
current = that.select().first();
if (!current.length) {
return;
}
if (current.is(TR)) {
current = current.children(TD).first();
}
rows = plain.split("\n").filter(f => f);
currentRow = current.closest("tr");
currentField = that.thead.find("th:eq(" + current.index() + ")").data("field");
currentRowUid = currentRow.data("uid");
uids.push(currentRowUid);
currentRow.nextAll(ITEMROW).slice(0, rows.length - 1).each((i, item) => {
uids.push($(item).data("uid"));
});
that._executePaste(rows, uids, null, currentField);
},
_pasteInsertHandler: function(plain) {
var that = this,
dataSource = that.dataSource,
rows,
current,
currentRow,
dataItemIndex,
dataItem;
current = that.select().first();
if (!current.length) {
return;
}
if (current.is(TR)) {
current = current.children(TD).first();
}
rows = plain.split("\n").filter(f => f);
currentRow = current.closest("tr");
dataItem = that.dataItem(currentRow);
dataItemIndex = dataSource.indexOf(dataItem) + 1;
that._executePaste(rows, null, dataItemIndex, null);
},
_executePaste: function(rows, uids, index, currentField) {
var that = this,
dataSource = that.dataSource,
update = uids || false,
dataItem,
row,
cells,
cell,
column,
field,
selectedUids = that._getSelectedRowUids(),
selectedColumnFields = that._getSelectedColumnFields(),
changedItems = [],
visibleColumns = visibleLeafColumns(that.columns).filter(col => !col.selectable && !col.draggable & !col.command),
startingIndex = currentField && visibleColumns.map(c => c.field).indexOf(currentField);
// If only one value is copied and multiple cells are selected, replace all values in all selected cells with the copied value.
if (rows.length === 1 && rows[0].split("\t").length === 1 && update) {
for (let j = 0; j < selectedUids.length; j++) {
const uid = selectedUids[j];
dataItem = dataSource.getByUid(uid);
cell = rows[0].split("\t")[0];
for (let j = 0; j < selectedColumnFields.length; j++) {
field = selectedColumnFields[j];
if (dataItem && cell) {
dataItem.set(field, cell);
}
}
if (dataItem && dataItem.dirty) {
changedItems.push(dataItem);
}
}
} else {
// If more than one value is copied, proceed with the standard replace.
for (let i = 0; i < rows.length; i++) {
row = rows[i];
cells = row.split("\t");
dataItem = update ? dataSource.getByUid(uids[i]) : dataSource.insert(index + i, {});
for (let j = 0; j < cells.length; j++) {
cell = cells[j].replace(/\r/, "");
column = visibleColumns[j + startingIndex || 0];
if (column && dataItem && cell) {
field = column.field;
dataItem.set(field, cell);
}
}
if (dataItem && dataItem.dirty) {
changedItems.push(dataItem);
}
}
}
that.trigger(PASTE, { items: changedItems, type: update ? "replace" : "insert" });
},
_pasteKeyboardHandler: function(e) {
var that = this,
current = that.current(),
clipBoardData = e.originalEvent.clipboardData,
operation = (that.pasteActionsDropDownList && that.pasteActionsDropDownList.value()) || "insert",
rowUid,
cellIndex,
plain;
if ($(e.target).is(".k-edit-cell input:visible")) {
return;
}
if (clipBoardData) {
e.preventDefault();
plain = clipBoardData.getData("text").trimEnd();
// If the copied value consists only of white spaces or new lines, reduce it to a single white space.
if (isEmptyString(plain)) {
plain = " ";
}
if (current && current.length) {
cellIndex = current.index();
rowUid = current.closest(TR).data("uid");
}
if (operation === "replace") {
that._pasteReplaceHandler(plain);
}
if (operation === "insert") {
that._pasteInsertHandler(plain);
}
// Restore the focus to the last focused cell.
if (cellIndex && rowUid) {
that._currentRowIndex = that.wrapper.find(TR + "[data-uid='" + rowUid + "']").index();
that._restoreCurrent(cellIndex);
}
}
},
_paste: function() {
var that = this,
options = that.options,
selectable = options.selectable,
allowPaste = options.allowPaste;
if (allowPaste && selectable) {
that.pasteHandler = that._pasteKeyboardHandler.bind(that);
const container = that.content || that.table;
container.on(PASTE + NS, that.pasteHandler);
if (that.options.toolbar) {
that._pasteToolbarDropDown();
}
}
},
_clipboard: function() {
var options = this.options;
var selectable = options.selectable;
if (selectable && options.allowCopy) {
var grid = this;
if (!options.navigatable) {
grid.table.attr(TABINDEX, 0);
grid.table.add(grid.lockedTable)
.on(MOUSEDOWN + NS + " keydown" + NS, ".k-detail-cell", function(e) {
if (e.target !== e.currentTarget) {
e.stopImmediatePropagation();
}
})
.on(MOUSEDOWN + NS, NAVROW + ">" + NAVCELL, tableClick.bind(grid));
}
grid.copyHandler = grid.copySelection.bind(grid);
grid.updateClipBoardState = function() {
if (grid.areaClipBoard) {
grid.areaClipBoard.val(grid.getTSV()).trigger("focus").select();
}
};
const container = grid.content || grid.table;
grid.bind("change", grid.updateClipBoardState);
container.on("keydown", grid.copyHandler);
grid.clearAreaHandler = grid.clearArea.bind(grid);
container.on("keyup", grid.clearAreaHandler);
}
},
copySelectionToClipboard: function(includeHeaders) {
this._createAreaClipBoard();
this.areaClipBoard.val(this.getTSV(includeHeaders)).trigger("focus").select();
document.execCommand('copy');
},
copySelection: function(e) {
if ((e instanceof jQuery.Event && !(e.ctrlKey || e.metaKey)) ||
!(e.keyCode === 67 && (e.ctrlKey || e.metaKey)) ||
$(e.target).is("input:visible,textarea:visible") ||
(window.getSelection && window.getSelection().toString()) ||
(document.selection && document.selection.createRange().text)) {
return;
}
this._createAreaClipBoard();
this.areaClipBoard.val(this.getTSV()).trigger("focus").select();
},
_createAreaClipBoard: function() {
if (!this.areaClipBoard) {
this.areaClipBoard =
$("<textarea />")
.css({
position: "fixed",
top: "50%",
left: "50%",
opacity: 0,
width: 0,
height: 0
})
.appendTo(this.wrapper);
}
},
getTSV: function(includeHeaders) {
var grid = this;
var selected = grid.select();
var delimeter = "\t";
var allowCopy = grid.options.allowCopy;
var hasLockedCols = grid._isLocked() && lockedColumns(grid.columns).length;
if ($.isPlainObject(allowCopy) && allowCopy.delimeter) {
delimeter = allowCopy.delimeter;
}
var text = "";
if (selected.length) {
if (selected.eq(0).is(TR)) {
selected = selected.find("td:not(.k-group-cell)");
}
{
selected.filter(":visible");
}
var result = [];
var cellsOffset = this.columns.length;
var lockedCols = grid._isLocked() && lockedColumns(grid.columns).length;
var inLockedArea = true;
var fields = [];
var field;
var columns = visibleLeafColumns(this.columns);
$.each(selected, function(idx, cell) {
cell = $(cell);
field = grid._getCellField(cell, hasLockedCols);
if (columns.findIndex(c => c.field === field) === -1) {
return;
}
var tr = cell.closest(TR);
var rowIndex = tr.index();
var cellIndex = cell.index();
{
cellIndex -= cell.prevAll(":hidden").length;
}
if (lockedCols && inLockedArea) {
inLockedArea = $.contains(grid.lockedTable[0], cell[0]);
}
if (grid._groups() && inLockedArea) {
cellIndex -= grid._groups();
}
cellIndex = inLockedArea ? cellIndex : (cellIndex + lockedCols);
if (field) {
fields[cellIndex] = field;
}
if (cellsOffset > cellIndex) {
cellsOffset = cellIndex;
}
var cellText = cell.text();
if (!result[rowIndex]) {
result[rowIndex] = [];
}
result[rowIndex][cellIndex] = cellText;
});
var rowsOffset = result.length;
result = $.each(result, function(idx, val) {
if (val) {
result[idx] = val.slice(cellsOffset);
if (rowsOffset > idx) {
rowsOffset = idx;
}
}
});
if (includeHeaders && fields.length) {
result.splice(rowsOffset, 0, fields.map(function(field) {
return getTitle(field, columns);
}));
var headerIndex = result.findIndex(function(el) {
return el !== undefined$1;
});
result[headerIndex] = result[headerIndex].slice(cellsOffset);
}
$.each(result.slice(rowsOffset), function(idx, val) {
if (val) {
text += val.join(delimeter) + "\r\n";
} else {
text += "\r\n";
}
});
}
return text;
},
clearArea: function(e) {
if (this.areaClipBoard && e && e.target === this.areaClipBoard[0]) {
focusTable(this.table, true);
}
if (this.areaClipBoard) {
this.areaClipBoard.remove();
this.areaClipBoard = null;
}
},
_adaptiveColumns: function() {
var that = this;
if (that._anyColumnHasMediaQuery()) {
that._setColumnsMediaVisibility(that.columns);
that._attachColumnMediaResizeHandler();
}
},
_anyColumnHasMediaQuery: function() {
return this._columnsWithMediaQuery().length;
},
_columnsWithMediaQuery: function() {
return columnsWithMedia(this.columns);
},
_attachColumnMediaResizeHandler: function() {
var that = this;
that._detachColumnMediaResizeHandler();
that._columnMediaResizeHandler = that._onColumnMediaResize.bind(that);
$(window).on(RESIZE + NS, that._columnMediaResizeHandler);
},
_detachColumnMediaResizeHandler: function() {
var that = this;
if (that._columnMediaResizeHandler) {
$(window).off(RESIZE + NS, that._columnMediaResizeHandler);
}
},
_onColumnMediaResize: function() {
var that = this;
that._setColumnsMediaVisibility(that.columns);
that._setContentMediaWidth();
},
_setColumnsMediaVisibility: function(columns) {
var cols = columns || [];
for (var i = 0; i < cols.length; i++) {
this._setColumnMediaVisibility(cols[i]);
}
},
_setColumnMediaVisibility: function(column) {
var that = this;
if (isUndefined(column.media)) {
that._setColumnsMediaVisibility(column.columns);
} else {
if (columnMatchesMedia(column)) {
that._showColumnByMedia(column);
if (!column.hidden) {
that._setColumnsMediaVisibility(column.columns);
}
} else {
that._hideColumnByMedia(column);
}
}
},
_showColumnByMedia: function(column) {
if (!column.hidden) {
// "hidden" has a priority over "matchesMedia"
this.showColumn(column);
}
setColumnMatchesMedia(column);
},
_hideColumnByMedia: function(column) {
var initiallyHidden = column.hidden;
if (!initiallyHidden) {
column._hideByMedia = true;
this.hideColumn(column);
column._hideByMedia = false;
// hiding is tracked in "matchesMedia" instead of "hidden" flag
column.hidden = initiallyHidden;
}
setColumnMatchesMedia(column);
},
_setContentMediaWidth: function() {
var that = this;
var options = that.options;
var isLocked = that._isLocked();
var footer;
if (options.scrollable && (options.resizable === true || (options.resizable && options.resizable.columns === true))) {
if (isLocked && that.lockedFooter) {
footer = that.lockedFooter.children("table");
} else if (that.footer) {
footer = that.footer.find(">.k-grid-footer-wrap>table");
}
if (!footer || !footer[0]) {
footer = $();
}
var header = isLocked ? that.wrapper.find(".k-grid-header-locked").find("table") : that.wrapper.find(".k-grid-header").find("table");
var contentTable = isLocked ? that.lockedTable : that.table;
var headerColumns = header.find("th");
var headerColgroup = header.find("colgroup");
var headerColumnsCount = headerColumns.length;
var visibleHeaderColumnsCount = headerColumns.filter(isCellVisible).length;
var hiddenHeaderColumnsCount = headerColumns.length - visibleHeaderColumnsCount;
var totalHeaderWidth = 0;
if (header[0].style.width !== "" && parseFloat(header[0].style.width) !== totalHeaderWidth) {
var currentHeaderWidth = header.css(WIDTH);
for (var i = 0; i < headerColumnsCount; i++) {
if (isElementVisible(headerColumns[i])) {
var columnWidth;
var cellIndex = Math.max(i, (i - hiddenHeaderColumnsCount));
var colgroupChild = headerColgroup.children()[cellIndex];
var columnStyleWidth = colgroupChild ? colgroupChild.style.width : "";
if (columnStyleWidth !== "") {
columnWidth = parseFloat(columnStyleWidth);
} else {
// remove the header width to calculate the height of a column without fixed width
header.css(WIDTH, AUTO);
columnWidth = outerWidth(headerColumns.eq(i));
header.css(WIDTH, currentHeaderWidth);
}
totalHeaderWidth += columnWidth;
}
}
contentTable.css('width', totalHeaderWidth - 1); // subtract 1 to remove the horizontal scroll
header.css('width', totalHeaderWidth);
footer.css('width', totalHeaderWidth);
that._updateStickyColumns();
}
}
},
_minScreenSupport: function() {
var any = this.hideMinScreenCols();
if (any) {
this.minScreenResizeHandler = this.hideMinScreenCols.bind(this);
$(window).on("resize", this.minScreenResizeHandler);
}
},
hideMinScreenCols: function() {
var cols = this.columns,
screenWidth = (window.innerWidth > 0) ? window.innerWidth : screen.width;
return this._iterateMinScreenCols(cols, screenWidth);
},
_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;
},
_stickyColumns: function() {
var that = this;
if (that._anyStickyColumns()) {
that._setStickyColumns(false);
}
},
_updateStickyColumns: function() {
var that = this;
var groupHeaderColumnTemplateColumns = grep(leafColumns(that.columns), function(column) { return column.groupHeaderColumnTemplate; });
if (that._anyStickyColumns()) {
that._setStickyColumns(true);
that._templates();
if (groupHeaderColumnTemplateColumns.length > 0) {
that._renderGroupRows();
}
if (that._hasFilterRow()) {
that._updateStickyFilterCells();
}
}
},
_updateStickyFilterCells: function() {
var that = this;
var filterCells = that.thead.find(".k-filter-row").find("td:not(.k-group-cell,.k-hierarchy-cell)");
if (filterCells.length) {
filterCells.each(function() {
var th = $(this);
var column = th.data("column");
if (column.sticky) {
if (isPlainObject(column.stickyStyle)) {
th.css({
left: column.stickyStyle.left || "",
right: column.stickyStyle.right || ""
});
}
th.addClass(STICKY_HEADER_CLASS);
} else {
th.css({
left: "",
right: ""
});
th.removeClass(STICKY_HEADER_CLASS);
}
});
}
},
_anyStickyColumns: function() {
var that = this;
return stickyColumns(that.columns).length;
},
_setStickyColumns: function(updateStyles) {
var that = this;
var columns = stickyColumns(that.columns);
var visibleColumns = visibleStickyColumns(that.columns);
var stickyWidths = that._calculateStickyWidths(visibleColumns);
that._removeStickyAttributes(columns);
that._setStickyClassAttributes(columns);
that._setStickyStyleAttributes(visibleColumns, stickyWidths, updateStyles);
if (updateStyles) {
that._setStickyStyles(visibleColumns, stickyWidths);
}
},
_calculateStickyWidths: function(columns, initialLeftWidth, initialRightWidth) {
var that = this;
var i;
var column;
var columnWidth;
var nextColumnLeft;
var nextColumnRight;
var left = isRtl ? "right" : "left";
var right = isRtl ? "left" : "right";
var stickyWidths = {
left: new Array(columns.length).fill(initialLeftWidth ? initialLeftWidth : 0),
right: new Array(columns.length).fill(initialRightWidth ? initialRightWidth : 0)
};
for (i = 0; i < columns.length - 1; i++) {
column = columns[i];
columnWidth = that._sumColumnWidth(column);
nextColumnLeft = columnWidth + stickyWidths[left][i];
stickyWidths[left][i + 1] = nextColumnLeft;
}
for (i = columns.length - 1; i > 0; i--) {
column = columns[i];
columnWidth = that._sumColumnWidth(column);
nextColumnRight = columnWidth + stickyWidths[right][i];
stickyWidths[right][i - 1] = nextColumnRight;
}
return stickyWidths;
},
_setStickyClassAttributes: function(columns, masterIndex) {
var that = this;
var i;
var column;
for (i = 0; i < columns.length; i++) {
column = columns[i];
if (column.columns) {
if (!masterIndex && i) {
masterIndex = i;
}
that._setStickyClassAttributes(childColumns([column]), masterIndex);
}
if (masterIndex) {
addColumnAttribute(column, "headerAttributes", "class", STICKY_HEADER_NO_BORDER_CLASS);
}
addColumnAttribute(column, "attributes", "class", STICKY_CELL_CLASS);
addColumnAttribute(column, "headerAttributes", "class", STICKY_HEADER_CLASS);
addColumnAttribute(column, "footerAttributes", "class", STICKY_FOOTER_CLASS);
}
},
_setStickyStyleAttributes: function(columns, stickyWidths, updateStyles) {
var that = this;
var i;
var column;
var stickyLeft;
var stickyRight;
var stickyStyle;
var childCols;
var childStickyWidths;
for (i = 0; i < columns.length; i++) {
column = columns[i];
stickyLeft = stickyWidths.left[i];
stickyRight = stickyWidths.right[i];
stickyStyle = { left: stickyLeft + "px", right: stickyRight + "px" };
if (column.columns) {
childCols = visibleChildColumns([column]);
childStickyWidths = that._calculateStickyWidths(childCols, stickyLeft, stickyRight);
that._setStickyStyleAttributes(childCols, childStickyWidths, updateStyles);
if (updateStyles) {
that._setStickyStyles(childCols, childStickyWidths);
}
}
addColumnAttribute(column, "attributes", kendo.attr("style-left"), stickyStyle.left);
addColumnAttribute(column, "attributes", kendo.attr("style-right"), stickyStyle.right);
addColumnAttribute(column, "headerAttributes", kendo.attr("style-left"), stickyStyle.left);
addColumnAttribute(column, "headerAttributes", kendo.attr("style-right"), stickyStyle.right);
addColumnAttribute(column, "footerAttributes", kendo.attr("style-left"), stickyStyle.left);
addColumnAttribute(column, "footerAttributes", kendo.attr("style-right"), stickyStyle.right);
column.stickyStyle = stickyStyle;
}
},
_removeStickyAttributes: function(columns) {
var that = this;
var i;
var cellClassRegExp = new RegExp("(\\s*" + STICKY_CELL_CLASS + ")*", "ig");
var headerClassRegExp = new RegExp("(\\s*" + STICKY_HEADER_CLASS + ")*", "ig");
var footerClassRegExp = new RegExp("(\\s*" + STICKY_FOOTER_CLASS + ")*", "ig");
var headerClassNoBorderRegExp = new RegExp("(\\s*" + STICKY_HEADER_NO_BORDER_CLASS + ")*", "ig");
var column;
for (i = 0; i < columns.length; i++) {
column = columns[i];
if (column.columns) {
that._removeStickyAttributes(childColumns([column]));
}
removeColumnAttribute(column, "attributes", "class", cellClassRegExp);
removeColumnAttribute(column, "attributes", kendo.attr("style-left"), '', true);
removeColumnAttribute(column, "attributes", kendo.attr("style-right"), '', true);
removeColumnAttribute(column, "headerAttributes", "class", headerClassRegExp);
removeColumnAttribute(column, "headerAttributes", "class", headerClassNoBorderRegExp);
removeColumnAttribute(column, "headerAttributes", kendo.attr("style-left"), '', true);
removeColumnAttribute(column, "headerAttributes", kendo.attr("style-right"), '', true);
removeColumnAttribute(column, "footerAttributes", "class", footerClassRegExp);
removeColumnAttribute(column, "footerAttributes", kendo.attr("style-left"), '', true);
removeColumnAttribute(column, "footerAttributes", kendo.attr("style-right"), '', true);
}
},
_setStickyStyles: function(columns, stickyWidths) {
var that = this;
var i;
var j;
var leafsCols = leafColumns(nonLockedColumns(that.columns));
var rows = that.tbody.children(":not(.k-detail-row)");
var row;
var column;
var columnIndex;
var left;
var right;
var header;
var footer;
var groupHeader;
var cell;
for (i = 0; i < columns.length; i++) {
column = columns[i];
left = stickyWidths.left[i];
right = stickyWidths.right[i];
columnIndex = leafsCols.indexOf(column);
header = that._getColumnHeader(column);
header.addClass(STICKY_HEADER_CLASS);
if (column.headerAttributes["class"] && column.headerAttributes["class"].indexOf(STICKY_HEADER_NO_BORDER_CLASS) !== -1) {
header.addClass(STICKY_HEADER_NO_BORDER_CLASS);
}
setLeftAndRightStyles(header, left, right);
if (column.columns) {
continue;
}
if (that.footer) {
footer = that.footer.find(".k-grid-footer-wrap tr.k-footer-template").children().filter(":not(.k-group-cell,.k-hierarchy-cell)").eq(columnIndex);
footer.addClass(STICKY_FOOTER_CLASS);
setLeftAndRightStyles(footer, left, right);
}
for (j = 0; j < rows.length; j++) {
row = $(rows[j]);
if (row.hasClass(GROUPING_ROW)) {
groupHeader = row.find("." + column.groupHeaderColumnTemplateClass);
groupHeader.addClass(STICKY_CELL_CLASS);
setLeftAndRightStyles(groupHeader, left, right);
} else {
cell = row.children().filter(":not(.k-group-cell,.k-hierarchy-cell)").eq(columnIndex);
cell.addClass(STICKY_CELL_CLASS);
setLeftAndRightStyles(cell, left, right);
}
}
}
},
_removeStickyStyles: function(columns) {
var that = this;
var i;
var j;
var leafsCols = leafColumns(nonLockedColumns(that.columns));
var rows = that.tbody.children(":not(.k-detail-row)");
var row;
var column;
var columnIndex;
var header;
var footer;
var groupHeader;
var cell;
for (i = 0; i < columns.length; i++) {
column = columns[i];
columnIndex = leafsCols.indexOf(column);
header = that._getColumnHeader(column);
header.removeClass(STICKY_HEADER_CLASS);
header.removeClass(STICKY_HEADER_NO_BORDER_CLASS);
setLeftAndRightStyles(header, "", "");
if (column.columns) {
that._removeStickyStyles(column.columns);
continue;
}
if (column.footerTemplate && that.footer) {
footer = that.footer.find(".k-grid-footer-wrap tr.k-footer-template").children().filter(":not(.k-group-cell,.k-hierarchy-cell)").eq(columnIndex);
footer.removeClass(STICKY_FOOTER_CLASS);
setLeftAndRightStyles(footer, "", "");
}
for (j = 0; j < rows.length; j++) {
row = $(rows[j]);
if (row.hasClass(GROUPING_ROW)) {
groupHeader = row.find("." + column.groupHeaderColumnTemplateClass);
groupHeader.removeClass(STICKY_CELL_CLASS);
setLeftAndRightStyles(groupHeader, "", "");
} else {
cell = row.children().filter(":not(.k-group-cell,.k-hierarchy-cell)").eq(columnIndex);
cell.removeClass(STICKY_CELL_CLASS);
setLeftAndRightStyles(cell, "", "");
}
}
}
},
_getColumnHeader: function(column) {
var that = this;
var header = $("#" + column.headerAttributes.id).length ? $("#" + column.headerAttributes.id) : $("#" + that._cellId);
return header;
},
_sumColumnWidth: function(column) {
var that = this;
var width = 0;
if (column.columns) {
width = that._sumCurrentWidths(leafColumns([column]));
} else {
width = that._sumCurrentWidths([column]);
}
return width;
},
_sumCurrentWidths: function(cols) {
var that = this;
var width = 0;
var colWidth = 0;
var col;
var header;
var i;
var length = cols.length;
for (i = 0; i < length; i++) {
col = cols[i];
header = that._getColumnHeader(col);
if (!col.hidden && columnMatchesMedia(col)) {
colWidth = header.is(":visible") ? header.outerWidth() : col.width;
width += colWidth ? parseInt(colWidth, 10) : 0;
}
}
return width;
},
_belongsToGrid: function(element) {
return this.wrapper[0] === element.closest(WRAPPER)[0];
},
getSelectedData: function() {
var that = this;
var selectedRanges = that.selectable.selectedRanges();
var selectedRangeNames = Object.keys(selectedRanges);
var selectedSingleItems = that.selectable.selectedSingleItems();
var result = [];
var visibleColumns = visibleLeafColumns(that.columns);
for (var idx = 0; idx < selectedRangeNames.length; idx++) {
result = result.concat(that._mapSelectionToData(selectedRanges[selectedRangeNames[idx]], visibleColumns, null, true));
}
if (selectedSingleItems.length) {
result = result.concat(that._mapSelectionToData(selectedSingleItems, visibleColumns, null, true));
}
return result;
},
getSelectedDataByKeys: function() {
var that = this,
dataSource = that.dataSource,
keys = that.selectedKeyNames(),
visibleColumns = visibleLeafColumns(that.columns),
key,
dataItem,
result = {};
var columnMapHandler = function(col) {
var result = {};
if (!col.field) {
return;
}
result[col.field] = dataItem[col.field];
return result;
};
for (let i = 0; i < keys.length; i++) {
key = keys[i];
dataItem = dataSource.get(key);
if (dataItem) {
result[dataItem.uid] = $.extend.apply({}, visibleColumns.map(columnMapHandler));
}
}
return Object.keys(result).map(function(id) {
return result[id];
});
},
exportSelectedToExcel: function(includeHeaders) {
if (!kendo.excel || !kendo.ooxml) {
throw new Error("The excel export functionality depends on both kendo.excel.js and kendo.ooxml.js scripts, please make sure they are included.");
}
var that = this;
var excel = this.options.excel || {};
var visibleColumns = visibleLeafColumns(that.columns);
var exporter = new kendo.excel.ExcelExporter({});
var columnHandler = function() { return { autoWidth: true }; };
var book = {
sheets: [{
columns: Array.apply(0, Array(visibleColumns.length)).map(columnHandler),
rows: [],
freezePane: {},
filter: false
}]
};
var selectedRanges = that.selectable.selectedRanges();
var selectedRangeNames = Object.keys(selectedRanges);
var selectedSingleItems = that.selectable.selectedSingleItems();
var idx;
var exportData = [];
var hasLockedCols = that._isLocked() && lockedColumns(that.columns).length;
var sortHandler = exportDataSort.bind(that);
for (idx = 0; idx < selectedRangeNames.length; idx++) {
exportData = exportData.concat(that._mapSelectionToData(selectedRanges[selectedRangeNames[idx]], visibleColumns, isExcelExportableColumn));
}
if (exportData.length) {
that._addRangeSelectionRows(book, exporter, exportData, includeHeaders);
}
exportData = selectedSingleItems.length ? that._mapSelectionToData(selectedSingleItems, visibleColumns, isExcelExportableColumn) : [];
if (exportData.length) {
if (hasLockedCols) {
exportData = exportData.sort(sortHandler);
}
that._addSingleSelectionRows(book, exporter, exportData, includeHeaders);
}
if (book.sheets[0].rows.length) {
var workbook = new kendo.ooxml.Workbook(book);
if (!workbook.options) {
workbook.options = {};
}
workbook.options.skipCustomHeight = true;
workbook.toDataURLAsync().then(function(dataURI) {
kendo.saveAs({
dataURI: dataURI,
fileName: book.fileName || excel.fileName,
proxyURL: excel.proxyURL,
forceProxy: excel.forceProxy
});
});
}
},
_addSingleSelectionRows: function(book, exporter, data, includeHeaders) {
var idx = 0;
var visibleColumns = visibleLeafExportColumns(this.columns);
var item;
const exporterInstance = exporter._instance ?? exporter;
for (idx = 0; idx < data.length; idx++) {
item = data[idx];
exporter.data = [item];
this._setExporterColumns(exporterInstance, visibleColumns, item);
this._createExportRows(book, exporterInstance, includeHeaders);
}
},
_addRangeSelectionRows: function(book, exporter, data, includeHeaders) {
var visibleColumns = visibleLeafExportColumns(this.columns);
const exporterInstance = exporter._instance ?? exporter;
exporter.data = data;
this._setExporterColumns(exporterInstance, visibleColumns, data[0]);
this._createExportRows(book, exporterInstance, includeHeaders);
},
_createExportRows: function(book, exporter, includeHeaders) {
const exporterInstance = exporter._instance ?? exporter;
book.sheets[0].rows = book.sheets[0].rows.concat(includeHeaders ? exporterInstance._rows() : exporterInstance._dataRows(exporterInstance.data, 0));
},
_setExporterColumns: function(exporter, columns, item) {
const exporterInstance = exporter._instance ?? exporter;
exporterInstance.columns = exporterInstance.options.columns = $.map(columns.filter(function(col) {
return Object.keys(item).indexOf(col.field) >= 0;
}), exporterInstance._prepareColumn);
},
_mapSelectionToData: function(elements, visibleColumns, columnsFilter, ignoreOffset) {
var that = this;
var elementType = elements[0][0].nodeName;
var isRowSelection = elementType === 'TR';
var dataItem;
var result = {};
var element;
var curr;
var field;
var columnMapHandler = function(col) {
var result = {};
if (!col.field || (columnsFilter && !columnsFilter(col))) {
return;
}
result[col.field] = dataItem[col.field];
return result;
};
var hasLockedCols = that._isLocked() && lockedColumns(that.columns).length;
var column;
for (var i = 0; i < elements.length; i++) {
element = elements[i];
dataItem = that.dataItem(isRowSelection ? element : element.parent());
if (isRowSelection) {
result[dataItem.uid] = $.extend.apply({}, visibleColumns.map(columnMapHandler));
} else {
field = that._getCellField(element, hasLockedCols, ignoreOffset);
if (!field) {
continue;
}
curr = result[dataItem.uid];
if (!curr) {
curr = result[dataItem.uid] = {};
}
column = findColumnByField(visibleColumns, field);
if (!column || (columnsFilter && !columnsFilter(column))) {
continue;
}
curr[field] = dataItem[field];
}
}
return Object.keys(result).map(function(id) {
result[id].uid = id;
return result[id];
});
},
_getCellField: function(cell, hasLockedCols, ignoreOffset) {
const grid = this;
const inLockedArea = hasLockedCols && $.contains(grid.lockedTable[0], cell[0]);
const fieldAttr = kendo.attr('field');
const index = kendo.attr('index');
const lockedOffset = inLockedArea ? 0 : hasLockedCols;
let indexOffset = 0;
if (ignoreOffset) {
indexOffset = grid._trailingColumns();
}
if (hasLockedCols) {
return grid.element.find(".k-grid-header-" + (inLockedArea ? "locked" : "wrap") + " th[" + index + "='" + (cell.index() + lockedOffset) + "']").attr(fieldAttr);
} else {
return grid.thead.find("th[" + index + "='" + (cell.index() - indexOffset) + "']").attr(fieldAttr);
}
},
_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);
},
_relatedCell: function(cell) {
var lockedTable = this.lockedTable;
cell = $(cell);
if (!lockedTable) {
return cell;
}
var table = cell.closest(this.table.add(this.lockedTable));
var index = table.find(">tbody>tr>td").index(cell);
table = table[0] === this.table[0] ? lockedTable : this.table;
return table.find(">tbody>tr>td").index(index);
},
clearSelection: function() {
var that = this;
if (that.selectable && !that._checkBoxSelection) {
that.selectable.clear();
}
if (that._checkBoxSelection) {
that._deselectCheckRows(that.select());
return;
}
if (that.options.persistSelection) {
that._persistSelectedRows();
} else {
that._selectedIds = {};
}
},
select: function(items) {
var that = this,
selectable = that.selectable,
selectableoptions = kendo.ui.Selectable.parseOptions(this.options.selectable),
cell = selectableoptions.cell;
items = that.table.add(that.lockedTable).find(items);
if (items.length) {
if (selectable && !selectable.options.multiple) {
selectable.clear();
items = items.first();
}
if (that._isLocked()) {
items = items.add(items.map(function() {
if (cell) {
return that._relatedCell(this);
}
else {
return that._relatedRow(this);
}
}));
}
if (selectable && !that._checkBoxSelection) {
selectable.value(items);
} else {
that._checkRows(items);
if (that.select().length === that.items().length) {
that._toggleHeaderCheckState(true);
}
}
if (!cell) {
that._persistSelectedRows();
}
return;
}
return selectable ? selectable.value() : that.items().filter("." + SELECTED);
},
_initSelectableAggregates: function() {
var that = this;
if (!that.options.selectable) {
return;
}
if (!that._selectableAggregatesOptions) {
that._selectableAggregatesOptions = that._parseSelectableAggregatesOptions();
}
if (that._selectableAggregatesOptions.count) {
that._cellAggregates = {
count: 0
};
}
},
_calculateAggregatesForSelected: function() {
var that = this,
options = that.options,
selectedData = that.getSelectedDataByKeys(),
selectable = that.options.selectable,
cellAggregates = selectable.cellAggregates,
cellsLength = visibleLeafColumns(that.columns).filter(col => !col.selectable && !col.draggable & !col.command).length,
columnFields = getColumnsFields(options.columns),
isCellSelection = kendo.ui.Selectable.parseOptions(selectable).cell,
dataItem,
type,
value,
numberAggregates = [],
dateAggregates = [],
booleanAggregates = [],
count, min, max, sum, average, earliest, latest, isTrue, isFalse;
if (!cellAggregates) {
return;
}
// getSelectedDataByKeys won't work for cell selection.
if (isCellSelection) {
selectedData = that.getSelectedData();
}
cellAggregates = that._selectableAggregatesOptions;
for (let i = 0; i < selectedData.length; i++) {
dataItem = selectedData[i];
for (let j = 0; j < columnFields.length; j++) {
value = dataItem[columnFields[j]];
type = getType(value);
switch (type) {
case "number":
numberAggregates.push(value);
break;
case "date":
dateAggregates.push(value);
break;
case "boolean":
booleanAggregates.push(value);
break;
}
}
}
if (cellAggregates.count) {
count = isCellSelection ? cellsExcludingSpecialColumns(that.select()).length : selectedData.length * cellsLength;
}
if (numberAggregates.length) {
max = cellAggregates.max ? numberAggregates.reduce((acc, current) => Math.max(acc, current)) : null;
min = cellAggregates.min ? numberAggregates.reduce((acc, current) => Math.min(acc, current)) : null;
sum = cellAggregates.sum ? numberAggregates.reduce((acc, current) => acc + current) : null;
average = cellAggregates.average ? numberAggregates.reduce((acc, current) => (acc + current)) / numberAggregates.length : null;
}
if (dateAggregates.length) {
earliest = cellAggregates.earliest ? dateAggregates.reduce((acc, current) => new Date(Math.min(acc, current))) : null;
latest = cellAggregates.latest ? dateAggregates.reduce((acc, current) => new Date(Math.max(acc, current))) : null;
}
if (booleanAggregates.length) {
isTrue = cellAggregates.isTrue ? booleanAggregates.filter(b => b === true).length : null;
isFalse = cellAggregates.isFalse ? booleanAggregates.filter(b => b === false).length : null;
}
that._cellAggregates = {
count: count,
max: max,
min: min,
sum: sum,
average: average,
earliest: earliest,
latest: latest,
isTrue: isTrue,
isFalse: isFalse
};
if (that.statusBar) {
that._statusBar();
}
},
_parseSelectableAggregatesOptions: function() {
var that = this,
cellAggregates = that.options.selectable.cellAggregates,
result = {};
if (isArray(cellAggregates)) {
for (let i = 0; i < cellAggregates.length; i++) {
result[cellAggregates[i]] = true;
}
return result;
}
// If the value of cellAggregates is 'true' -> all aggregates must be enabled.
return {
count: true,
min: true,
max: true,
sum: true,
average: true,
earliest: true,
latest: true,
isTrue: true,
isFalse: 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");
}
},
_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) {
var that = this,
rangeSelectedAttr = kendo.attr("range-selected");
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).removeAttr(rangeSelectedAttr).find(CHECKBOXINPUT).attr(ARIA_CHECKED, false)
.prop("checked", false).attr(ARIA_LABEL, "Select row");
});
that._toggleHeaderCheckState(false);
that._persistSelectedRows();
},
_checkRows: function(items) {
items.each(function() {
$(this).addClass(SELECTED).find(CHECKBOXINPUT)
.prop("checked", true)
.attr(ARIA_LABEL, "Deselect row")
.attr(ARIA_CHECKED, true);
});
},
_persistSelectedRows: function() {
var that = this,
key,
dataItem,
allRows = that.items(),
dataSourceOptions = that.dataSource.options,
schema = dataSourceOptions.schema,
modelId,
selectedViewIds = {};
if (!schema || !schema.model || !that._data) {
return;
}
modelId = that._getSchemaIdField();
if (!modelId) {
return;
}
if (!kendo.ui.Selectable.parseOptions(that.options.selectable).multiple && !that._checkBoxSelection) {
that._selectedIds = {};
}
that.select().each(function() {
dataItem = that.dataItem(this);
selectedViewIds[dataItem[modelId]] = true;
});
for (var i = 0; i < allRows.length; i++) {
dataItem = that.dataItem(allRows[i]);
key = dataItem[modelId];
if (selectedViewIds[key]) {
that._selectedIds[key] = true;
} else {
delete that._selectedIds[key];
}
}
},
selectedKeyNames: function() {
var that = this,
ids = [];
for (var property in that._selectedIds) {
ids.push(property);
}
ids.sort();
return ids;
},
_updateCurrentAttr: function(current, next, skipFocus) {
var headerId = $(current).data("headerId");
var nextId;
var descId;
$(current).removeClass(FOCUSED);
this.table.removeAttr(ARIA_ACTIVEDESCENDANT);
if (headerId) {
headerId = headerId.replace(this._cellId, "");
$(current).attr(ID, headerId);
} else {
$(current).removeAttr(ID);
}
nextId = next.attr(ID);
if (nextId != this._cellId) {
next.data("headerId", nextId);
}
if (!!nextId) {
descId = nextId;
} else {
next.attr(ID, this._cellId);
}
if (!skipFocus) {
next.addClass(FOCUSED);
}
this.table.attr(ARIA_ACTIVEDESCENDANT, descId || this._cellId);
this._current = next;
},
_scrollCurrent: function() {
const current = this._current;
const 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,.k-virtual-scrollable-wrap");
var scrollableContainer = $(this.content).find(">.k-virtual-scrollable-wrap").addBack().last()[0];
//adjust scroll vertically
if (isInContent) {
if (this.virtualScroll) {
var rowIndex = Math.max(inArray(row[0], this._items(row.parent())), 0);
if (this.virtualScroll.rows) {
this._rowVirtualIndex = this.virtualScrollable.itemIndex(rowIndex);
this.virtualScrollable.scrollIntoView(row);
} else {
this._rowVirtualIndex = rowIndex;
this._scrollTo(this._relatedRow(row)[0], scrollableContainer);
}
} else {
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);
}
},
_findGroupedItem: function(data, id, idField) {
const that = this;
let item;
for (let i = 0; i < data.length; i++) {
const group = data[i];
if (group.field === idField) {
if (group.value === id) {
if (group.items[0].uid && group.items[0][idField]) {
item = group.items[0];
} else {
item = that._findGroupedItem(group.items, id, idField);
}
}
} else if (group.items[0].uid && group.items[0][idField]) {
item = group.items.find((item) => item[idField] === id);
} else {
item = that._findGroupedItem(group.items, id, idField);
}
if (item) {
return item;
}
}
},
_findClosestGroupingRow: function(htmlRow, rowsCount, hiddenGroupingRows) {
const that = this;
const hasGroupingRows = that.options.groupable && that.dataSource.group().length > 0;
let i = rowsCount ? rowsCount : 0;
let j = hiddenGroupingRows ? hiddenGroupingRows : 0;
if (!hasGroupingRows || !htmlRow) {
return { targetRow: htmlRow, rowsToTarget: i, hiddenGroupingRows: j };
}
const prevSibling = $(htmlRow.previousSibling);
if (prevSibling && prevSibling.hasClass(GROUPING_ROW)) {
let result = { targetRow: prevSibling, rowsToTarget: i, hiddenGroupingRows: j };
if (prevSibling.css("display") === "none") {
result = that._findClosestGroupingRow(prevSibling[0], i, j + 1);
}
return result;
} else {
const result = that._findClosestGroupingRow(prevSibling[0], i + 1, j);
if (result) {
return { targetRow: result.targetRow, rowsToTarget: result.rowsToTarget, hiddenGroupingRows: j };
}
}
},
_checkItemAlreadyLoaded: function(id, idField) {
const that = this;
const dataSource = that.dataSource;
const ranges = dataSource._ranges;
let item;
for (let i = 0; i < ranges.length; i++) {
const range = ranges[i].data;
item = range.find((item) => item[idField] === id);
if (item) {
return { loadedItem: item, page: i };
}
}
return;
},
scrollToItem: function(id, callback) {
const that = this,
options = that.options,
dataSource = that.dataSource,
groups = dataSource.group(),
pageSize = dataSource.pageSize(),
idField = that._getSchemaIdField(),
scrollable = options.scrollable,
scrollableContainer = that.wrapper.find(".k-grid-content.k-auto-scrollable"),
rowHeight = kendo._outerHeight(that.tbody.find(`tr:not(.${GROUPING_ROW})`)),
isVirtual = scrollable && scrollable.virtual && (scrollable.virtual === 'rows' || scrollable.virtual === true);
let rootGroupingRow = options.groupable && that.wrapper.find(`.${GROUPING_ROW}:first-child`);
let previouslyScrolledItems = {};
let targetRowIsHidden = false;
let groupingRowHeight = 0;
if (that._scrolledItems) {
previouslyScrolledItems = that._scrolledItems;
}
if (isVirtual && groups.length === 0) {
that.virtualScrollable._alwaysScrollTop = true;
}
if (!id || !idField) {
return;
}
const currentView = dataSource.view();
let item = currentView.find((item) => item[idField] == id);
if (groups.length > 0) {
item = that._findGroupedItem(currentView, id, idField);
groupingRowHeight = kendo._outerHeight(rootGroupingRow[0]);
}
if (!item && isVirtual) {
if (!that.virtualScrollable._programmaticallyScrolling || that.virtualScrollable._programmaticallyScrolling.state() === 'resolved') {
that.virtualScrollable._programmaticallyScrolling = $.Deferred();
}
callback && typeof callback === 'function' && callback({
success: (index) => {
let itemIndex = index;
itemIndex = typeof itemIndex !== 'number' ? Number(itemIndex) : itemIndex;
if (isNaN(itemIndex)) {
return;
}
const serverPaging = dataSource.options.serverPaging;
let page = math.floor(itemIndex / pageSize);
if (serverPaging) {
const itemLoaded = that._checkItemAlreadyLoaded(id, idField);
if (itemLoaded) {
page = itemLoaded.page;
}
}
const allRows = scrollableContainer.find(TR);
const lastRowOffsetTop = allRows[allRows.length - 1].offsetTop;
const pageEndOffset = (pageSize / allRows.length) * lastRowOffsetTop;
const itemsToTarget = (itemIndex - page * pageSize) - 1;
const scrollPosition = page * pageEndOffset + itemsToTarget * rowHeight;
that._scrollingUp = that.virtualScrollable.verticalScrollbar.scrollTop() > scrollPosition;
that._scrollOffset = scrollPosition;
that.virtualScrollable._scrollTo(scrollPosition);
that.virtualScrollable.verticalScrollbar.trigger(SCROLL);
return that.virtualScrollable._programmaticallyScrolling.done(() => {
that.scrollToItem(id);
});
}
});
return;
}
const uid = item && item.uid;
if (!uid) {
return;
}
const selector = `[data-uid=${uid}]`;
let element = $(selector);
let { targetRow, rowsToTarget, hiddenGroupingRows } = that._findClosestGroupingRow(element[0]);
if (!element || !targetRow) {
return;
} else if (groups.length > 0 && element.css("display") === "none") {
element = targetRow;
targetRowIsHidden = true;
}
const hiddenGroupingRowsOffset = targetRowIsHidden ? (hiddenGroupingRows * groupingRowHeight) + rowHeight : 0;
let wrapperPosition = element[0].offsetTop - (((rowsToTarget + groups.length) * groupingRowHeight) - hiddenGroupingRowsOffset);
let scrollPosition = wrapperPosition;
if (isVirtual) {
if (previouslyScrolledItems && previouslyScrolledItems[id]) {
const scrollerPosition = Math.floor(that.virtualScrollable.verticalScrollbar.scrollTop());
const prevScrollDown = Math.floor(previouslyScrolledItems[id].scrollingDownOffset);
const prevScrollUp = Math.floor(previouslyScrolledItems[id].scrollingUpOffset);
if (scrollerPosition === prevScrollUp || scrollerPosition === prevScrollDown) {
return;
}
that._scrollingUp = scrollerPosition > scrollPosition;
if (that._scrollingUp) {
scrollPosition = prevScrollUp ?? scrollPosition;
} else {
scrollPosition = prevScrollDown ?? scrollPosition;
}
}
if (that._scrollOffset) {
if (!that._scrollingUp) {
scrollPosition += that._scrollOffset;
} else {
if (that._scrollOffset === wrapperPosition) {
that._scrollOffset += rowHeight;
}
scrollPosition = ((wrapperPosition - that.virtualScrollable._scrollTop) + that._scrollOffset);
}
}
that.virtualScrollable._scrollTo(wrapperPosition, scrollPosition);
if (!previouslyScrolledItems[id]) {
previouslyScrolledItems[id] = {};
}
if (that._scrollingUp) {
if (previouslyScrolledItems[id] && !previouslyScrolledItems[id].scrollingUpOffset) {
previouslyScrolledItems[id].scrollingUpOffset = scrollPosition;
}
} else {
if (previouslyScrolledItems[id] && !previouslyScrolledItems[id].scrollingDownOffset) {
previouslyScrolledItems[id].scrollingDownOffset = scrollPosition;
}
}
} else {
scrollableContainer.scrollTop(scrollPosition);
}
if (that.virtualScrollable) {
if (that._scrollOffset) {
delete that._scrollOffset;
}
if (that._scrollingUp) {
delete that._scrollingUp;
}
}
that._scrolledItems = previouslyScrolledItems;
},
current: function(next) {
return this._setCurrent(next, true);
},
_setCurrent: function(next, preventTrigger, preventScroll, skipFocus) {
var current = this._current;
next = $(next);
if (current && next && current.length && next.length && current.closest(".k-filter-row").length > 0 && next.closest(".k-filter-row").length === 0) {
this._filterFocusable().attr(TABINDEX, -1);
}
if (next.length) {
if (!current || current[0] !== next[0]) {
var parent = next.parent();
var siblings = parent.children(DATA_CELL);
var colspan = parseInt(parent.children().first().attr("colspan"), 10);
if (this._hasVirtualColumns()) {
this._virtualCellIndex = (colspan > 1 ? colspan : 0) + siblings.index(next);
}
this._updateCurrentAttr(current, next, skipFocus);
if (!preventScroll) {
this._scrollCurrent();
}
if (!preventTrigger) {
this.trigger(NAVIGATE, {
element: next
});
}
}
}
if (next && next.length) {
this._lastCellIndex = next.parent().children(".k-group-cell," + DATA_CELL_HIDDENINCLUDED).index(next);
}
this._updateSelctCheckbox(current, next);
return this._current;
},
_removeCurrent: function() {
if (this._current) {
this._current.removeClass(FOCUSED);
this._current = null;
}
},
_updateSelctCheckbox: function(current, next) {
var nextCheckbox;
if (next && next.length) {
nextCheckbox = next.find(".k-select-checkbox");
if (nextCheckbox.length > 0) {
nextCheckbox.trigger("focus");
} else if (current && current.find(".k-select-checkbox").length > 0) {
focusTable(this.table, true);
}
}
},
_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;
},
_navigatable: function() {
var that = this;
if (!that.options.navigatable) {
return;
}
//data tables - locked and non-locked
var dataTables = that.table.add(that.lockedTable);
//header tables - locked and non-locked
var headerTables = that.thead.parent().add($(">table", that.lockedHeader));
//the over wich keys will be handled
var tables = dataTables;
if (that.options.scrollable) {
//add the header table when the widget is scrollable
tables = tables.add(headerTables);
}
this._navigatableTables = tables;
this._headertables = headerTables;
//dettach all previous events
tables.off(MOUSEDOWN + NS + " focus" + NS + " focusout" + NS + " keydown" + NS);
headerTables
.find("a.k-link").attr("tabIndex", -1);
//prevent propagation when clicked inside detail grid
dataTables
.on("keydown" + NS, ".k-detail-cell", function(e) {
if (e.target !== e.currentTarget) {
e.stopImmediatePropagation();
}
});
tables
//handle click on tables, will attempt to focus the table
.on((kendo.support.touch ? "touchstart" + NS : MOUSEDOWN + NS), NAVROW + ">" + NAVCELL, tableClick.bind(that))
.on("focus" + NS, that._tableFocus.bind(that))
.on("focusout" + NS, that._tableBlur.bind(that))
.on("keydown" + NS, that, that._tableKeyDown.bind(that));
that._filterFocusable().on("focus", that._filterFocus.bind(that));
},
_filterFocus: function(e) {
var header = e.target.closest("th");
this._filterFocusable().attr(TABINDEX, 0);
this._setCurrent(header);
$(header).removeClass(FOCUSED);
},
_tableFocus: function() {
var current = this.current();
var table = this.lockedTable ? this.lockedTable : this.table;
//if there is already current, highlighted it
//otherwise highlight the first possible cell
if (current && current.is(":visible")) {
current.addClass(FOCUSED);
} else {
if (this._virtualColScroll) {
this._setCurrent(table.find(NAVROW).first().children(NAVCELL).first(), true, true);
} else {
this._setCurrent(table.find(NAVROW).first().children(NAVCELL).first());
}
}
this.table.attr(TABINDEX, 0);
},
_tableBlur: function() {
var current = this.current();
if (current) {
current.removeClass(FOCUSED);
}
},
_findCellIndex: function(columns, startIndex, reversed) {
var cellIndex;
var i;
if (reversed) {
for (i = startIndex; i >= 0; i--) {
cellIndex = i;
if (!columns[i].hidden) {
break;
}
}
} else {
for (i = startIndex; i < columns.length; i++) {
cellIndex = i;
if (!columns[i].hidden) {
break;
}
}
}
return cellIndex;
},
_scrollToColumn: function(key, e) {
if (this._virtualCellIndex === undefined$1) {
return false;
}
var that = this;
var cellIndex = that._virtualCellIndex;
var leafsCols = leafColumns(nonLockedColumns(that.columns));
var scrollWidth = 0;
if (key == (isRtl ? keys.LEFT : keys.RIGHT) && (cellIndex !== leafsCols.length - 1)) {
cellIndex = that._findCellIndex(leafsCols, cellIndex + 1);
} else if (key == (isRtl ? keys.RIGHT : keys.LEFT) && cellIndex) {
cellIndex = that._findCellIndex(leafsCols, cellIndex - 1, true);
} else if (key == keys.HOME) {
cellIndex = that._findCellIndex(leafsCols, 0);
} else if (key == keys.END) {
cellIndex = that._findCellIndex(leafsCols, leafsCols.length - 1, true);
}
for (var i = 0; i < cellIndex; i++) {
scrollWidth += leafsCols[i].width;
}
that._virtualCellIndex = cellIndex;
if (e) {
e.preventDefault();
e.stopPropagation();
}
let scrollable = that.content;
if (that._hasVirtualRows() && that._hasVirtualColumns()) {
scrollable = that.virtualScrollable.wrapper;
}
kendo.scrollLeft(scrollable, scrollWidth);
return true;
},
_tableKeyDown: function(e) {
let current = this.current(),
currentTable = current && current.closest(DOT + "k-grid-table")[0],
virtualScroll = this.virtualScroll || {},
requestInProgress = this.virtualScrollable && this.virtualScrollable.fetching(),
target = $(e.target),
canHandle = !e.isDefaultPrevented() && (!target.is(":button,a,:input:not(.k-select-checkbox),a>.k-icon,a>.k-svg-icon") || this._isFocusableGridElement(current));
if (e.altKey && e.keyCode == keys.DOWN) {
this.current().find(".k-grid-filter-menu, .k-grid-column-menu").click();
e.stopImmediatePropagation();
return;
}
// do not handle key down if request in progress
// or there isn't current set
if (requestInProgress) {
// swallow key events while in progress
e.preventDefault();
return;
}
if (virtualScroll.columns && (!current || !document.body.contains(current[0])) && (this._scrollToColumn(e.keyCode, e))) {
return;
}
if (!current) {
current = $(this.lockedTable).add(this.options.scrollable ? this.table : this.tbody).find(NAVROW).first().children(NAVCELL).first();
}
if (!current.length) {
return;
}
var handled = false;
if (!e.isDefaultPrevented() && e.keyCode === keys.F10) {
handled = this._focusToolbar();
}
if (canHandle && e.keyCode == keys.UP) {
handled = this._moveUp(current, e.shiftKey, e.ctrlKey);
}
if (canHandle && e.keyCode == keys.DOWN) {
handled = this._moveDown(current, e.shiftKey, e.ctrlKey);
}
if (canHandle && e.keyCode == (isRtl ? keys.LEFT : keys.RIGHT)) {
handled = this._moveRight(current, e.altKey, e.shiftKey, e.ctrlKey, currentTable);
}
if (canHandle && e.keyCode == (isRtl ? keys.RIGHT : keys.LEFT)) {
handled = this._moveLeft(current, e.altKey, e.shiftKey, e.ctrlKey, currentTable);
}
if (canHandle && e.keyCode == keys.PAGEDOWN) {
handled = this._handlePageDown();
}
if (canHandle && e.keyCode == keys.PAGEUP) {
handled = this._handlePageUp();
}
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 (canHandle && e.keyCode == keys.SPACEBAR) {
handled = this._handleSpaceKey(current, e.ctrlKey);
}
if (e.keyCode == keys.ENTER || e.keyCode == keys.F2) {
handled = this._handleEnterKey(current, currentTable, target);
}
if (e.keyCode == keys.ESC) {
handled = this._handleEscKey(current, currentTable);
}
if (e.keyCode == keys.TAB) {
handled = this._handleTabKey(current, currentTable, e.shiftKey, target);
}
if (handled) {
//prevent scrolling while pressing the keys
e.preventDefault();
//required in hierarchy
e.stopPropagation();
}
},
_focusToolbar: function() {
var focusable = this.wrapper.find(".k-grid-toolbar [tabindex=0]");
if (focusable.length > 0) {
focusable.first().addClass(".k-focus").trigger("focus");
return true;
}
return false;
},
_focusFocusable: function(current, next, preventTrigger, preventScroll, eventData) {
const focusable = this._isFocusableGridElement(next) && next.find(FOCUSABLE);
// If we have focused a focusable element inside a cell with multiple focusable elements,
// we should not be able to use the arrows to navigate to another cell.
if ((this._containerHasActiveElement(current) && current.find(FOCUSABLE).length !== 1) || !next.length) {
return;
}
focusTable(this.table, true);
this._setCurrent(next, preventTrigger, preventScroll);
if (focusable.length === 1 && !focusable.is("table")) {
focusable.trigger("focus");
eventData?.preventDefault();
}
},
_containerHasActiveElement: function(container) {
return container.find(activeElement()).length;
},
_isFocusableGridElement: function(element) {
if (!element) {
return false;
}
return element.is(FOCUSABLE_GRID_ELEMENT_SELECTORS) || element.has(FOCUSABLE_GRID_ELEMENT_SELECTORS).length;
},
_moveLeft: function(current, altKey, shiftKey, ctrlKey, currentTable) {
var next, index;
var row = current.parent();
//thead or tbody
var container = row.parent();
if (altKey) {
if (row.hasClass(GROUPING_ROW)) {
this.collapseGroup(row);
} else {
this.collapseRow(row);
}
} else if (ctrlKey && current.is(DOT + HEADER_CLASS) && this.options.reorderable) {
this._moveColumn(current, true);
} else {
index = container.find(NAVROW).index(row);
next = this._prevHorizontalCell(container, current, index);
if (!next[0] && !this._containerHasActiveElement(current)) {
if (shiftKey) {
if (this.lockedTable) {
next = this._relatedRow(row);
if ($.contains(this.lockedTable[0], row[0])) {
next = next.prevAll(ITEMROW).first();
}
next = next.children(DATA_CELL).last();
} else {
next = this._tabNext(current, currentTable, true);
}
} else {
container = this._horizontalContainer(container);
next = this._prevHorizontalCell(container, current, index);
if (next[0] !== current[0]) {
focusTable(this.table, true);
}
}
}
this._focusFocusable(current, next);
}
return true;
},
_moveRight: function(current, altKey, shiftKey, ctrlKey, currentTable) {
var next, index;
var row = current.parent();
//thead or tbody
var container = row.parent();
if (altKey) {
if (row.hasClass(GROUPING_ROW)) {
this.expandGroup(row);
} else {
this.expandRow(row);
}
} else if (ctrlKey && current.is(DOT + HEADER_CLASS) && this.options.reorderable) {
this._moveColumn(current, false);
} else {
index = container.find(NAVROW).index(row);
next = this._nextHorizontalCell(container, current, index);
if (!next[0] && !this._containerHasActiveElement(current)) {
if (shiftKey) {
if (this.lockedTable) {
next = this._relatedRow(row);
if ($.contains(this.table[0], row[0])) {
next = next.nextAll(ITEMROW).first();
}
next = next.children(DATA_CELL).first();
} else {
next = this._tabNext(current, currentTable, false);
}
} else {
container = this._horizontalContainer(container, true);
next = this._nextHorizontalCell(container, current, index);
if (next[0] !== current[0]) {
focusTable(this.table, true);
}
}
}
this._focusFocusable(current, next);
}
return true;
},
_moveUp: function(current, shiftKey, ctrlKey) {
//thead or tbody
var container = current.parent().parent();
var next, cellIndex, index, oldIndex;
if (shiftKey) {
next = current.parent();
next = next.prevAll(ITEMROW).first();
next = current.parent().is(ITEMROW) ? next.children().eq(current.index()) : next.children(DATA_CELL).last();
} else if (ctrlKey && current.parent().is(ITEMROW) && this._hasReorderableRows()) {
cellIndex = current.index();
next = current.parent();
next = next.prevAll(ITEMROW).first();
index = this.tbody.children(ITEMROW).index(next);
oldIndex = this.tbody.children(ITEMROW).index(current.parent());
if (index >= 0 && !this.trigger(ROWREORDER, { oldIndex: oldIndex, newIndex: index, row: current.parent() })) {
this.reorderRows(current.parent(), index);
next = this.tbody.children(ITEMROW).eq(index).children().eq(cellIndex);
}
} else {
next = this._prevVerticalCell(container, current);
if (!next[0]) {
this._lastCellIndex = 0;
container = this._verticalContainer(container, true);
next = this._prevVerticalCell(container, current);
if (next.is(":hidden")) {
next = next.nextAll().not(":hidden").first();
}
if (next[0]) {
focusTable(this.table, true);
}
}
}
var tmp = this._lastCellIndex || 0;
this._focusFocusable(current, next);
this._lastCellIndex = tmp;
return true;
},
_moveDown: function(current, shiftKey, ctrlKey) {
//thead or tbody
var container = current.parent().parent();
var next, cellIndex, index, oldIndex;
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 if (ctrlKey && current.parent().is(ITEMROW) && this._hasReorderableRows()) {
cellIndex = current.index();
next = current.parent();
next = next.nextAll(ITEMROW).first();
index = this.tbody.children(ITEMROW).index(next);
oldIndex = this.tbody.children(ITEMROW).index(current.parent());
if (index >= 0 && !this.trigger(ROWREORDER, { oldIndex: oldIndex, newIndex: index, row: current.parent() })) {
this.reorderRows(current.parent(), index + 1);
next = this.tbody.children(ITEMROW).eq(index).children().eq(cellIndex);
}
} 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._focusFocusable(current, this._findVisibleCell(next));
this._lastCellIndex = tmp;
return true;
},
_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
});
}
},
_handleHome: function(current, ctrl) {
const that = this;
let row = current.parent();
const rowContainer = row.parent();
const isInLockedTable = that.lockedTable && that.lockedTable.children("tbody")[0] === rowContainer[0];
const isInBody = rowContainer[0] === that.tbody[0];
let prev;
const hasVirtualColumns = that._hasVirtualColumns();
const hasVirtualRows = that._hasVirtualRows();
const scrollable = hasVirtualRows ? that.virtualScrollable.wrapper : that.content;
const isScrolledToStart = scrollable.scrollLeft() === 0;
if (hasVirtualColumns && hasVirtualRows && ctrl) {
that._focusVirtualCell(true, hasVirtualColumns && !isScrolledToStart);
return true;
}
if (hasVirtualColumns) {
if (isScrolledToStart) {
that._setCurrent(that.table.find(ITEMROW).first().children(NAVCELL).first());
} else {
that._forceScrollVirtualColumn(keys.HOME, ctrl);
}
return true;
}
if (hasVirtualRows && ctrl) {
that._focusVirtualCell(true);
return true;
}
if (ctrl) {
if (that.lockedTable) {
prev = that.lockedTable.find(ITEMROW).first().children(NAVCELL).first();
} else {
prev = that.table.find(ITEMROW).first().children(NAVCELL).first();
}
} else if (isInBody || isInLockedTable) {
if (isInBody && this.lockedTable) {
row = that._relatedRow(row);
}
prev = row.children(DATA_CELL).first();
}
if (prev && prev.length) {
that._setCurrent(prev);
return true;
}
},
_setCurrentVirtualCell: function(focusFirst) {
const that = this;
if (focusFirst) {
this._setCurrent(that.table.find(ITEMROW).first().children(NAVCELL).first());
} else {
this._setCurrent(that.table.find(ITEMROW).last().children(NAVCELL).last());
}
},
_forceScrollVirtualColumn: function(key, condition, setboth) {
const that = this;
if (setboth) {
that._shouldFocusInLastRow = !condition;
that._shouldFocusInFirstRow = condition;
} else if (key === keys.HOME) {
that._shouldFocusInFirstRow = condition;
} else {
that._shouldFocusInLastRow = condition;
}
that.one(DATABOUND, function() {
if (setboth) {
that.one(DATABOUND, function() {
that._setCurrentVirtualCell(condition);
});
}
if (that._shouldFocusInLastRow) {
that.content.scrollTop(that.content[0].scrollHeight);
delete that._shouldFocusInLastRow;
}
if (that._shouldFocusInFirstRow) {
that.content.scrollTop(0);
delete that._shouldFocusInFirstRow;
}
});
that._scrollToColumn(key);
},
_focusVirtualCell: function(first, scrollColumn) {
const that = this;
const scrollbar = this.virtualScrollable.verticalScrollbar;
const isScrolledToBottom = Math.ceil(scrollbar.scrollTop() + scrollbar.innerHeight()) >= scrollbar[0].scrollHeight;
const isScrollToTop = this.virtualScrollable.verticalScrollbar.scrollTop() === 0;
const scrollbarCondition = first ? isScrollToTop : isScrolledToBottom;
const key = first ? keys.HOME : keys.END;
if (scrollbarCondition) {
if (scrollColumn) {
that._forceScrollVirtualColumn(key, first, true);
} else {
that._setCurrentVirtualCell(first);
}
} else {
if (that.dataSource.group().length === 0) {
that.virtualScrollable._alwaysScrollTop = true;
}
const scrollPosition = first ? 0 : scrollbar[0].scrollHeight;
that.one(DATABOUND, function() {
if (scrollColumn) {
that._forceScrollVirtualColumn(key, first, true);
} else {
that._setCurrentVirtualCell(first);
if (that._shouldFocusInLastRow) {
delete that._shouldFocusInLastRow;
}
if (that._shouldFocusInFirstRow) {
delete that._shouldFocusInFirstRow;
}
}
});
scrollbar.scrollTop(scrollPosition);
scrollbar.trigger(SCROLL);
}
},
_handleEnd: function(current, ctrl) {
const that = this;
let row = current.parent();
const rowContainer = row.parent();
const isInLockedTable = that.lockedTable && that.lockedTable.children("tbody")[0] === rowContainer[0];
const isInBody = rowContainer[0] === that.tbody[0];
let next;
const hasVirtualColumns = that._hasVirtualColumns();
const hasVirtualRows = that._hasVirtualRows();
const scrollable = hasVirtualRows ? that.virtualScrollable.wrapper : that.content;
const isScrolledToEnd = (scrollable.scrollLeft() + scrollable.innerWidth()) >= scrollable[0].scrollWidth;
if (hasVirtualColumns && hasVirtualRows && ctrl) {
that._focusVirtualCell(false, hasVirtualColumns && !isScrolledToEnd);
return true;
}
if (hasVirtualColumns) {
if (isScrolledToEnd) {
that._setCurrent(that.table.find(ITEMROW).last().children(NAVCELL).last());
} else {
that._forceScrollVirtualColumn(keys.END, ctrl);
}
return true;
}
if (hasVirtualRows && ctrl) {
that._focusVirtualCell(false);
return true;
}
if (ctrl) {
next = that.table.find(ITEMROW).last().children(NAVCELL).last();
} else if (isInBody || isInLockedTable) {
if (!isInBody && this.lockedTable) {
row = that._relatedRow(row);
}
next = row.children(DATA_CELL).last();
}
if (next && next.length) {
that._setCurrent(next);
return true;
}
},
_handlePageDown: function() {
if (!this.options.pageable) {
return false;
}
this.dataSource.page(this.dataSource.page() + 1);
return true;
},
_handlePageUp: function() {
if (!this.options.pageable) {
return false;
}
this.dataSource.page(this.dataSource.page() - 1);
return true;
},
_handleTabKey: function(current, currentTable, shiftKey, target) {
const isInCell = this.options.editable && this._editMode() == "incell";
let cell = $(activeElement()).closest(".k-edit-cell");
let filterFocusable;
const isTargetFocusable = target.is(FOCUSABLE);
const isTargetNotTable = !target.is("table");
const hasMultipleFocusableElements = current.find(FOCUSABLE).length > 1;
const isCurrentFocusableGridElement = this._isFocusableGridElement(current);
const isNotInEditMode = !isInEdit(current);
if (!cell[0] && isTargetFocusable && isTargetNotTable && hasMultipleFocusableElements && isCurrentFocusableGridElement && isNotInEditMode) {
if ((target.is(":last-child") && !shiftKey) || (target.is(":first-child") && shiftKey)) {
focusTable(this.table, true);
return true;
}
if (shiftKey) {
target = target.prev(FOCUSABLE);
} else {
target = target.next(FOCUSABLE);
}
target.trigger("focus");
return true;
}
if (!isInCell ||
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;
}
if (cell[0] && cell[0] !== current[0]) {
current = cell;
}
cell = this._tabNext(current, currentTable, shiftKey);
if (cell[0] === current[0]) {
return false;
}
if (cell.length) {
this._handleEditing(current, cell, cell.closest("table"));
return true;
}
return false;
},
_handleEscKey: function(current) {
const active = activeElement();
const isInCell = this._editMode() == "incell";
if (!isInEdit(current)) {
if (current.has(active).length && !(this._isFocusableGridElement(current) && current.find(FOCUSABLE).length === 1)) {
// return focus back to the table
focusTable(this.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 (isInCell) {
this.closeCell(true);
} else {
var currentIndex = $(current).parent().index();
if (active) {
active.blur();
}
this.cancelRow(true);
if (currentIndex >= 0) {
this._setCurrent(this.items().eq(currentIndex).children(NAVCELL).first());
}
}
focusTable(this.table, true);
return true;
},
_toggleCurrent: function(current, editable, hasDetails) {
var row = current.parent();
if (current.is(".k-command-cell")) {
return false;
}
if (row.is(".k-filter-row")) {
return false;
}
if (row.is(DOT + GROUPING_ROW)) {
row.find(".k-icon,.k-svg-icon").first().click();
return true;
}
if (!editable && hasDetails) {
row.find(".k-icon,.k-svg-icon").first().click();
return true;
}
return false;
},
_handleSpaceKey: function(current, ctrlKey) {
var that = this;
if (!ctrlKey || !that.groupable || !current.hasClass(HEADER_CLASS)) {
return;
}
var descriptors = that.groupable.descriptors();
var field = current.attr(kendo.attr("field"));
var aggregates = that.groupable.aggregates();
if (that.groupable._canDrag(current)) {
descriptors.push({
field: field,
dir: "asc",
aggregates: aggregates || []
});
} else {
descriptors = $.grep(descriptors, function(item) {
return item.field !== field;
});
}
that.dataSource.group(descriptors);
return true;
},
_handleEnterKey: function(current, currentTable, target) {
var editable = this.options.editable && this.options.editable.update !== false;
var container = target.closest("td");
var hasDetails = this._hasDetails();
var 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;
}
if (this._toggleCurrent(current, editable, hasDetails)) {
return true;
}
var focusable = current.find(":kendoFocusable").first();
if (focusable[0] && !current.hasClass("k-edit-cell") && 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;
}
return false;
},
_nextHorizontalCell: function(table, current, originalIndex) {
var cells = current.nextAll(DATA_CELL);
if (!cells.length) {
var rows = table.find(NAVROW);
var rowIndex = rows.index(current.parent());
//no sibling cells are found and we've changed the table
if (rowIndex == -1) {
if (current.hasClass(HEADER_CLASS)) {
var headerRows = [];
mapColumnToCellRows([lockedColumns(this.columns)[0]], childColumnsCells(rows.eq(0).children(":visible").first()), headerRows, 0, 0);
if (headerRows[originalIndex]) {
return headerRows[originalIndex][0];
}
return current;
}
//current is in filter row
if (current.parent().hasClass("k-filter-row")) {
return rows.last().children(DATA_CELL).first();
}
//get the same row index in the new table
return this._findVisibleCell(rows.eq(originalIndex).children(DATA_CELL + ",[hidden]").first());
}
}
return this._findVisibleCell(current.nextAll(DATA_CELL + ",[hidden]").eq(0));
},
_prevHorizontalCell: function(table, current, originalIndex) {
var cells = current.prevAll(DATA_CELL);
if (!cells.length) {
var rows = table.find(NAVROW);
var rowIndex = rows.index(current.parent());
//no sibling cells are found and we've changed the table
if (rowIndex == -1) {
if (current.hasClass(HEADER_CLASS)) {
var headerRows = [];
var columns = lockedColumns(this.columns);
mapColumnToCellRows([columns[columns.length - 1]], childColumnsCells(rows.eq(0).children().last()), headerRows, 0, 0);
if (headerRows[originalIndex]) {
return headerRows[originalIndex][0];
}
return current;
}
//current is in filter row
if (current.parent().hasClass("k-filter-row")) {
return rows.last().children(DATA_CELL).last();
}
//get the same row index in the new table
return rows.eq(originalIndex).children(DATA_CELL).last();
}
}
cells = current.prevAll(DATA_CELL + ",[hidden]");
let cellToFocus = this._findVisibleCell(cells.first());
if (cellToFocus.is(".k-group-cell")) {
return cellToFocus.next(DATA_CELL);
}
return cellToFocus;
},
_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;
},
_findVisibleCell: function($cell) {
var col = $cell.index();
var row = $cell.closest('tr').index();
var $newFocus;
if ($cell.is('[hidden]')) {
$newFocus = $cell.prevAll(':not([hidden])').first();
var hiddenCount = $cell.prevUntil(':not([hidden])', '[hidden]').length;
if (!$newFocus.attr('colspan') || ($newFocus.attr('colspan') > 1 && $newFocus.attr('colspan') <= hiddenCount + 1)) {
$newFocus = $cell.prevAll('[hidden]').last();
if ($newFocus.length === 0) {
return $cell.closest('tr').prevAll().find(`td:nth-of-type(${col + 1}):visible`).last();
}
while (!$newFocus.attr('rowspan') && !($newFocus.attr('rowspan') > 1 && $newFocus.attr('rowspan') != row - $newFocus.closest('tr').index()) && Math.abs($newFocus.index() - col) != $newFocus.attr('colspan')) {
$newFocus = $newFocus.closest('tr').prevAll().find('td, th').eq(col).first();
if ($newFocus.length === 0) {
$newFocus = $cell;
break;
}
}
}
} else {
$newFocus = $cell;
}
return $newFocus;
},
_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);
//current is in the header, but not at the last level of multi-level columns
if (index || current.hasClass(HEADER_CLASS)) {
cells = parentColumnsCells(current);
return cells.eq(cells.length - 2);
}
//check this out
index = Math.max(row.children(DATA_CELL_HIDDENINCLUDED).index(current), this._lastCellIndex || 0);
//if current is inside filter row
if (row.hasClass("k-filter-row")) {
let offset = rows.last().children(".k-group-cell").length;
return leafDataCells(container).filter(isCellVisible).eq(Math.max(0, index - offset));
}
//move up to header container
if (rowIndex == -1) {
if (this._hasVirtualColumns()) {
index = this._virtualCellIndex;
}
//is there filter row in the header container
row = container.find("tr.k-filter-row:visible");
if (!row[0]) {
// in hierarchical grid we need to correct the index
// since the k-hierarchy cell is navigatable
if ((this._hasDetails() || current.parent().find('.k-hierarchy-cell').length) && index) {
index--;
}
let offset = 0;
if (current.parent().is(".k-table-group-row")) {
offset = rows.last().children(".k-group-cell").length;
}
return leafDataCells(container).eq(Math.max(0, index - offset));
} else {
if (this._hasDetails()) {
index--;
}
}
} else {
row = rowIndex === 0 ? $() : rows.eq(rowIndex - 1);
}
cells = row.children(DATA_CELL_HIDDENINCLUDED);
if (cells.length > index) {
let nextCell = cells.eq(index);
if (nextCell.is(".k-group-cell")) {
nextCell = nextCell.nextAll("td").not(".k-group-cell").not(":hidden").first();
}
return this._findVisibleCell(nextCell);
}
return cells.eq(0);
},
_nextVerticalCell: function(container, current) {
var cells;
var originalRow;
var row = originalRow = 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 virtualScroll = this.virtualScroll || {};
var colspan;
//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(HEADER_CLASS)) {
return childColumnsCells(current).eq(1);
}
index = index ? parseInt(index, 10) : row.children(DATA_CELL_HIDDENINCLUDED).index(current);
index = Math.max(index, this._lastCellIndex || 0);
//move down to data container
if (rowIndex == -1) {
row = rows.eq(0);
if (virtualScroll.columns) {
colspan = parseInt(row.children().first().attr("colspan"), 10);
index = this._virtualCellIndex - (colspan > 1 ? colspan : 0);
}
// in hierarchical grid we need to correct the index
// since the k-hierarchy cell is navigatable
if (this._hasDetails() || row.find('.k-hierarchy-cell').length) {
index++;
}
if (row.hasClass("k-table-group-row")) {
index += originalRow.children(".k-group-cell").length;
}
} else {
row = rows.eq(rowIndex + current[0].rowSpan);
}
cells = row.children(".k-group-cell," + DATA_CELL_HIDDENINCLUDED);
let cellToFocus = cells.eq(0);
if (cells.length > index) {
cellToFocus = cells.eq(index);
}
if (cellToFocus.is(".k-group-cell")) {
cellToFocus = cellToFocus.nextAll("td").not(".k-group-cell").not(":hidden").first();
}
return cellToFocus;
},
_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");
},
_horizontalContainer: function(container, right) {
var length = this._navigatableTables.length;
if (length <= 2) {
return container;
}
var table = container.parent();
var index = inArray(table[0], this._navigatableTables);
index += right ? 1 : -1;
if (right && (index == 2 || index == length)) {
return container;
}
if (!right && (index == 1 || index < 0)) {
return container;
}
return this._navigatableTables.eq(index).find("thead, tbody");
},
_tabNext: function(current, currentTable, back) {
var switchRow = true;
var next = back ? current.prevAll(DATA_CELL).first() : current.nextAll(":visible").first();
if (!next.length) {
next = current.parent();
if (this.lockedTable) {
switchRow = (back && currentTable == this.lockedTable[0]) || (!back && currentTable == this.table[0]);
next = this._relatedRow(next);
}
if (switchRow) {
if (this._hasVirtualColumns()) {
return current;
}
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();
}
}
return next;
},
_handleEditing: function(current, next, table) {
var that = this,
active = $(activeElement()),
mode = that._editMode(),
isIE = browser.msie,
editContainer = that._editContainer,
focusable,
editable = that.options.editable && that.options.editable.update !== false,
isEdited;
table = $(table);
if (mode == "incell") {
isEdited = current.hasClass("k-edit-cell");
} else {
isEdited = current.parent().hasClass("k-grid-edit-row");
}
if (that.editable) {
if ($.contains(editContainer[0], active[0])) {
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.editable) {
focusTable(that.table);
return;
}
if (that.editable.end()) {
if (mode == "incell") {
that.closeCell();
} else {
that.saveRow();
isEdited = true;
}
} else {
if (mode == "incell") {
that._setCurrent(editContainer);
} else {
that._setCurrent(editContainer.children().filter(DATA_CELL).first());
}
focusable = editContainer.find(":kendoFocusable").first()[0];
if (focusable) {
focusable.focus();
}
return;
}
}
if (next) {
that._setCurrent(next);
}
focusTable(that.table, true);
if (!editable) {
return;
}
if ((!isEdited && !next) || next) {
if (mode === INCELL) {
if (!$(that.current()).hasClass(HIERARCHY_CELL_CLASS)) {
that.editCell(that.current());
}
} else {
that.editRow(that.current().parent());
}
}
},
_wrapper: function() {
var that = this,
table = that.table,
height = that.options.height,
width = that.options.width,
wrapper = that.element;
if (!wrapper.is(DIV)) {
wrapper = wrapper.wrap("<div/>").parent();
}
that.wrapper = wrapper.addClass("k-grid " + kendo.getValidCssClass("k-grid-", "size", that.options.size));
if (height) {
that.wrapper.css(HEIGHT, height);
table.css(HEIGHT, AUTO);
}
if (width) {
that.wrapper.css(WIDTH, width);
}
that._initMobile();
},
_initContextMenu: function() {
var that = this,
options = that.options,
groupsContextMenu = isPlainObject(options.contextMenu) && isArray(options.contextMenu.groups) ? { items: options.contextMenu.groups } : { items: defaultGroupsContextMenu },
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);
if (that.groupable) {
groupsContextMenu = extend({}, {
showOn: "click",
target: that.groupable.groupContainer,
filter: ".k-groupable-context-menu",
messages: options.messages,
action: that._action.bind(that),
states: that._buildStates()
}, mainOptions, groupsContextMenu);
}
that.tbodyContextMenu = new ui.grid.ContextMenu("<ul></ul>", tbodyContextMenu);
that.theadContextMenu = new ui.grid.ContextMenu("<ul></ul>", theadContextMenu);
that.groupsContextMenu = !!that.groupable && new ui.grid.ContextMenu("<ul></ul>", groupsContextMenu);
},
_buildStates: function() {
var that = this;
return {
isEditable: that.options.editable,
isSelectable: that.options.selectable,
isSortable: that.options.sortable,
isRowReorderable: isPlainObject(that.options.reorderable) ? that.options.reorderable.rows : that.options.reorderable,
isGroupable: that.options.groupable,
allowPaste: that.options.allowPaste,
alwaysDisabled: false,
hasSelection: () => (this.select() ? this.select().length > 0 : false),
isSorted: () => !(this.dataSource.sort() ? this.dataSource.sort().length > 0 : false),
canMoveGroupPrev: (target) => {
var group = $(target).closest(".k-chip");
return group.index() > 0;
},
canMoveGroupNext: (target) => {
var length = $(target).closest(".k-chip-list").children().length - 1;
var group = $(target).closest(".k-chip");
return group.index() < length;
}
};
},
_action: function(args) {
var commandName = args.command,
commandOptions = extend({ grid: this }, args.options),
command = new ui.grid.commands[commandName](commandOptions);
return command.exec();
},
_initMobile: function() {
var options = this.options;
var that = this;
this._isMobile = that.options.adaptiveMode !== 'auto' && (options.mobile === true && kendo.support.mobileOS) ||
options.mobile === "phone" ||
options.mobile === "tablet";
if (this._isMobile) {
var html = this.wrapper.addClass("k-grid-mobile").wrap(
'<div data-' + kendo.ns + 'stretch="true" data-' + kendo.ns + 'role="view" ' +
'data-' + kendo.ns + 'init-widgets="false"></div>'
)
.parent();
this.pane = this._createPane(html);
this.view = this.pane.view();
if (options.height) {
this.pane.element.parent().css(HEIGHT, options.height);
} else {
this.pane.element.parent().css(HEIGHT, this.wrapper[0].style.height);
}
this._editAnimation = "slide";
// Grid transitions should not propagate to the view
that.wrapper.on("transitionend" + NS, function(e) {
e.stopPropagation();
});
that.wrapper.on("contextmenu" + NS, "th a", function(e) {
e.preventDefault();
return false;
});
this.view.bind("showStart", function() {
if (that._isLocked()) {
that._updateTablesWidth();
that._applyLockedContainersWidth();
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
that._syncLockedFooterHeight();
}
});
}
},
_createPane: function(html) {
var pane = kendo.Pane.wrap(html, {
viewEngine: {
viewOptions: {
renderOnInit: true,
wrap: false,
wrapInSections: true,
detachOnHide: false,
detachOnDestroy: false
}
}
});
return pane;
},
_initLoader: function(options) {
var that = this,
defaultOptions = {
size: 'medium',
messages: { exporting: 'Exporting...' }
};
defaultOptions = $.extend({}, defaultOptions, options);
const loader = $("<div></div>").kendoLoader(defaultOptions).data("kendoLoader");
that.loader = loader;
that._loaderContainer = loaderContainer.useLoaderContainer.bind(that);
},
_tbody: function() {
var that = this,
table = that.table,
tbody;
tbody = table.find(">tbody");
if (!tbody.length) {
tbody = $("<tbody/>").appendTo(table);
}
tbody.addClass('k-table-tbody');
that.tbody = tbody;
},
_scrollable: function() {
var that = this,
header,
table,
options = that.options,
scrollable = options.scrollable,
hasVirtualScroll = scrollable !== true && scrollable.virtual,
virtualScroll = hasVirtualScroll ? parseVirtualSettings(scrollable.virtual) : null,
scrollbar = !kendo.support.kineticScrollNeeded || (virtualScroll && virtualScroll.rows) ? kendo.support.scrollbar() : 0,
headerWrap;
if (scrollable) {
header = that.wrapper.children(".k-grid-header");
if (!header[0]) {
header = $('<div class="k-grid-header" />').insertBefore(that.table);
}
// workaround for IE issue where scroll is not raised if container is same width as the scrollbar
header.css((isRtl ? "padding-left" : "padding-right"), scrollable.virtual ? scrollbar + 1 : scrollbar);
table = $('<table role="none" class="k-grid-header-table k-table"/>');
table.addClass(kendo.getValidCssClass("k-table-", "size", options.size));
table.width(that.table[0].style.width);
table.append(that.thead);
header.empty().append($('<div class="k-grid-header-wrap k-auto-scrollable" />').append(table));
that.content = that.table.parent();
that.virtualScroll = virtualScroll;
if (that.content.is(".k-virtual-scrollable-wrap, " + DOT + classNames.scrollContainer)) {
that.content = that.content.parent();
}
if (!that.content.is(".k-grid-content, .k-virtual-scrollable-wrap")) {
that.content = that.table.wrap('<div class="k-grid-content k-auto-scrollable" />').parent();
}
if (!that.content.parent().hasClass("k-grid-container")) {
that.content.wrap("<div class='k-grid-container' />").parent();
}
if (virtualScroll && virtualScroll.rows && !that.virtualScrollable) {
that._createVirtualScrollable();
}
if (virtualScroll && virtualScroll.columns) {
that.table.add(that.thead.parent()).css({
width: sumWidths(visibleLeafColumns(visibleNonLockedColumns(that.columns)))
});
}
headerWrap = header.children(".k-grid-header-wrap");
that.scrollables = headerWrap.add(that.content);
// the footer may exists if rendered from the server
var footer = that.wrapper.find(".k-grid-footer");
if (footer.length) {
that.scrollables = that.scrollables.add(footer.children(".k-grid-footer-wrap"));
}
headerWrap.off("scroll" + NS).on("scroll" + NS, function(e) {
if (that._scrollLeft !== this.scrollLeft) {
kendo.scrollLeft(that.scrollables.not(e.currentTarget), this.scrollLeft);
}
});
if (virtualScroll && virtualScroll.rows) {
that.content.find(">.k-virtual-scrollable-wrap").off("scroll" + NS).on("scroll" + NS, function() {
var isScrollingLeft = this.scrollLeft != that._scrollLeft;
that._scrollLeft = this.scrollLeft;
kendo.scrollLeft(that.scrollables, this.scrollLeft);
if (that.lockedContent) {
that.lockedContent[0].scrollTop = this.scrollTop;
}
if (virtualScroll.columns && isScrollingLeft) {
that.refresh();
}
});
} else {
var endless = scrollable.endless;
var originalPageSize = that.dataSource.options.pageSize;
if (endless) {
that._endlessPageSize = originalPageSize;
}
that.content.off("scroll" + NS).on("scroll" + NS, function(e) {
var isScrollingLeft = this.scrollLeft != that._scrollLeft;
that._scrollLeft = this.scrollLeft;
kendo.scrollLeft(that.scrollables.not(e.currentTarget), that._scrollLeft);
if (that.lockedContent && e.currentTarget == that.content[0]) {
that.lockedContent[0].scrollTop = this.scrollTop;
}
if (endless) {
if ((this.scrollTop + this.clientHeight - this.scrollHeight >= -10) &&
!that._endlessFetchInProgress &&
that._endlessPageSize < that.dataSource.total()) {
that._skipRerenderItemsCount = that._endlessPageSize;
that._endlessPageSize = that._endlessPageSize + originalPageSize;
that.dataSource.options.endless = true;
that._endlessFetchInProgress = true;
that.dataSource.pageSize(that._endlessPageSize);
}
}
if (virtualScroll && virtualScroll.columns && isScrollingLeft) {
that._virtualColScroll = true;
that._cacheEditableState();
that.refresh();
that._restoreEditableState();
that._virtualColScroll = false;
}
if (that.rowResizer) {
that.rowResizer.css("left", e.currentTarget.scrollLeft + "px");
}
});
var touchScroller = that.content.data("kendoTouchScroller");
if (touchScroller) {
touchScroller.destroy();
}
touchScroller = kendo.touchScroller(that.content);
if (touchScroller && touchScroller.movable) {
that.touchScroller = touchScroller;
touchScroller.movable.bind("change", function(e) {
kendo.scrollLeft(that.scrollables, -e.sender.x);
if (that.lockedContent) {
that.lockedContent.scrollTop(-e.sender.y);
}
});
that.one(DATABOUND, function(e) {
e.sender.wrapper.addClass("k-grid-backface");
});
}
}
}
},
_createVirtualScrollable: function() {
var that = this;
if (that.virtualScrollable) {
that.virtualScrollable.destroy();
}
that.virtualScrollable = new VirtualScrollable(that.content, {
dataSource: that.dataSource,
itemHeight: function() { return that._averageRowHeight(); },
page: function() {
that._restoreEditableState();
},
scroll: function() {
that._focusEditable();
},
loadStart: function() {
that._progress(true);
},
loadEnd: function() {
that._progress(false);
}
});
that.virtualScrollable.bind(PAGING, that._onVirtualPaging.bind(that));
},
_onVirtualPaging: function() {
var that = this;
that._cacheEditableState();
if (that._isVirtualIncellEditable()) {
that._shouldClearEditableState = false;
that.closeCell();
that._shouldClearEditableState = true;
}
},
_isVirtualEditable: function() {
return this._isVirtualIncellEditable() || this._isVirtualInlineEditable() || this._isVirtualPopupEditable();
},
_isVirtualInlineEditable: function() {
return (this.virtualScrollable) && this._editMode() === INLINE;
},
_isVirtualIncellEditable: function() {
return (this.virtualScrollable) && this._editMode() === INCELL;
},
_isVirtualPopupEditable: function() {
return this.virtualScrollable && this._editMode() === "popup";
},
_hasVirtualColumns: function() {
return (this.virtualScroll || {}).columns ? true : false;
},
_hasVirtualRows: function() {
return (this.virtualScroll || {}).rows ? true : false;
},
_scrollVirtualWrapper: function() {
var that = this;
var scrollable = that.virtualScrollable;
if (that._isVirtualInlineEditable() || that._isVirtualIncellEditable()) {
if (scrollable._isScrolledToBottom()) {
scrollable._scrollWrapperToBottom();
} else if (scrollable._isScrolledToTop()) {
scrollable._scrollWrapperToTop();
}
}
},
_scrollVirtualWrapperOnColumnResize: function() {
var virtualScrollable = this.virtualScrollable;
if (virtualScrollable) {
virtualScrollable._scrollWrapperOnColumnResize();
}
},
_restoreEditableState: function() {
var that = this;
var editableState = that._editableState || {};
var editedModel = editableState.model;
var dataSource = that.dataSource;
var inlineMode = that._isVirtualInlineEditable();
var incellMode = that._isVirtualIncellEditable();
var virtualColumns = that._hasVirtualColumns();
var row;
var cell;
if ((inlineMode || incellMode || virtualColumns) && editedModel && dataSource._getByUid(editedModel.uid, dataSource.view())) {
if (that._editMode() === INLINE) {
that._shouldClearEditableState = false;
that.editRow(editedModel);
if (!virtualColumns) {
that._focusEditable();
}
} else if (that._editMode() === INCELL) {
row = that.tbody.children(attrEquals(UNIQUE_ID, editedModel.uid));
cell = $(row).children(attrEquals(FIELD, editableState.field));
if (cell[0]) {
that._shouldClearEditableState = false;
that.editCell(cell);
if (!virtualColumns) {
that._focusEditable();
}
}
}
}
that._shouldClearEditableState = true;
},
_focusEditable: function() {
var that = this;
var editedField = (that._editableState || {}).field;
var editContainer = that._editContainer;
if (editContainer && editContainer.length && !contains(editContainer[0], activeElement()) && that._canFocusEditable()) {
if (that._isVirtualInlineEditable() || that._hasVirtualColumns()) {
editContainer.find(attrEquals(CONTAINER_FOR, editedField)).find(FOCUSABLE).eq(0).trigger("focus");
} else if (that._isVirtualIncellEditable() || that._hasVirtualColumns()) {
editContainer.find(FOCUSABLE).eq(0).trigger("focus");
}
}
},
_canFocusEditable: function() {
var that = this;
var result = ((that._isVirtualIncellEditable() || that._isVirtualInlineEditable() || that._hasVirtualColumns()) &&
(isElementVisibleInWrapper((that.virtualScrollable || {}).wrapper, that._editContainer) || isElementVisibleInWrapper(that.content, that._editContainer)));
return result;
},
_cacheEditableState: function() {
var that = this;
var editContainer = that._editContainer;
var editedModel = editContainer ? that._modelForContainer(editContainer) : null;
var inlineMode = that._isVirtualInlineEditable();
var incellMode = that._isVirtualIncellEditable();
var virtualColumns = that._hasVirtualColumns();
var active;
var widget;
var value;
if ((inlineMode || incellMode || virtualColumns) && editedModel) {
that._clearEditableState();
active = $(activeElement());
if (editContainer && active[0] && contains(editContainer[0], active[0])) {
//change event is not fired if the editable container is scrolled
//out of the virtual view with the mousewheel right after editing
active.change();
widget = kendo.widgetInstance(active, kendo.ui);
if (widget && isFunction(widget.value) && active.is(INPUT)) {
value = active.val();
if (active.is("[type='checkbox'")) {
value = active.is(":checked");
}
widget.value(value);
widget.trigger(CHANGE);
}
}
if (that._editMode() === INLINE) {
that._editableState = {
model: editedModel,
field: active.closest("[" + kendo.attr(CONTAINER_FOR) + "]").attr(kendo.attr(CONTAINER_FOR))
};
} else if (that._editMode() === INCELL) {
that._editableState = {
model: editedModel,
field: editContainer.attr(kendo.attr(FIELD))
};
}
}
},
_clearSortClasses: function() {
var that = this,
content = that.content || that.table,
lockedContent = that.lockedContent;
if (content) {
content.find(COLGROUP).removeClass(SORTED_CLASS);
}
if (lockedContent) {
lockedContent.find(COLGROUP).removeClass(SORTED_CLASS);
}
},
_clearEditableState: function() {
var that = this;
if (that.virtualScrollable || (that.virtualScroll && that._hasVirtualColumns())) {
that._editableState = null;
}
},
_destroyVirtualScrollable: function() {
var that = this;
that._clearEditableState();
if (that.virtualScrollable && that.virtualScrollable.element) {
that.virtualScrollable.destroy();
}
that.virtualScrollable = null;
},
_destroyRowResizing: function() {
if (this.rowResizing) {
this.rowResizing.destroy();
this.rowResizing = null;
}
if (this.rowResizer) {
this._detachRowResizerEvents();
this.rowResizer.off(DUBLECLICK + NS);
this.rowResizer = null;
this._clearCachedRowsHeight();
}
},
_renderNoRecordsContent: function() {
var that = this;
if (that.options.noRecords) {
var noRecordsElement = that.table.parent().children('.' + NORECORDSCLASS);
if (noRecordsElement.length) {
noRecordsElement.remove();
}
if (!that.dataSource || !that.dataSource.view().length) {
noRecordsElement = $(that.noRecordsTemplate({ grid: that }));
kendo.applyStylesFromKendoAttributes(noRecordsElement, ["margin", "position"]);
noRecordsElement.insertAfter(that.table);
}
}
},
_setContentWidth: function(scrollLeft) {
var that = this,
hiddenDivClass = 'k-grid-content-expander',
hiddenDiv = '<div class="' + hiddenDivClass + '"></div>',
resizable = that.resizable,
expander;
if (that.options.scrollable && that.wrapper.is(":visible")) {
expander = that.table.parent().children('.' + hiddenDivClass);
that._setContentWidthHandler = that._setContentWidth.bind(that);
if (!that.dataSource || !that.dataSource.view().length) {
if (!expander[0]) {
expander = $(hiddenDiv).appendTo(that.table.parent());
if (resizable) {
resizable.bind("resize", that._setContentWidthHandler);
}
}
if (that.thead) {
expander.width(that.thead.width());
if (!isNaN(parseFloat(scrollLeft, 10))) {
kendo.scrollLeft(that.content, scrollLeft);
}
}
} else if (expander[0]) {
expander.remove();
if (resizable) {
resizable.unbind("resize", that._setContentWidthHandler);
}
}
that._applyLockedContainersWidth(true);
that._syncLockedContentHeight();
// workaround IE does not show vertical scrollbar for elements without width
if (that.lockedHeader && that.table[0].clientWidth === 0) {
that.table[0].style.width = "1px";
}
}
},
_applyLockedContainersWidth: function(calculateGroupWidth) {
if (this.options.scrollable && this.lockedHeader) {
let headerTable = this.thead.parent(),
headerWrap = headerTable.parent(),
contentWidth = this.wrapper[0].clientWidth,
groups = this._groups(),
scrollbar = kendo.support.scrollbar(),
cols = this.lockedHeader.find(">table>colgroup>col:not(.k-group-col, .k-hierarchy-col)"),
nonLockedCols = headerTable.find(">colgroup>col:not(.k-group-col, .k-hierarchy-col)"),
width = columnsWidth(cols),
nonLockedColsWidth = columnsWidth(nonLockedCols),
footerWrap;
if (groups > 0 && calculateGroupWidth) {
width += outerWidth(this.lockedHeader.find(".k-group-cell").first()) * groups;
}
if (width >= contentWidth) {
width = contentWidth - 3 * scrollbar;
}
this.lockedHeader
.add(this.lockedContent)
.width(width);
headerWrap[0].style.width = headerWrap.parent().width() - width - 2 + PX;
headerTable.add(this.table).width(nonLockedColsWidth);
//https://github.com/telerik/kendo-ui-core/issues/377
if (this.virtualScrollable && !isIE11) {
contentWidth -= scrollbar;
}
this.content[0].style.width = contentWidth - width - 1 + PX;
if (this.lockedFooter && this.lockedFooter.length) {
this.lockedFooter.width(width);
footerWrap = this.footer.find(".k-grid-footer-wrap");
footerWrap[0].style.width = headerWrap[0].clientWidth + PX;
footerWrap.children().first().width(nonLockedColsWidth);
}
}
},
_setContentHeight: function() {
var that = this,
options = that.options,
height,
header = that.wrapper.children(".k-grid-header"),
scrollbar = kendo.support.scrollbar();
var scrollableHeight = (options.scrollable || {}).height;
if (options.scrollable && that.wrapper.is(":visible")) {
if (scrollableHeight && that.content[0].style.height === "") {
// fallback to client-side setting as ASP.NET MVC Core wrapper does not provide server rendering of the content
that.content[0].style.height = scrollableHeight;
}
height = that.wrapper.innerHeight();
height -= outerHeight(header);
if (that.pager && that.pager.element.is(":visible")) {
height -= outerHeight(that.pager.element);
}
if (options.groupable) {
height -= outerHeight(that.wrapper.children(".k-grouping-header"));
}
if (options.toolbar) {
height -= outerHeight(that.wrapper.children(".k-grid-toolbar"));
}
if (that.footerTemplate) {
height -= outerHeight(that.wrapper.children(".k-grid-footer"));
}
if (that.statusBar) {
height -= outerHeight(that.wrapper.children(".k-selection-aggregates"));
}
var isGridHeightSet = function(el) {
var initialHeight, newHeight;
if (el[0].style.height) {
return true;
} else {
initialHeight = el.height();
}
el.height(AUTO);
newHeight = el.height();
if (initialHeight != newHeight) {
el.height("");
return true;
}
el.height("");
return false;
};
if (isGridHeightSet(that.wrapper)) { // set content height only if needed
if (height > scrollbar * 2) { // do not set height if proper scrollbar cannot be displayed
if (that.lockedContent) {
scrollbar = that.table[0].offsetWidth > that.table.parent()[0].clientWidth ? scrollbar : 0;
that.lockedContent.height(height - scrollbar);
}
that.content.height(height);
} else {
that.content.height(scrollbar * 2 + 1);
}
}
}
},
_averageRowHeight: function() {
var that = this,
itemsCount = that._items(that.tbody, true).length,
rowHeight = that._rowHeight;
if (itemsCount === 0) {
return rowHeight;
}
if (!that._rowHeight) {
that._rowHeight = rowHeight = outerHeight(that.table) / itemsCount;
that._sum = rowHeight;
that._measures = 1;
}
var currentRowHeight = outerHeight(that.table) / itemsCount;
if (rowHeight !== currentRowHeight) {
that._measures++;
that._sum += currentRowHeight;
that._rowHeight = that._sum / that._measures;
}
return rowHeight;
},
_dataSource: function() {
var that = this,
options = that.options,
pageable,
dataSource = options.dataSource;
dataSource = isArray(dataSource) ? { data: dataSource } : dataSource;
if (isPlainObject(dataSource)) {
extend(dataSource, { table: that.table, fields: that.columns });
pageable = options.pageable;
if (isPlainObject(pageable) && pageable.pageSize !== undefined$1) {
dataSource.pageSize = pageable.pageSize;
}
}
if (that.dataSource && that._refreshHandler) {
that.dataSource.unbind(CHANGE, that._refreshHandler)
.unbind(PROGRESS, that._progressHandler)
.unbind(REQUESTEND, that._requestEndHandler)
.unbind(ERROR, that._errorHandler)
.unbind(SORT, that._sortHandler);
} else {
that._refreshHandler = that.refresh.bind(that);
that._progressHandler = that._requestStart.bind(that);
that._requestEndHandler = that._requestEnd.bind(that);
that._errorHandler = that._error.bind(that);
that._sortHandler = that._clearSortClasses.bind(that);
}
that.dataSource = DataSource.create(dataSource)
.bind(CHANGE, that._refreshHandler)
.bind(PROGRESS, that._progressHandler)
.bind(REQUESTEND, that._requestEndHandler)
.bind(ERROR, that._errorHandler)
.bind(SORT, that._sortHandler);
},
_error: function() {
this._progress(false);
this._requestInProgress = false;
},
_requestStart: function() {
this._progress(true);
this._requestInProgress = true;
},
_requestEnd: function() {
this._requestInProgress = false;
},
_modelChange: function(e) {
var that = this,
tbody = that.tbody,
model = e.model,
row = that.tbody.find("tr[" + kendo.attr("uid") + "=" + model.uid + "]"),
relatedRow,
cell,
column,
isAlt = row.hasClass("k-table-alt-row"),
tmp,
idx = that._items(tbody).index(row),
isLocked = that.lockedContent,
selectable,
selectableRow,
childCells,
originalCells,
length;
if (isLocked) {
relatedRow = that._relatedRow(row);
}
if (row.add(relatedRow).children(".k-edit-cell").length && !that.options.rowTemplate) {
row.add(relatedRow).children(":not(.k-group-cell,.k-hierarchy-cell)").each(function() {
cell = $(this);
column = leafColumns(that.columns)[that._calculateColumnIndex(cell)];
if (column.field === e.field) {
if (!cell.hasClass("k-edit-cell")) {
that._displayCell(cell, column, model);
} else {
cell.addClass("k-dirty-cell");
}
}
});
} else if (!row.hasClass("k-grid-edit-row")) {
selectableRow = $().add(row);
if (isLocked) {
tmp = (isAlt ? that.lockedAltRowTemplate : that.lockedRowTemplate)(model);
selectableRow = selectableRow.add(relatedRow);
relatedRow.replaceWith(tmp);
}
tmp = (isAlt ? that.altRowTemplate : that.rowTemplate)(model);
let tmpResult = $(tmp);
kendo.applyStylesFromKendoAttributes(tmpResult, ["display"]);
row.replaceWith(tmpResult);
tmp = that._items(tbody).eq(idx);
if (isLocked) {
row = row.add(relatedRow);
relatedRow = that._relatedRow(tmp)[0];
adjustRowHeight(tmp[0], relatedRow);
tmp = tmp.add(relatedRow);
}
selectable = that.options.selectable;
if ((selectable || that._checkBoxSelection) && row.hasClass(SELECTED)) {
that.select(tmp);
}
originalCells = selectableRow.children(":not(.k-group-cell,.k-hierarchy-cell)");
childCells = tmp.children(":not(.k-group-cell,.k-hierarchy-cell)");
for (idx = 0, length = that.columns.length; idx < length; idx++) {
column = that.columns[idx];
cell = childCells.eq(idx);
if (selectable && originalCells.eq(idx).hasClass(SELECTED)) {
cell.addClass(SELECTED);
}
}
that.trigger("itemChange", { item: tmp, data: model, ns: ui });
}
},
_pageable: function() {
var that = this,
pagerWrap,
pageable = that.options.pageable,
size = that.options.size,
navigatable = that.options.navigatable;
if (pageable) {
pagerWrap = that.wrapper.children("div.k-grid-pager");
if (!pagerWrap.length) {
pagerWrap = $('<div class="k-pager k-grid-pager"/>');
}
if (pageable.position === "top") {
pagerWrap.prependTo(that.wrapper).addClass("k-grid-pager-top");
} else {
pagerWrap.appendTo(that.wrapper);
}
if (that.pager) {
that.pager.destroy();
}
let adaptive = that.options.adaptiveMode;
if (that.options.adaptiveMode === "auto") {
if (pageable && typeof pageable === "object" && pageable.adaptiveMode) {
adaptive = pageable.adaptiveMode;
}
}
if (typeof pageable === "object" && pageable instanceof kendo.ui.Pager) {
that.pager = pageable;
} else {
if (that.dataSource._groupPaging) {
that.pager = new GroupsPager(pagerWrap, extend({}, pageable, { dataSource: that.dataSource, navigatable: navigatable, size: size, adaptiveMode: adaptive }));
} else {
that.pager = new kendo.ui.Pager(pagerWrap, extend({}, pageable, { dataSource: that.dataSource, navigatable: navigatable, size: size, adaptiveMode: adaptive }));
}
}
that.pager.bind("pageChange", function(e) {
if (that.trigger("page", { page: e.index })) {
e.preventDefault();
}
});
that._togglePagerVisibility();
}
},
_statusBar: function() {
var that = this,
options = that.options,
wrapper = that.wrapper,
statusBarTemplate = options.statusBarTemplate,
content = "";
if (statusBarTemplate) {
if (!that.statusBar) {
content += '<div class="k-selection-aggregates k-grid-selection-aggregates">';
content += statusBarTemplate({ aggregates: that._cellAggregates });
content += '</div>';
if (options.scrollable) {
that.statusBar = $(content).insertAfter(wrapper.find(DOT + "k-grid-container"));
} else {
that.statusBar = $(content).insertAfter(wrapper.find(DOT + "k-grid-table"));
}
} else {
that.statusBar.html(statusBarTemplate({ aggregates: that._cellAggregates }));
}
}
},
_rerenderGroupFooterTemplate: function(model) {
const that = this;
const uid = model.uid;
const groupFooterTemplate = that.groupFooterTemplate;
const lockedGroupFooterTemplate = that.lockedGroupFooterTemplate;
const groupDataForRow = that._groupRows.find((grRow) => grRow.value === model[grRow.field]);
const isScrollable = that.options.scrollable;
let container = that.tbody;
if (isScrollable) {
container = that.wrapper.find(".k-grid-container");
}
if (!groupDataForRow) {
return;
}
const updateFooter = (row, template) => {
const footer = row.nextAll(".k-group-footer").first();
if (footer && footer.length) {
const html = template(that._groupData(groupDataForRow, false, false));
footer.replaceWith(html);
}
};
const rows = container.find("tr[" + kendo.attr("uid") + "=" + uid + "]");
if (rows.length > 1) {
const lockedRow = rows.first();
updateFooter(lockedRow, lockedGroupFooterTemplate);
}
const row = rows.last();
updateFooter(row, groupFooterTemplate);
},
_footer: function() {
var that = this,
aggregates = that.dataSource.aggregates(),
html = "",
footerTemplate = that.footerTemplate,
options = that.options,
footerWrap,
footer = that.footer || that.wrapper.find(".k-grid-footer");
if (footerTemplate) {
html = $(that._wrapFooter(footerTemplate(aggregates)));
kendo.applyStylesFromKendoAttributes(html, ["display", "left", "right"]);
if (footer.length) {
var tmp = html;
footer.replaceWith(tmp);
footer = that.footer = tmp;
} else {
if (options.scrollable) {
if (that.statusBar) {
that.footer = html.insertBefore(that.statusBar);
} else if (options.pageable && options.pageable.position !== "top") {
that.footer = html.insertBefore(that.wrapper.children("div.k-grid-pager"));
} else {
that.footer = html.appendTo(that.wrapper);
}
footer = that.footer;
} else {
footer = that.footer = html.insertAfter(that.tbody);
}
}
} else if (footer && !that.footer) {
that.footer = footer;
}
if (footer.length) {
if (options.scrollable) {
footerWrap = footer.attr(TABINDEX, -1).children(".k-grid-footer-wrap");
that.scrollables = $(
that.scrollables
.filter(function() { return !$(this).is(".k-grid-footer-wrap"); })
.toArray()
).add(footerWrap);
}
if (that._footerWidth) {
footer.find("table").css('width', that._footerWidth);
}
if (footerWrap) {
var offset = kendo.scrollLeft(that.content);
if (options.scrollable !== true && that.virtualScroll && that.virtualScroll.rows) {
offset = kendo.scrollLeft(that.wrapper.find('.k-virtual-scrollable-wrap'));
}
kendo.scrollLeft(footerWrap, offset);
}
}
if (that.lockedContent) {
that._appendLockedColumnFooter();
that._applyLockedContainersWidth();
that._syncLockedFooterHeight();
}
},
_wrapFooter: function(footerRow) {
var that = this,
html = "",
table,
scrollbar = !kendo.support.mobileOS ? kendo.support.scrollbar() : 0;
if (that.options.scrollable) {
html = $('<div class="k-grid-footer"><div class="k-grid-footer-wrap"><table class="k-table k-grid-footer-table"><tfoot class="k-table-tfoot">' + footerRow + '</tfoot></table></div></div>');
table = html.find("table");
table.addClass(kendo.getValidCssClass("k-table-", "size", that.options.size));
that._appendCols(table);
html.css((isRtl ? "padding-left" : "padding-right"), scrollbar); // Update inner fix.
return html;
}
return '<tfoot class="k-grid-footer k-table-tfoot">' + footerRow + '</tfoot>';
},
_actionsheetFooterActionsTemplate: function(buttonsConfig) {
let buttonsHtml = "";
buttonsConfig.forEach(buttonOptions => {
const command = buttonOptions.command;
const text = buttonOptions.text;
buttonsHtml += kendo.html.renderButton(`<button data-command=${command}>${text}</button>`, buttonOptions);
});
return buttonsHtml;
},
_isAdaptive: function() {
const that = this;
return that.options.adaptiveMode === "auto" && (that.smallMQL.mediaQueryList.matches || that.mediumMQL.mediaQueryList.matches);
},
_toolPopup: function(cell) {
return cell.popup && cell.popup.wrapper;
},
_filterToolbarTool: function(cell) {
const that = this;
const columns = leafColumns(that.columns);
const options = that.options;
const clearFilterButton = (cell) => {
const clearFilterSelector = that._isAdaptive() ? "[ref-actionsheet-action-button]" : "[ref='clear-filter']";
return that._toolPopup(cell)?.find(clearFilterSelector);
};
const toolbarFilterOptions = that._toolbarOptionsForTool("filter");
function content({ isAdaptive }) {
let content = "";
for (let i = 0; i < columns.length; i++) {
const column = columns[i];
const filterable = options.filterable && column.filterable !== false;
if (!filterable || column.command) {
continue;
}
content += `<div class="k-columnmenu-item-wrapper">`;
content += `<div class="k-columnmenu-item-content k-columns-item" ref="filter" tabindex="0" data-field="${column.field}" data-index=${column.index || i || 0}></div>`;
content += `</div>`;
}
if ((!toolbarFilterOptions || toolbarFilterOptions.clearButton) && !isAdaptive) {
content += `<div class="k-actions k-actions-stretched k-actions-horizontal k-column-menu-footer">`;
content += kendo.html.renderButton(`<button ref="clear-filter">Clear all filters</button>`, { icon: "filter-clear" });
content += "</div>";
}
return content;
}
const menu = cell.data("kendoColumnMenu");
if (menu) {
menu.wrapper.off("click" + NS);
menu.element.off("click" + NS);
menu.destroy();
}
const filterable = options.filterable && that.options.columnMenu.filterable !== false ? extend(true, { pane: that.pane }, options.filterable) : false;
if (!filterable) {
return;
}
const menuOptions = {
dataSource: that.dataSource,
columns: false,
sortable: false,
filterable: filterable,
hideAutoSizeColumn: true,
owner: that,
adaptiveMode: that.options.adaptiveMode,
encodeTitles: that.options.encodeTitles,
componentType: "modern",
_actionsheet: {
actionButtons: defaultActionSheetFooterButtons.filter,
title: "Filter by",
closeButton: true,
ref: "filter-view",
},
closeCallback: function(e) {
e.removeClass(SELECTED);
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.find(".k-focus").removeClass("k-focus");
}
cell.element.focus();
},
init: function(e) {
cell.wrapper.attr("ref", "filter-tool");
if (!that._showAdaptiveView) {
for (var idx = 0, length = columns.length; idx < length; idx++) {
const column = columns[idx];
const field = column.field;
const filterable = options.filterable && column.filterable !== false;
if (!filterable) {
continue;
}
const element = cell.wrapper.find(`.k-columns-item[data-field="${field}"]`);
that._initFilterMenuForColumn(column, element);
}
}
},
contentTemplate: content,
filtering: function(e) {
if (that.trigger("filter", { filter: e.filter, field: e.field })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
}
};
cell = cell.kendoColumnMenu(menuOptions).data("kendoColumnMenu");
cell.element.bind("click" + NS, function(e) {
if (cell.popup && cell.popup._closing) {
return;
}
$(e.currentTarget).addClass(SELECTED);
clearFilterButton(cell)?.toggleClass("k-disabled", !cell.dataSource._filter);
});
that.unbind("filter");
that.bind("filter", function(e) {
const filters = cell.dataSource._filter;
const field = e.field;
let isRemoveFilter = !e.filter;
let condition;
const filteredFields = filters && filters.filters;
if (
isRemoveFilter
&& filteredFields
&& filteredFields.length
&& !filteredFields.find((descriptor) => (descriptor.filters && descriptor.filters.length ? descriptor.filters[0].field === field : descriptor.field === field))
) {
return;
}
const expansionPanel = cell.wrapper
.find(`.k-columns-item[data-field='${field}']`);
const headerElement = expansionPanel
?.closest(".k-expander")
?.find(".k-columnmenu-item");
if (filters && filters.filters.length) {
if (isRemoveFilter) {
condition = filteredFields.filter((descriptor) => descriptor.field !== field).length > 0;
} else {
condition = !isRemoveFilter;
}
} else if (!isRemoveFilter) {
condition = true;
}
if (expansionPanel.length) {
expansionPanel.data("kendoExpansionPanel").toggle(false);
}
clearFilterButton(cell)?.toggleClass("k-disabled", !condition);
that._toggleColumnMenuFilterIndicator(headerElement, !isRemoveFilter);
that._toggleBadge(cell.element, condition);
});
cell.bind("open", function() {
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.focus();
const clearFilterBtn = clearFilterButton(cell);
const filters = cell.dataSource._filter && cell.dataSource._filter.filters;
if (filters && filters.length) {
filters.forEach((descriptor) => {
const field = descriptor.field || descriptor.filters[0].field;
const expansionPanel = cell.wrapper
.find(`.k-columns-item[data-field='${field}']`);
const headerElement = expansionPanel
?.closest(".k-expander")
?.find(".k-columnmenu-item");
that._toggleColumnMenuFilterIndicator(headerElement, true);
});
}
if (clearFilterBtn.length) {
clearFilterBtn.off("mousedown" + NS);
clearFilterBtn.on("mousedown" + NS, function() {
that.dataSource.filter([]);
that._toggleBadge(cell.element, false);
cell.wrapper.find(".k-columnmenu-indicators").remove();
clearFilterBtn.toggleClass("k-disabled", true);
cell.popup.close();
});
}
}
});
},
_initFilterMenuForColumn: function(column, element) {
const that = this;
let filterable = that._hasFilterMenu();
let filterMenu;
if (element.length) {
filterMenu = element.data("kendoFilterMenu");
if (filterMenu) {
filterMenu.destroy();
}
filterMenu = element.data("kendoFilterMultiCheck");
if (filterMenu) {
filterMenu.destroy();
}
var columnFilterable = column.filterable;
var options = extend({},
filterable,
columnFilterable,
{
appendToElement: true,
componentType: "modern",
dataSource: that.dataSource,
values: column.values,
format: column.format,
title: column.title || column.field,
pane: that.pane,
adaptiveMode: that.options.adaptiveMode,
change: function(e) {
if (that.trigger("filter", { filter: e.filter, field: e.field })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
},
}
);
if (columnFilterable && columnFilterable.messages) {
options.messages = extend(true, {}, filterable.messages, columnFilterable.messages);
}
if (columnFilterable && columnFilterable.dataSource) {
options.forceUnique = false;
options.checkSource = columnFilterable.dataSource;
}
if (columnFilterable && columnFilterable.multi) {
return element.kendoFilterMultiCheck(options).data("kendoFilterMultiCheck");
} else {
return element.kendoFilterMenu(options).data("kendoFilterMenu");
}
}
},
_toolbarOptionsForTool: function(toolName) {
const that = this;
const options = that.options;
let toolbarItems = [];
if (Array.isArray(options.toolbar)) {
toolbarItems = options.toolbar;
} else if (options.toolbar && options.toolbar.items) {
toolbarItems = options.toolbar.items;
}
return extend({}, defaultCommands[toolName], toolbarItems.find((item) => item.name === toolName));
},
_groupToolbarTool: function(cell) {
const that = this;
const options = that.options;
const clearGroupButton = (cell) => {
const clearGroupSelector = that._isAdaptive() ? "[ref-actionsheet-action-button]:not('.k-button-solid-primary')" : "[ref='clear-group']";
return that._toolPopup(cell)?.find(clearGroupSelector);
};
let menu;
let menuOptions;
const groupable = (options.groupable && options.groupable.enabled !== false) || that.dataSource._groupPaging;
if (!groupable) {
return;
}
menu = cell.data("kendoColumnMenu");
if (menu) {
menu.wrapper.off("click" + NS);
menu.element.off("click" + NS);
menu.destroy();
}
const toolbarGroupOptions = that._toolbarOptionsForTool("group");
// Currently we want to distribute reordering throught the buttons as a default and only behaviour
// the user wont be able to set it throught the options by himself
toolbarGroupOptions.reorderButtons = true;
const indicator = ({ isAdaptive, isFirstItem, isLastItem }) => (
`<span class="k-group-menu-item-actions">
${toolbarGroupOptions.reorderButtons ?
`<span class="k-group-menu-item-action k-group-menu-item-up-action ${isFirstItem ? "k-disabled" : ""}" ${isFirstItem ? "aria-disabled=true" : "aria-disabled=false"}>
${kendo.ui.icon($('<span></span>'), { icon: "chevron-up", size: isAdaptive ? "large" : "medium" })}
</span>
<span class="k-group-menu-item-action k-group-menu-item-down-action ${isLastItem ? "k-disabled" : ""}" ${isLastItem ? "aria-disabled=true" : "aria-disabled=false"}>
${kendo.ui.icon($('<span></span>'), { icon: "chevron-down", size: isAdaptive ? "large" : "medium" })}
</span>`
:
`<span class="k-group-menu-item-action k-group-menu-item-drag-action">
${kendo.ui.icon($('<span></span>'), { icon: "handle-drag-dots", size: isAdaptive ? "large" : "medium" })}
</span>`}
</span>`);
const itemTemplate = (column, action, options) => {
const isAdaptive = that._isAdaptive();
return `<div class="k-group-menu-item" data-field="${column.field}" data-index="${(options && options.index) || column.index || "0"}" tabindex="0">
${(options && options.renderIndicator) ? indicator({ isAdaptive: isAdaptive, isFirstItem: options.isFirstItem, isLastItem: options.isLastItem }) : ""}
<span class="k-group-item-text">${column.title || column.field || ""}</span>
<span class="k-spacer"></span>
<span class="k-group-menu-item-actions">
<span class="k-group-menu-item-action ${action.actionClass}">
${kendo.ui.icon($('<span></span>'), { ...action, size: isAdaptive ? "large" : "medium" })}
</span>
</span>
</div>`;
};
const content = ({ columns }) => {
const isAdaptive = that._isAdaptive();
let content = `<div class="k-group-menu k-group-menu-md"><div class='k-group-menu-item-wrap'>`;
columns.forEach((column) => {
if (!isColumnGroupable(that, column) || column.command) {
return;
}
content += itemTemplate(column, { icon: "plus-circle", actionClass: "k-group-menu-item-add-action" });
});
content += `</div>`;
if ((!toolbarGroupOptions || toolbarGroupOptions.clearButton) && !isAdaptive) {
content += `<div class="k-actions k-actions-stretched k-actions-horizontal k-column-menu-footer">
${kendo.html.renderButton(`<button ref="clear-group">Clear grouping</button>`, { icon: "x" })}
</div>`;
}
content += `</div>`;
return content;
};
menuOptions = {
dataSource: that.dataSource,
columns: false,
sortable: false,
filterable: false,
hideAutoSizeColumn: false,
owner: that,
adaptiveMode: that.options.adaptiveMode,
encodeTitles: that.options.encodeTitles,
componentType: "modern",
_actionsheet: {
actionButtons: defaultActionSheetFooterButtons.group,
title: "Group by",
ref: "group-view",
closeButton: {
icon: "check",
themeColor: "primary",
},
},
init: function(e) {
const element = cell.wrapper.find(".k-group-menu");
element.attr("ref", "group-tool");
if (cell._showAdaptiveView) {
element.unwrap();
element.removeClass("k-group-menu-md").addClass("k-group-menu-lg");
} else {
cell.wrapper.removeClass("k-column-menu");
}
element.find(".k-group-menu-item").on("click" + NS, `.k-group-menu-item-remove-action, .k-group-menu-item-add-action`, function(e) {
that._groupItemClickHandler(e, cell, { itemTemplate, indicator });
});
that._syncGroupingTool(e, cell, that.dataSource.group(), { itemTemplate, indicator });
},
closeCallback: function(e) {
e.removeClass(SELECTED);
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.find(".k-focus").removeClass("k-focus");
}
cell.element.focus();
},
contentTemplate: content,
};
let oldGroups = that.dataSource.group() || [];
cell = cell.kendoColumnMenu(menuOptions).data("kendoColumnMenu");
that.bind("group", function(e) {
const that = this;
const groups = e.groups || that.dataSource.group() || [];
const clearButton = clearGroupButton(cell);
const groupedData = oldGroups.length > groups.length ? oldGroups : groups;
that._syncGroupingTool(e, cell, groupedData, { itemTemplate, indicator });
that._toggleBadge(cell.element, groups.length > 0);
clearButton?.toggleClass("k-disabled", !groups.length);
oldGroups = groups;
});
cell.element.on("click" + NS, function(e) {
if (cell.popup && cell.popup._closing) {
return;
}
$(e.currentTarget).addClass(SELECTED);
});
cell.bind("open", function() {
const clearButton = clearGroupButton(cell);
if (clearButton.length) {
clearButton.off("mousedown" + NS);
clearButton.on("mousedown" + NS, function() {
that.dataSource.group([]);
that.groupable.trigger(CHANGE, { groups: [] });
that._toggleBadge(cell.element, false);
clearButton?.toggleClass("k-disabled", true);
cell.popup.close();
});
}
clearButton?.toggleClass("k-disabled", !that.dataSource.group().length);
});
},
_toggleReorderButtonsDisabledState: function(item, isFirstItem, isLastItem) {
const disabled = "k-disabled";
if (!item.length) {
return;
}
const firstReorderButton = item.find(".k-group-menu-item-actions .k-group-menu-item-up-action");
if (firstReorderButton.length) {
if (isFirstItem && !firstReorderButton.hasClass(disabled)) {
firstReorderButton.addClass(disabled);
firstReorderButton.attr("aria-disabled", true);
} else if (!isFirstItem && firstReorderButton.hasClass(disabled)) {
firstReorderButton.removeClass(disabled);
firstReorderButton.attr("aria-disabled", true);
}
const prevItem = firstReorderButton.next();
if (prevItem.length) {
if (isLastItem && !prevItem.hasClass(disabled)) {
prevItem.addClass(disabled);
prevItem.attr("aria-disabled", true);
} else if (!isLastItem && prevItem.hasClass(disabled)) {
prevItem.removeClass(disabled);
prevItem.attr("aria-disabled", true);
}
}
}
},
_syncGroupingTool: function(ev, cell, groupedData, templates) {
const that = this;
const groups = ev.groups || that.dataSource.group() || [];
const getWrapper = () => (cell._showAdaptiveView ? that._toolPopup(cell) : cell.wrapper);
const containerClass = "k-group-menu-item-wrap";
const findContainers = () => getWrapper()?.find(`.${containerClass}`);
const itemSelector = ".k-group-menu-item";
const wrapper = getWrapper();
let containers = findContainers();
if (cell._draggableInstance && cell._triggeredReordering) {
delete cell._triggeredReordering;
return;
}
if (containers && containers.length) {
groupedData.forEach((group, i) => {
const item = wrapper.find(itemSelector + `[data-field='${group.field}']`);
const index = item.data("index");
const action = item.find(".k-icon")?.attr("class").includes("plus-circle") ? "remove" : "add";
const shouldAdd = action === "remove";
const actionClass = `k-group-menu-item-${action}-action`;
const parentContainer = item.parent();
containers = findContainers();
let isFirstItem = groups && groups.length ? groups[0]?.field === group.field : false;
let isLastItem = groups && groups.length ? groups[groups.length - 1].field === group.field : false;
that._toggleReorderButtonsDisabledState(item, isFirstItem, isLastItem);
const isRemoveAction = !(groups.find((descriptor) => descriptor.field === group.field));
if (!isRemoveAction && parentContainer.is("[ref='group-container']")) {
return;
}
let container;
if (containers && containers.length === 2) {
container = shouldAdd ? containers.first() : containers.last();
} else {
container = $(`<div class="${containerClass}" ${shouldAdd ? 'ref="group-container' : ""}"></div>`);
const method = shouldAdd ? "prepend" : "append";
const containersWrapper = containers.first().parent();
const clearBtn = containersWrapper.find("[ref='clear-group']");
if (clearBtn.length && !shouldAdd) {
clearBtn.parent().before(container);
} else if (containersWrapper.length) {
containersWrapper[method](container);
}
}
const column = that.columns[index];
const shouldAddDragIndicator = !isRemoveAction && groups.length > 1;
const templateOptions = {
renderIndicator: shouldAddDragIndicator,
index,
isFirstItem,
isLastItem,
};
const groupedItem = $(templates.itemTemplate(column, { icon: shouldAdd ? "x-circle" : "plus-circle", actionClass: actionClass }, templateOptions));
item.remove();
const shouldRemoveContainer = containers.length === 2 && !parentContainer.children().length;
if (shouldRemoveContainer) {
if (parentContainer.data("kendoReorderable")) {
parentContainer.data("kendoReorderable")?.destroy();
}
parentContainer.remove();
}
if (shouldAdd) {
if (shouldAddDragIndicator) {
const firstItem = container.children().first();
if (firstItem.find(".k-group-menu-item-actions")?.length === 1) {
firstItem.prepend(templates.indicator({
isAdaptive: that._isAdaptive(),
isFirstItem: true,
isLastItem: false,
}));
}
}
container.append(groupedItem);
} else {
const nextItem = container.find(itemSelector + `[data-index="${index + 1}"]`);
if (groups.length === 1) {
const firstItem = parentContainer.children().first();
firstItem.find(".k-group-menu-item-actions:first-of-type").remove();
}
if (nextItem.length) {
nextItem.before(groupedItem);
} else {
container.append(groupedItem);
}
}
container.find(groupedItem).on("click" + NS, `.k-group-menu-item-remove-action, .k-group-menu-item-add-action`, function(e) {
that._groupItemClickHandler(e, cell);
});
});
containers = findContainers();
if (containers && containers.length) {
const dragIndicators = containers.first().find(".k-group-menu-item-drag-action");
const reorderButtons = containers.first().find(".k-group-menu-item-up-action, .k-group-menu-item-down-action");
const container = containers.first();
const hasContainer = container.is("[ref='group-container']") && container?.length;
const initDragInstance = dragIndicators.length;
const initButtonsReordering = reorderButtons.length;
if (hasContainer && initButtonsReordering) {
reorderButtons.each(function() {
const button = $(this);
button.unbind("click" + NS);
button.bind("click" + NS, (e) => that._buttonClickReorderHandler(e, cell));
});
} else if (hasContainer && initDragInstance) {
that._groupToolDraggableInstance(cell, container);
that._groupToolReorderableInstance(cell, container);
}
}
}
},
_buttonClickReorderHandler: function(e, cell) {
e.preventDefault();
e.stopPropagation();
const that = this;
const itemSelector = ".k-group-menu-item";
const clicked = $(e.currentTarget);
const element = clicked.closest(itemSelector);
const position = clicked.hasClass("k-group-menu-item-up-action") ? "before" : "after";
const target = position === "before" ? element.prev(itemSelector) : element.next(itemSelector);
const evData = {
element,
target,
position,
};
that._handleGroupReordering(evData, cell);
},
_groupToolDraggableInstance: function(cell, container) {
const that = this;
const isMobile = that._isMobile;
cell._draggableInstance = container.kendoDraggable({
holdToDrag: isMobile,
showHintOnHold: isMobile,
preventOsHoldFeatures: isMobile,
group: "group-item-draggable",
autoScroll: true,
filter: ".k-group-menu-item-drag-action",
hint: function(target) {
var hint = $('<div class="k-reorder-clue k-drag-clue">' + kendo.ui.icon({ icon: "cancel", iconClass: "k-drag-status" }) + '</div>');
return hint;
},
clickMoveClick: false,
cursorOffset: { top: 0, left: 0 }
}).data("kendoDraggable");
},
_groupToolReorderableInstance: function(cell, container) {
const that = this;
const itemSelector = ".k-group-menu-item";
if (container && container.data("kendoReorderable")) {
container.data("kendoReorderable").destroy();
}
container.kendoReorderable({
smartPosition: false,
draggable: cell._draggableInstance,
dragOverContainers: function(sourceIndex, targetIndex) {
var result = true;
$(itemSelector).eq(targetIndex);
return result;
},
dropFilter: "> " + itemSelector,
allowIcon: "insert-middle",
orientation: "vertical",
reorderDropCue: $('<div class="k-drop-hint k-drop-hint-h"><div class="k-drop-hint-start"></div><div class="k-drop-hint-line"></div></div>'),
positionDropCue: function(reorderDropCue) {
reorderDropCue.css({
transform: "translate(0,-50%)",
});
},
externalDraggable: function(e) {
var draggable = e.draggable;
if (draggable) {
return draggable;
}
},
change: function(e) {
that._handleGroupReordering(e, cell);
}
});
},
_handleGroupReordering: function(e, cell) {
const element = e.element;
const newSibling = e.target;
const method = e.position === "before" ? "insertBefore" : "insertAfter";
const descriptors = this.groupable.descriptors();
element[method](newSibling);
let targetIndex;
let newSiblingIndex;
for (let i = 0; i < descriptors.length; i++) {
const descriptor = descriptors[i];
if (descriptor.field === element.data("field")) {
targetIndex = i;
}
if (descriptor.field === newSibling.data("field")) {
newSiblingIndex = i;
}
if (targetIndex && newSiblingIndex) {
break;
}
}
if ((targetIndex || targetIndex === 0) && (newSiblingIndex || newSiblingIndex === 0)) {
const movedDescriptor = descriptors.splice(targetIndex, 1)[0];
let insertIndex = newSiblingIndex - 1 < 0 ? 0 : newSiblingIndex - 1;
if (e.position === "after") {
insertIndex += 1;
}
descriptors.splice(insertIndex, 0, movedDescriptor);
cell._triggeredReordering = true;
this.dataSource.group(descriptors);
this.groupable.trigger(CHANGE, { groups: descriptors });
}
},
_groupItemClickHandler: function(e, cell) {
const that = this;
const itemSelector = ".k-group-menu-item";
const item = $(e.currentTarget).closest(itemSelector);
const action = $(e.currentTarget).find(".k-icon")?.attr("class").includes("plus-circle") ? "remove" : "add";
const shouldAdd = action === "remove";
const index = item.data("index");
let descriptors = that.groupable.descriptors();
const column = that.columns[index];
if (shouldAdd) {
descriptors.push({ field: column.field, dir: "asc", aggregates: that.groupable.aggregates() || [], colID: column.uid, compare: (column.sortable && column.sortable.compare) || (that.groupable.sort && that.groupable.sort.compare) });
} else {
descriptors = descriptors.filter((descriptor) => descriptor.field !== column.field);
}
that.dataSource.group(descriptors);
that.groupable.trigger(CHANGE, { groups: descriptors });
},
_sortToolbarTool: function(cell) {
const that = this;
const options = that.options;
const selectorClass = "k-columnmenu-indicators";
const isAdaptive = that._isAdaptive();
const clearSortButton = (cell) => {
const clearSortSelector = that._isAdaptive() ? "[ref-actionsheet-action-button]:not('.k-button-solid-primary')" : "[ref='clear-sort']";
return that._toolPopup(cell)?.find(clearSortSelector);
};
let menu;
let menuOptions;
const toolbarSortOptions = that._toolbarOptionsForTool("sort");
menu = cell.data("kendoColumnMenu");
if (menu) {
menu.wrapper.off("click" + NS);
menu.element.off("click" + NS);
menu.destroy();
}
function content({ columns, isAdaptive }) {
let content = `<div class="k-columnmenu-item-wrapper">`;
columns.forEach((column) => {
if (column.sortable === false || column.command) {
return;
}
content += `<div class="k-columnmenu-item" tabindex="0" data-field="${column.field}">${column.title || column.field || ""}</div>`;
});
content += "</div>";
if ((!toolbarSortOptions || toolbarSortOptions.clearButton) && !isAdaptive) {
content += `<div class="k-actions k-actions-stretched k-actions-horizontal k-column-menu-footer">`;
content += kendo.html.renderButton(`<button ref="clear-sort">Clear Sorting</button>`, { icon: "x" });
content += "</div>";
}
return content;
}
const sortable = options.columnMenu.sortable !== false && options.sortable !== false ? extend({}, options.sortable, { allowUnsort: false }) : false;
if (!sortable) {
return;
}
menuOptions = {
dataSource: that.dataSource,
columns: false,
sortable: sortable,
filterable: false,
hideAutoSizeColumn: true,
owner: that,
adaptiveMode: that.options.adaptiveMode,
encodeTitles: that.options.encodeTitles,
componentType: "modern",
_actionsheet: {
actionButtons: defaultActionSheetFooterButtons.sort,
title: "Sort by",
ref: "sort-view",
closeButton: {
icon: "check",
themeColor: "primary",
},
},
init: function(e) {
cell.wrapper.attr("ref", "sort-tool");
},
closeCallback: function(e) {
e.removeClass(SELECTED);
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.find(".k-focus").removeClass("k-focus");
}
cell.element.focus();
},
sort: function(e) {
const preventClose = e.preventClose;
cell._preventClose = that.options.sortable.mode === "multiple" || preventClose;
if (that.trigger("sort", { sort: e.sort })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
},
contentTemplate: content,
};
cell = cell.kendoColumnMenu(menuOptions).data("kendoColumnMenu");
that.unbind("sort");
that.bind("sort", function(e) {
const dataSource = e.sender.dataSource;
const sortFields = dataSource._sortFields;
const isArray = Array.isArray(e.sort);
const field = e.sort.field;
const isMultiSortingEnabled = e.sender.options.sortable && (e.sender.options.sortable.mode === "multiple" || e.sender.options.sortable.mode === "mixed");
let condition;
let isUnsortEvent = e.sort.dir === undefined$1;
if (isArray) {
condition = e.sort.length;
} else if (sortFields && Object.keys(sortFields).length) {
condition = !isUnsortEvent || isUnsortEvent && Object.keys(sortFields).length - 1 > 0;
} else {
condition = !isUnsortEvent;
}
that._toggleBadge(cell.element, condition);
const element = cell.wrapper.find(`.k-columnmenu-item[data-field='${field}']`);
let indicatorsWrapper = element.find("." + selectorClass);
if (isUnsortEvent) {
indicatorsWrapper.remove();
} else {
if (!isMultiSortingEnabled) {
indicatorsWrapper = cell.wrapper.find("." + selectorClass);
}
if (indicatorsWrapper.length) {
indicatorsWrapper.remove();
}
element.append(that._renderIndicator(`sort-${e.sort.dir}-small`));
}
clearSortButton(cell)?.toggleClass("k-disabled", !condition);
});
cell.bind("open", function() {
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.focus();
const clearSortBtn = clearSortButton(cell);
const items = popupElement.find(".k-columnmenu-item");
if (clearSortBtn.length) {
clearSortBtn.off("mousedown" + NS);
clearSortBtn.on("mousedown" + NS, function() {
that.dataSource.sort([]);
that._toggleBadge(cell.element, false);
clearSortButton(cell)?.toggleClass("k-disabled", true);
cell.wrapper.find(".k-columnmenu-indicators").remove();
cell.close();
});
}
if (items.length) {
popupElement.off("click" + NS);
popupElement.on("click" + NS, ".k-columnmenu-item", function(e) {
const currentTarget = $(e.currentTarget);
const field = currentTarget.data("field");
const unsort = that._toggleColumnMenuSortIndicator(currentTarget);
const isMixed = that.options.sortable && that.options.sortable.mode === "mixed";
const hasCtrlKey = e.originalEvent.ctrlKey;
cell.field = field;
cell._sortHandler({ item: currentTarget, allowUnsort: unsort, allowSelectedState: false, isMixed, hasCtrlKey });
that._toggleSortIndexes(that.dataSource._sortFields && Object.keys(that.dataSource._sortFields).length > 1, cell, selectorClass);
});
}
}
});
cell.element.on("click" + NS, function(e) {
if (cell.popup && cell.popup._closing) {
return;
}
$(e.currentTarget).addClass(SELECTED);
const sortFields = cell.dataSource._sortFields;
const condition = sortFields && Object.keys(sortFields).length;
const shouldRenderIndexes = Object.keys(sortFields).length > 1;
if (condition) {
Object.keys(sortFields).forEach((sortField) => {
const element = cell.wrapper.find(`.k-columnmenu-item[data-field='${sortField}']`);
const indicator = element.find("." + selectorClass);
if (indicator.length) {
indicator.remove();
}
element.append(that._renderIndicator(`sort-${sortFields[sortField].dir}-small`));
});
}
that._toggleSortIndexes(shouldRenderIndexes, cell, selectorClass, isAdaptive);
clearSortButton(cell)?.toggleClass("k-disabled", !condition);
});
},
_toggleSortIndexes: function(condition, cell, selector) {
const that = this;
const showIndexes = that.options.sortable && that.options.sortable.showIndexes;
if (!showIndexes) {
return;
}
const indicators = cell.wrapper.find(`.${selector}`);
let sortFields = cell.dataSource && cell.dataSource._sortFields;
if (!indicators.length) {
return;
}
if (condition) {
indicators.each((index, indicator) => {
const field = $(indicator).closest(".k-columnmenu-item").data("field");
const sortField = sortFields[field];
const sortIndex = $(indicator).parent().find(".k-sort-index");
if (!sortIndex.length) {
if (sortField.index) {
$(indicator).append(`<span class='k-sort-index'>${sortField.index}</span>`);
} else {
$(indicator).append(`<span class='k-sort-index'>${index + 1}</span>`);
}
} else {
sortIndex.text(sortField.index);
}
});
} else {
cell.wrapper.find(".k-sort-index").remove();
}
},
_columnChooserTool: function(cell) {
const that = this;
const templateRef = "column-chooser";
function content(config) {
const template = config._defaultContents()[templateRef];
return template(config);
}
const menu = cell.data("kendoColumnMenu");
if (menu) {
menu.wrapper.off("click" + NS);
menu.element.off("click" + NS);
menu.destroy();
}
const menuOptions = {
dataSource: that.dataSource,
columns: that.columns,
sortable: false,
filterable: false,
hideAutoSizeColumn: true,
owner: that,
adaptiveMode: that.options.adaptiveMode,
encodeTitles: that.options.encodeTitles,
componentType: "modern",
contentTemplate: content,
_actionsheet: {
actionButtons: defaultActionSheetFooterButtons[templateRef],
title: "Column visibility",
subtitle: "Selected fields are visible",
closeButton: true,
ref: `${templateRef}-view`,
},
init: function(e) {
cell.wrapper.attr("ref", templateRef + "-tool");
if (cell._showAdaptiveView) {
cell.popup._content.find(`[ref='${templateRef}']`).unwrap();
} else {
cell.wrapper.removeClass("k-column-menu");
}
},
closeCallback: function(e) {
e.removeClass(SELECTED);
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.find(".k-focus").removeClass("k-focus");
}
if (cell && cell._showAdaptiveView) {
cell._applyColumnVisibility();
}
cell.element.focus();
},
};
cell = cell.kendoColumnMenu(menuOptions).data("kendoColumnMenu");
cell.element.bind("click", function(e) {
if (cell.popup && cell.popup._closing) {
return;
}
$(e.currentTarget).addClass(SELECTED);
});
cell.bind("open", function() {
const popupElement = that._toolPopup(cell);
if (popupElement.length) {
popupElement.find(".k-checkbox")?.first()?.focus();
}
});
},
_toggleBadge: function(cell, condition) {
const badgeSelector = "k-badge-container";
const badgeContainer = cell.closest(`.${badgeSelector}`);
const badge = badgeContainer.length && badgeContainer.find(".k-badge");
const overflowProp = cell.data("overflow");
if (!badge.length && condition) {
const badgeContainer = cell.wrap(`<div class='k-badge-container' ${overflowProp ? "data-overflow=" + overflowProp : ""}></div>`).parent();
badgeContainer.append($('<span></span>').kendoBadge({
round: 'full',
position: 'edge',
align: 'top end',
themeColor: 'primary',
cutoutBorder: true,
}));
} else if (!condition && badge.length) {
badge.remove();
cell.unwrap(".k-badge-container");
}
},
_toggleColumnMenuFilterIndicator: function(element, condition) {
const that = this;
const classSelector = ".k-columnmenu-indicators";
const indicatorWrapper = element.find(classSelector);
const spacer = element.find(".k-spacer");
if (condition && spacer.length) {
if (indicatorWrapper && indicatorWrapper.length) {
return;
}
spacer.before(that._renderIndicator("filter"));
} else {
if (indicatorWrapper && indicatorWrapper.length) {
indicatorWrapper.remove();
}
}
},
_toggleColumnMenuSortIndicator: function(element) {
const that = this;
const classSelector = ".k-columnmenu-indicators";
const indicatorWrapper = element.find(classSelector);
const sortIndex = element.find(".k-sort-index");
let unsort;
let action = !sortIndex.length ? "append" : "before";
if (indicatorWrapper && indicatorWrapper.length) {
const indicator = indicatorWrapper.find(".k-icon");
if (indicator.length && indicator.hasClass("k-svg-i-sort-desc-small")) {
indicatorWrapper.remove();
unsort = true;
} else {
indicator.remove();
indicatorWrapper[action](that._renderIndicator("sort-desc-small"));
unsort = false;
}
} else {
element[action](that._renderIndicator("sort-asc-small"));
unsort = false;
}
return unsort;
},
_renderIndicator: function(icon) {
return $("<span class='k-columnmenu-indicators'></span>").append(
kendo.ui.icon($('<span></span>'), { icon: icon })
);
},
_globalColumnsMenu: function(cell) {
var that = this,
menu,
columns = leafColumns(that.columns),
options = that.options,
columnMenu = options.columnMenu,
menuOptions,
initCallback = function(e) {
if (that._isAdaptive()) {
e.sender.popup.wrapper.find(".k-expanded [ref=columns-visibility]").data("handler").toggle(false);
}
that.trigger(COLUMNMENUINIT, { field: e.field, container: e.container });
},
openCallback = function(e) {
that.trigger(COLUMNMENUOPEN, { field: e.field, container: e.container });
},
closeCallback = function() {
cell.trigger("focus");
};
if (columnMenu) {
if (typeof columnMenu == "boolean") {
columnMenu = {};
}
that._setColumnsMediaVisibility(columns);
let toggleable = !!(columnMenu.autoSize || columnMenu.clearAllFilters);
menu = cell.data("kendoColumnMenu");
if (menu) {
menu.destroy();
}
let columnsExpanderOptions = {
toggleable: toggleable,
expanded: columnMenu.expanded || true,
animation: false,
hideExpanderIndicator: !toggleable
};
menuOptions = {
dataSource: that.dataSource,
columns: columnMenu.columns,
sortable: false,
filterable: false,
clearAllFilters: columnMenu.clearAllFilters,
messages: columnMenu.messages,
hideAutoSizeColumn: true,
owner: that,
closeCallback: closeCallback,
init: initCallback,
open: openCallback,
pane: that.options.adaptiveMode !== 'auto' && that.pane,
autoSize: columnMenu.autoSize,
encodeTitles: that.options.encodeTitles,
componentType: "modern",
adaptiveMode: "auto",
columnsExpanderOptions: columnsExpanderOptions
};
cell.kendoColumnMenu(menuOptions);
}
},
_columnMenu: function() {
var that = this,
menu,
columns = leafColumns(that.columns),
column,
options = that.options,
columnMenu = options.columnMenu,
menuOptions,
sortable,
filterable,
cells,
hasMultiColumnHeaders = grep(that.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0,
hasLockableColumns = grep(that.columns, function(item) {
return item.lockable !== false;
}).length > 0,
hasStickableColumns = grep(that.columns, function(item) {
return item.stickable === true;
}).length > 0,
isMobile = this._isMobile,
initCallback = function(e) {
that.trigger(COLUMNMENUINIT, { field: e.field, container: e.container });
},
openCallback = function(e) {
that.trigger(COLUMNMENUOPEN, { field: e.field, container: e.container });
},
closeCallback = function() {
focusTable(that.table, true);
},
stickCallback = function(e) {
that.trigger(COLUMNSTICK, { column: e.column });
},
unstickCallback = function(e) {
that.trigger(COLUMNUNSTICK, { column: e.column });
},
sortHandler = function(e) {
if (that.trigger("sort", { sort: e.sort })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
},
filterHandler = function(e) {
if (that.trigger("filter", { filter: e.filter, field: e.field })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
};
if (columnMenu) {
if (typeof columnMenu == "boolean") {
columnMenu = {};
}
that._setColumnsMediaVisibility(columns);
cells = leafDataCells(that.thead);
for (var idx = 0, length = cells.length; idx < length; idx++) {
column = columns[idx];
var cell = cells.eq(idx);
if (column.columnMenu !== false && !column.command && (column.field || cell.attr("data-" + kendo.ns + "field"))) {
menu = cell.data("kendoColumnMenu");
if (menu) {
menu.destroy();
}
sortable = column.sortable !== false && columnMenu.sortable !== false && options.sortable !== false ? extend({}, options.sortable, {
compare: (column.sortable || {}).compare
}) : false;
filterable = options.filterable && column.filterable !== false && columnMenu.filterable !== false ? extend(true, { pane: that.pane }, options.filterable, column.filterable) : false;
if (column.filterable && column.filterable.dataSource) {
filterable.forceUnique = false;
filterable.checkSource = column.filterable.dataSource;
}
if (filterable) {
filterable.format = column.format;
}
const isAdaptive = that.options.adaptiveMode !== "auto" ? (columnMenu.adaptiveMode || that.options.adaptiveMode) : that.options.adaptiveMode;
menuOptions = {
dataSource: that.dataSource,
values: column.values,
columns: columnMenu.columns,
sortable: sortable,
filterable: filterable,
messages: columnMenu.messages,
owner: that,
adaptiveMode: isAdaptive,
adaptiveTitle: column.title || column.field,
closeCallback: closeCallback,
init: initCallback,
open: openCallback,
stick: stickCallback,
unstick: unstickCallback,
pane: that.options.adaptiveMode !== 'auto' && that.pane,
sort: sortHandler,
filtering: filterHandler,
filter: isMobile ? ":not(.k-column-active)" : "",
autoSize: columnMenu.autoSize,
hasLockableColumns: lockedColumns(columns).length > 0 && hasLockableColumns && !hasMultiColumnHeaders,
hasStickableColumns: hasStickableColumns && !hasMultiColumnHeaders,
encodeTitles: that.options.encodeTitles,
componentType: columnMenu.componentType,
appendTo: DOT + classNames.headerCellInner,
reorderable: options.reorderable === true || (options.reorderable && options.reorderable.columns),
groupable: that.options.groupable && that.options.groupable.enabled !== false && column.groupable !== false
};
cell.kendoColumnMenu(menuOptions);
}
}
}
},
_headerCells: function() {
return $(this.thead).find("th").filter(function() {
var th = $(this);
return !th.hasClass("k-group-cell") && !th.hasClass("k-hierarchy-cell");
});
},
_hasFilterMenu: function() {
var filterable = this.options.filterable;
if (filterable && typeof filterable.mode == STRING && filterable.mode.indexOf("menu") == -1) {
return false;
}
return filterable;
},
_filterable: function() {
var that = this,
columns = leafColumns(that.columns),
filterMenu,
cells,
cell,
filterInit = function(e) {
that.trigger(FILTERMENUINIT, { field: e.field, container: e.container });
},
closeCallback = function() {
focusTable(that.table, true);
},
filterHandler = function(e) {
if (that.trigger("filter", { filter: e.filter, field: e.field })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
},
filterOpen = function(e) {
that.trigger(FILTERMENUOPEN, { field: e.field, container: e.container });
},
filterable = that._hasFilterMenu();
if (filterable && !that.options.columnMenu) {
cells = leafDataCells(that.thead);//that._headerCells();
for (var idx = 0, length = cells.length; idx < length; idx++) {
cell = cells.eq(idx);
if (columns[idx].filterable !== false && !columns[idx].command && (columns[idx].field || cell.attr("data-" + kendo.ns + "field"))) {
filterMenu = cell.data("kendoFilterMenu");
if (filterMenu) {
filterMenu.destroy();
}
filterMenu = cell.data("kendoFilterMultiCheck");
if (filterMenu) {
filterMenu.destroy();
}
var columnFilterable = columns[idx].filterable;
var options = extend({},
filterable,
columnFilterable,
{
dataSource: that.dataSource,
values: columns[idx].values,
format: columns[idx].format,
closeCallback: closeCallback,
title: columns[idx].title || columns[idx].field,
init: filterInit,
open: filterOpen,
pane: that.pane,
change: filterHandler,
appendTo: DOT + classNames.headerCellInner,
adaptiveMode: that.options.adaptiveMode
}
);
if (columnFilterable && columnFilterable.messages) {
options.messages = extend(true, {}, filterable.messages, columnFilterable.messages);
}
if (columnFilterable && columnFilterable.dataSource) {
options.forceUnique = false;
options.checkSource = columnFilterable.dataSource;
}
if (columnFilterable && columnFilterable.multi) {
cell.kendoFilterMultiCheck(options);
} else {
cell.kendoFilterMenu(options);
}
}
}
}
},
_filterRow: function() {
var that = this;
if (!that._hasFilterRow()) {
return;
}
var settings;
var columns = leafColumns(that.columns),
filterable = that.options.filterable,
rowheader = that.thead.find(".k-filter-row"),
filterHandler = function(e) {
if (that.trigger("filter", { filter: e.filter, field: e.field })) {
e.preventDefault();
} else {
that._clearEditableState();
if (that.dataSource.options.endless) {
that._resetEndless();
}
}
};
this._updateHeader(that._groups());
for (var i = 0; i < columns.length; i++) {
var suggestDataSource,
col = columns[i],
operators = that.options.filterable.operators,
customDataSource = false,
td = $("<td class='k-table-td' title='" + that.options.messages.filterCellTitle + "'/>"),
field = col.field;
if (col.hidden) {
td.hide();
}
rowheader.append(td);
if (field && col.filterable !== false) {
var cellOptions = col.filterable && col.filterable.cell || {};
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) {
td.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,
size: that.options.size,
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,
adaptiveMode: that.options.adaptiveMode,
};
$("<span/>").attr(kendo.attr("field"), field)
.appendTo(td)
.kendoFilterCell(settings);
} else {
td.html(" ");
}
td.data("column", col);
}
this._filterFocusable().attr(TABINDEX, -1);
},
_sortable: function() {
var that = this,
columns = leafColumns(that.columns),
column,
sorterInstance,
cell,
sortable = that.options.sortable,
sortHandler = function(e) {
if (that.trigger("sort", { sort: e.sort })) {
e.preventDefault();
} else {
that._clearEditableState();
}
};
if (sortable) {
var cells = leafDataCells(that.thead);
for (var idx = 0, length = cells.length; idx < length; idx++) {
column = columns[idx];
if (column.sortable !== false && !column.command && column.field) {
cell = cells.eq(idx);
sorterInstance = cell.data("kendoColumnSorter");
if (sorterInstance) {
sorterInstance.destroy();
}
cell.attr("data-" + kendo.ns + "field", column.field)
.kendoColumnSorter(
extend({}, sortable, column.sortable, {
dataSource: that.dataSource,
aria: true,
filter: ":not(.k-column-active)",
change: sortHandler
})
);
}
}
cells = null;
}
},
_columns: function(columns) {
var that = this,
table = that.table,
encoded,
cols = table.find("col"),
lockedCols,
headerRows = that.element.find('thead tr'),
dataSource = that.options.dataSource,
draggableColumns;
// using HTML5 data attributes as a configuration option e.g. <th data-field="foo">Foo</foo>
columns = columns.length ? columns : map(table.find("th:not(.k-group-cell):not(.k-hierarchy-cell)"), function(th, idx) {
th = $(th);
var sortable = th.attr(kendo.attr("sortable")),
filterable = th.attr(kendo.attr("filterable")),
type = th.attr(kendo.attr("type")),
groupable = th.attr(kendo.attr("groupable")),
field = th.attr(kendo.attr("field")),
title = th.attr(kendo.attr("title")),
columnMenu = th.attr(kendo.attr("column-menu")),
menu = th.attr(kendo.attr("menu"));
if (!field) {
field = th.text().replace(/\s|[^A-z0-9]/g, "");
}
return {
field: field,
type: type,
title: title,
sortable: sortable !== "false",
filterable: filterable !== "false",
groupable: groupable !== "false",
menu: menu !== "false",
columnMenu: columnMenu !== "false",
template: th.attr(kendo.attr("template")),
width: cols.eq(idx).css(WIDTH)
};
});
encoded = !(that.table.find("tbody tr").length > 0 && (!dataSource || !dataSource.transport));
if (that.options.scrollable) {
var initialColumns = columns;
lockedCols = lockedColumns(columns);
columns = nonLockedColumns(columns);
if (lockedCols.length > 0 && columns.length === 0) {
throw new Error("There should be at least one non locked column");
}
normalizeHeaderCells(that.element.find("tr:has(th)").first(), initialColumns);
columns = lockedCols.concat(columns);
}
if (headerRows.length && columns.length) {
that._updateColumnIDs(columns, headerRows.first());
}
that.columns = normalizeColumns(columns, encoded);
if ($.grep(leafColumns(that.columns), function(col) { return col.selectable; }).length) {
that._selectedIds = {};
that._checkBoxSelection = true;
that.wrapper.on(CLICK + NS, "tbody > tr " + CHECKBOXINPUT, that._checkboxClick.bind(that));
that.wrapper.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);
}
}
that._foreignKeyBindings(flatColumns(that.columns));
},
_foreignKeyBindings: function(columns) {
var that = this;
var length = columns.length;
var column;
for (var i = 0; i < length; i++) {
column = columns[i];
if (column.dataSource) {
that._fetchForeignKeyValues(column);
}
}
},
_fetchForeignKeyValues: function(column) {
var that = this;
var promise = $.Deferred();
that._hasBoundForeignKey = true;
column.dataSource = DataSource.create(column.dataSource);
if (!that._foreignKeyPromises) {
that._foreignKeyPromises = [];
}
that._foreignKeyPromises.push(promise);
column.dataSource.fetch().then(function() {
var data = column.dataSource.data();
column.values = data.map(function(item) {
return {
value: item[column.dataValueField],
text: item[column.dataTextField]
};
});
promise.resolve();
});
},
_updateColumnIDs: function(columns, tr) {
if (!columns.length) {
return;
}
var ths = tr.find("th:not(.k-group-cell):not(.k-hierarchy-cell)");
var id;
for (var i = 0; i < columns.length; i++) {
id = ths.eq(i).attr(ID);
if (id) {
columns[i].headerAttributes = extend(columns[i].headerAttributes, { id: id });
}
}
this._updateColumnIDs(childColumns(columns), tr.next());
},
_headerCheckboxClick: function(e) {
var that = this,
checkBox = $(e.target),
checked = checkBox.prop("checked");
if (!that._belongsToGrid(checkBox)) {
return;
}
if (that.trigger(CHANGING, { target: checkBox, originalEvent: e })) {
e.preventDefault();
return;
}
if (checked) {
that.select(that.items());
} else {
that.clearSelection();
}
that._calculateAggregatesForSelected();
that.trigger(CHANGE, { cellAggregates: that._cellAggregates });
},
_checkboxClick: function(e) {
var that = this,
row = $(e.target).closest(TR),
isSelecting = !row.hasClass(SELECTED);
if (!that._belongsToGrid(row)) {
return;
}
if (that.trigger(CHANGING, { target: row, originalEvent: e })) {
e.preventDefault();
return;
}
if (isSelecting) {
that.select(row);
} else {
that._deselectCheckRows(row);
}
that._calculateAggregatesForSelected();
that.trigger(CHANGE, { cellAggregates: that._cellAggregates });
},
_groups: function() {
var group = this.dataSource.group();
return group ? group.length : 0;
},
_tmpl: function(rowTemplate, columns, alt, skipGroupCells) {
var that = this,
settings = extend({}, kendo.Template, that.options.templateSettings);
settings.paramName;
var idx,
length = columns.length,
state = { storage: {}, count: 0 },
column,
hasDetails = that._hasDetails(),
groups = that._groups();
var fieldAttr = kendo.attr("field");
var field;
var classAttribute;
var compiledAttributes;
let rowTemplateFunc;
if (!rowTemplate) {
rowTemplateFunc = (data) => {
var uid = length ? ` ${kendo.attr("uid")}="${kendo.getter("uid")(data)}"` : '';
var rowTemplateResult = `<tr class="${alt ? 'k-table-row k-table-alt-row ' : 'k-table-row '}k-master-row"${uid}>`;
if (groups > 0 && !skipGroupCells) {
rowTemplateResult += groupCells(groups);
}
if (hasDetails) {
rowTemplateResult += '<td class="k-hierarchy-cell k-table-td" aria-expanded="false">' + kendo.ui.icon($(`<a href="#" ${ARIA_LABEL}="${EXPAND}" tabindex="-1"></a>`), { icon: `caret-alt-${isRtl ? "left" : "right"}` }) + '</td>';
}
for (idx = 0; idx < length; idx++) {
column = columns[idx];
column.template;
field = column.field;
compiledAttributes = {};
let dirtyCellTemplate;
if (that._editMode() && field) {
column.attributes = column.attributes || {};
if (that.virtualScroll) {
column.attributes[fieldAttr] = field;
}
dirtyCellTemplate = that._dirtyCellTemplate(field)(data);
}
if (column.colSpan && column.colSpan > 0 && hasHiddenStyle(column.attributes)) { //virtual cell should be visible at all times
column.attributes = removeHiddenStyle(column.attributes);
} else if (!column.colSpan && column.hidden) {
column.attributes = addHiddenStyle(column.attributes);
}
if (column.command) {
column.attributes = column.attributes || {};
classAttribute = column.attributes["class"];
if (typeof classAttribute !== "undefined") {
if (classAttribute.indexOf("k-command-cell") < 0) {
column.attributes["class"] += " k-command-cell";
}
} else {
column.attributes["class"] = "k-command-cell";
}
}
if (column.draggable) {
column.attributes = column.attributes || {};
if (typeof column.attributes["class"] !== "undefined") {
if (column.attributes["class"].indexOf("k-drag-cell") < 0) {
column.attributes["class"] += " k-drag-cell";
}
} else {
column.attributes["class"] = "k-drag-cell";
}
if (!column.attributes["ref-grid-drag-cell"]) {
column.attributes["ref-grid-drag-cell"] = true;
}
if (typeof column.attributes[ARIA_LABEL] === "undefined") {
column.attributes[ARIA_LABEL] = that.options.messages.dragHandleLabel;
}
if (typeof column.attributes.style !== "undefined") {
if (column.attributes.style.indexOf("cursor: move;") < 0) {
column.attributes.style += " cursor: move;";
}
} else {
column.attributes.style = "cursor: move;";
}
}
if (column._attributesFunction) {
compiledAttributes = column._attributesFunction(data);
}
let attributes = extend({}, column.attributes, compiledAttributes);
if (dirtyCellTemplate) {
attributes["class"] = (attributes["class"] || "");
attributes["class"] += dirtyCellTemplate;
}
let columnAttributes = stringifyAttributes(attributes);
let colSpanAttributes = '';
if (column.colSpan) {
if (column.colSpan > 1) {
colSpanAttributes += " " + kendo.attr("virtual");
}
colSpanAttributes += ` colSpan="${column.colSpan}"`;
}
rowTemplateResult += decorateCellWithClass(`<td${columnAttributes}${colSpanAttributes}>`);
rowTemplateResult += column.selectable ? kendo.template(SELECTCOLUMNTMPL)({ size: kendo.getValidCssClass("k-checkbox-", "size", that.options.size) }) : that._cellTmpl(column, state)(data);
rowTemplateResult += "</td>";
}
rowTemplateResult += "</tr>";
return rowTemplateResult;
};
}
rowTemplate = kendo.template(rowTemplate || rowTemplateFunc, settings);
if (state.count > 0) {
return rowTemplate.bind(state.storage);
}
return rowTemplate;
},
_dirtyCellTemplate: function(field) {
return (data) => {
if (field && data && data.dirty && data.dirtyFields) {
let dirtyField = field.charAt(0) === "[" ? kendo.getter(field)(data.dirtyFields) : data.dirtyFields[field];
return dirtyField ? ' k-dirty-cell' : '';
}
return "";
};
},
_headerCellText: function(column) {
var that = this,
settings = extend({}, kendo.Template, that.options.templateSettings),
template = column.headerTemplate,
type = typeof (template),
text = column.title && (that.options.encodeTitles ? htmlEncode(column.title) : column.title) || htmlEncode(column.field || "");
if (type === FUNCTION) {
text = kendo.template(template, settings)({});
} else if (type === STRING) {
text = template;
}
return text;
},
_cellTmpl: function(column, state) {
var that = this,
settings = extend({}, kendo.Template, that.options.templateSettings),
template = column.template,
field = column.field,
// html = "",
idx,
length,
format = column.format,
type = typeof template,
columnValues = column.values;
if (column.command) {
if (isArray(column.command)) {
return (data) => {
let html = "";
for (idx = 0, length = column.command.length; idx < length; idx++) {
if (column.command[idx].visible) {
html += column.command[idx].visible(data) ? that._createButton(column.command[idx]) : '';
} else {
html += that._createButton(column.command[idx]);
}
}
return html;
};
}
return () => that._createButton(column.command);
}
if (column.selectable) {
return SELECTCOLUMNTMPL;
}
if (column.draggable) {
return DRAGHANDLECOLUMNTMPL;
}
return (data) => {
let html = that._dirtyIndicatorTemplate(field)(data);
if (type === FUNCTION) {
state.storage["tmpl" + state.count] = template;
html += template(data);
state.count++;
} else if (type === STRING) {
html += kendo.template(template, settings)(data);
} else if (columnValues && columnValues.length && isPlainObject(columnValues[0]) && "value" in columnValues[0] && field) {
var v = convertToObject(columnValues);
var f = v[settings.useWithBlock ? kendo.getter(field)(data) : field];
html += encode(f != null ? f : '');
} else {
let fieldValue = '';
if (field) {
field = kendo.getter(field)(data);
fieldValue = field == null ? '' : field;
}
if (format) {
fieldValue = kendo.format(format.replace(formatRegExp, "$1"), fieldValue);
}
html += column.encoded ? encode(fieldValue) : fieldValue;
}
return html;
};
},
_dirtyIndicatorTemplate: function(field) {
return (data) => {
if (field && data && data.dirty && data.dirtyFields) {
let dirtyField = field.charAt(0) === "[" ? kendo.getter(field)(data.dirtyFields) : data.dirtyFields[field];
return dirtyField ? '<span class=\"k-dirty\"></span>' : '';
}
return "";
};
},
_virtualCols: function(columns) {
var that = this;
var widths = $.map(columns, function(c) { return c.hidden ? 0 : parseInt(c.width, 10); });
var scrollLeft = that.virtualScrollable ? kendo.scrollLeft(that.content.find(">.k-virtual-scrollable-wrap")) : kendo.scrollLeft(that.content);
var tableWidth = outerWidth(that.content);
var sumOfWidths = sumWidths(columns);
var colsToRender = [];
var firstColspan = 0;
var lastColspan = 0;
var hiddenColumns = 0;
var idx = 0;
var widthOfHiddenColumns = 0;
var considerNext;
for (idx = 0; idx < columns.length; idx++) {
considerNext = (idx < widths.length - 1) ? widths[idx + 1] : 0;
if (widthOfHiddenColumns + widths[idx] + 2 * considerNext < scrollLeft) {
if (widths[idx]) {
hiddenColumns++;
}
widthOfHiddenColumns += widths[idx];
} else {
firstColspan = 1 + hiddenColumns;
break;
}
}
hiddenColumns = 0;
widthOfHiddenColumns = 0;
for (var i = columns.length - 1; i >= 0; i--) {
if (widthOfHiddenColumns + 3 * widths[i] < sumOfWidths - tableWidth - scrollLeft) {
if (widths[i]) {
hiddenColumns++;
}
widthOfHiddenColumns += widths[i];
} else {
lastColspan = 1 + hiddenColumns;
for (var j = idx; j <= i; j++) {
if (columns[j].locked) {
continue;
}
colsToRender.push(columns[j]);
if (columns[j].colSpan) {
delete columns[j].colSpan;
}
}
colsToRender[0].colSpan = firstColspan;
colsToRender[colsToRender.length - 1].colSpan = lastColspan;
break;
}
}
if (colsToRender[0].hidden) {
colsToRender[0].colSpan--;
}
that.virtualCols = colsToRender;
return colsToRender;
},
_templates: function() {
var that = this,
options = that.options,
dataSource = that.dataSource,
groups = dataSource.group(),
footer = that.footer || that.wrapper.find(".k-grid-footer"),
aggregates = dataSource.aggregate(),
columnLeafs = leafColumns(that.columns),
columnsLocked = leafColumns(lockedColumns(that.columns)),
leafsCols = options.scrollable ? leafColumns(nonLockedColumns(that.columns)) : columnLeafs,
columns = (that.virtualScroll || {}).columns ? that._virtualCols(leafsCols) : leafsCols,
groupHeaderColumnTemplateLockedColumns = grep(visibleColumns(columnsLocked), function(column, index) { return column.groupHeaderColumnTemplate && index !== 0; }),
groupHeaderColumnTemplateNonLockedColumns = grep(visibleColumns(columns), function(column) { return column.groupHeaderColumnTemplate; });
if (options.scrollable && columnsLocked.length) {
if (options.rowTemplate || options.altRowTemplate) {
throw new Error("Having both row template and locked columns is not supported");
}
that.rowTemplate = that._tmpl(options.rowTemplate, columns, false, true);
that.altRowTemplate = that._tmpl(options.altRowTemplate || options.rowTemplate, columns, true, true);
that.lockedRowTemplate = that._tmpl(options.rowTemplate, columnsLocked);
that.lockedAltRowTemplate = that._tmpl(options.altRowTemplate || options.rowTemplate, columnsLocked, true);
} else {
that.rowTemplate = that._tmpl(options.rowTemplate, columns);
that.altRowTemplate = that._tmpl(options.altRowTemplate || options.rowTemplate, columns, true);
}
if (that._hasDetails()) {
that.detailTemplate = that._detailTmpl(options.detailTemplate || (() => ""));
}
if ((that._group && !isEmptyObject(aggregates)) || (!isEmptyObject(aggregates) && !footer.length) ||
grep(columnLeafs, function(column) { return column.footerTemplate; }).length) {
that.footerTemplate = that._footerTmpl(columnLeafs, aggregates, "footerTemplate", "k-footer-template k-table-row");
}
if (groups && grep(columnLeafs, function(column) { return column.groupFooterTemplate; }).length) {
aggregates = $.map(groups, function(g) { return g.aggregates; });
that.groupFooterTemplate = that._footerTmpl(columns, aggregates, "groupFooterTemplate", "k-group-footer k-table-row", columnsLocked.length);
if (options.scrollable && columnsLocked.length) {
that.lockedGroupFooterTemplate = that._footerTmpl(columnsLocked, aggregates, "groupFooterTemplate", "k-group-footer k-table-row");
}
}
if (groups && (groupHeaderColumnTemplateLockedColumns.length || groupHeaderColumnTemplateNonLockedColumns.length)) {
aggregates = $.map(groups, function(g) { return g.aggregates; });
that.groupHeaderColumnTemplate = that._groupHeaderTmpl(visibleColumns(columns), aggregates, "groupHeaderColumnTemplate", "k-table-group-row k-grouping-row k-table-row", columnsLocked.length, groupHeaderColumnTemplateNonLockedColumns);
if (options.scrollable && columnsLocked.length) {
that.lockedGroupHeaderColumnTemplate = that._groupHeaderTmpl(visibleColumns(columnsLocked), aggregates, "groupHeaderColumnTemplate", "k-table-group-row k-grouping-row k-table-row", 0, groupHeaderColumnTemplateLockedColumns);
}
} else {
that.groupHeaderColumnTemplate = null;
that.lockedGroupHeaderColumnTemplate = null;
}
if (that.options.noRecords) {
that.noRecordsTemplate = that._noRecordsTmpl();
}
},
_noRecordsTmpl: 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 state = { storage: {}, count: 0 };
var settings = $.extend({}, kendo.Template, this.options.templateSettings);
settings.paramName;
var template;
// var html = "";
var type;
var tmpl;
let resultTemplate;
if (this.options.noRecords.template) {
template = this.options.noRecords.template;
} else {
template = kendo.format(defaultTemplate, this.options.messages.noRecords, scrollableNoGridHeightStyles);
}
type = typeof template;
if (type === "function") {
let currentCustomTemplate = state.storage["tmpl" + state.count] = template;
state.count++;
resultTemplate = (data) => kendo.format(wrapper, NORECORDSCLASS, currentCustomTemplate(data));
} else if (type === "string") {
resultTemplate = this.options.noRecords.template ?
kendo.format(wrapper, NORECORDSCLASS, template)
: () => kendo.format(wrapper, NORECORDSCLASS, template);
}
tmpl = kendo.template(resultTemplate, settings);
if (state.count > 0) {
tmpl = tmpl.bind(state.storage);
}
return tmpl;
},
_footerTmpl: function(columns, aggregates, templateName, rowClass, skipGroupCells) {
var that = this,
settings = extend({}, kendo.Template, that.options.templateSettings),
paramName = settings.paramName,
// html = "",
idx,
length,
template,
type,
storage = {},
count = 0,
scope = {},
groups = that._groups(),
fieldsMap = that.dataSource._emptyAggregates(aggregates),
column;
let footerTemplateFunction = (data) => {
let html = '<tr class="' + rowClass + '">';
if (groups > 0 && !skipGroupCells) {
html += groupCells(groups);
}
if (that._hasDetails()) {
html += '<td class="k-hierarchy-cell k-table-td"> </td>';
}
for (idx = 0, length = columns.length; idx < length; idx++) {
column = columns[idx];
template = column[templateName];
type = typeof template;
html += decorateCellWithClass("<td" + stringifyAttributes(column.footerAttributes) + ">");
if (template) {
if (type !== FUNCTION) {
scope = fieldsMap[column.field] ? extend({}, settings, { paramName: paramName + "['" + column.field + "']" }) : {};
template = kendo.template(template, scope);
}
storage["tmpl" + count] = template;
html += template(data);
count++;
} else {
html += " ";
}
html += "</td>";
}
html += '</tr>';
return html;
};
let resultTemplate = kendo.template(footerTemplateFunction, settings);
if (count > 0) {
return resultTemplate.bind(storage);
}
return resultTemplate;
},
_groupHeaderTmpl: function(columns, aggregates, templateName, rowClass, skipGroupCells, groupHeaderColumnTemplateColumns) {
var that = this,
settings = extend({}, kendo.Template, that.options.templateSettings),
paramName = settings.paramName,
html = "",
idx,
length,
template,
type,
storage = {},
count = 0,
scope = {},
fieldsMap = that.dataSource._emptyAggregates(aggregates),
column,
headerTemplateIndex = groupHeaderColumnTemplateColumns.length ? inArray(groupHeaderColumnTemplateColumns[0], columns) : -1,
groupHeaderColumnTemplateClass;
if (headerTemplateIndex < 0) {
return;
}
var groupHeaderTemplFunc = (data) => {
var resultHtml = '<tr data-group-uid="' + data.uid + '" class="' + rowClass + '">';
if (!skipGroupCells) {
for (var i = 0; i < data.groupCells; i++) {
resultHtml += '<td class="k-table-td k-group-cell"> </td>';
}
}
if (that._hasDetails()) {
resultHtml += '<td class="k-table-td k-hierarchy-cell"> </td>';
}
if (headerTemplateIndex < MINCOLSPANVALUE && groupHeaderColumnTemplateColumns.length <= 1 && !skipGroupCells) {
resultHtml += !skipGroupCells ? groupCellBuilder(columns.length)(data) : '';
return resultHtml;
// return kendo.template(resultHtml, settings);
}
if (headerTemplateIndex < MINCOLSPANVALUE) {
headerTemplateIndex = !skipGroupCells ? 1 : 0;
resultHtml += !skipGroupCells ? groupCellBuilder(headerTemplateIndex)(data) : '';
}
else {
resultHtml += !skipGroupCells ? groupCellBuilder(headerTemplateIndex)(data) : groupCellLockedContentBuilder(headerTemplateIndex);
}
for (idx = headerTemplateIndex, length = columns.length; idx < length; idx++) {
column = columns[idx];
template = column[templateName];
type = typeof template;
if (column.sticky) {
let stickyAttributes = '';
groupHeaderColumnTemplateClass = (column.groupHeaderColumnTemplateClass || '');
if (!groupHeaderColumnTemplateClass) {
groupHeaderColumnTemplateClass = column.groupHeaderColumnTemplateClass = "group-header-column-template-" + kendo.guid();
}
if (isPlainObject(column.stickyStyle)) {
let stickyLeft = column.stickyStyle.left ? `${kendo.attr("style-left")}="${column.stickyStyle.left}"` : '';
let stickyRight = column.stickyStyle.right ? `${kendo.attr("style-right")}="${column.stickyStyle.right}"` : '';
stickyAttributes = `${stickyLeft} ${stickyRight}`;
}
resultHtml += `<td class="k-table-td ${STICKY_CELL_CLASS} ${groupHeaderColumnTemplateClass}" ${stickyAttributes}>`;
} else {
resultHtml += "<td class='k-table-td'>";
}
if (template) {
if (type !== FUNCTION) {
scope = fieldsMap[column.field] ? extend({}, settings, { paramName: paramName + "['" + column.field + "']" }) : {};
template = kendo.template(template, scope);
}
storage["tmpl" + count] = template;
resultHtml += storage["tmpl" + count](data);
count++;
} else {
resultHtml += " ";
}
resultHtml += "</td>";
}
resultHtml += '</tr>';
return resultHtml;
};
html = kendo.template(groupHeaderTemplFunc, settings);
if (count > 0) {
return html.bind(storage);
}
return html;
},
_detailTmpl: function(template) {
var that = this,
settings = extend({}, kendo.Template, that.options.templateSettings);
settings.paramName;
var templateFunctionStorage = {},
templateFunctionCount = 0,
groups = that._groups(),
colspan = visibleColumns(leafColumns(that.columns)).length,
type = typeof template;
let detailTemplateFunction = (data) => {
let html = '<tr role="row" class="k-detail-row k-table-row">';
if (groups > 0) {
html += groupCells(groups);
}
html += `<td role="gridcell" class="k-hierarchy-cell k-table-td"></td><td role="gridcell" class="k-table-td k-detail-cell"${colspan ? ` colspan="${colspan}"` : ''}>`;
if (type === FUNCTION) {
templateFunctionStorage["tmpl" + templateFunctionCount] = template;
html += template(data);
templateFunctionCount++;
} else {
html += kendo.template(template, settings)(data);
}
html += "</td></tr>";
return html;
};
let resultTemplate = kendo.template(detailTemplateFunction, settings);
if (templateFunctionCount > 0) {
return resultTemplate.bind(templateFunctionStorage);
}
return resultTemplate;
},
_hasDetails: function() {
var that = this;
return that.options.detailTemplate !== null || (that._events[DETAILINIT] || []).length;
},
_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;
},
_details: function() {
var that = this;
if (that.options.scrollable && that._hasDetails() && lockedColumns(that.columns).length) {
throw new Error("Having both detail template and locked columns is not supported");
}
that.table.on(CLICK + NS, ".k-hierarchy-cell " + CARET_ALT_RIGHT + ", .k-hierarchy-cell " + CARET_ALT_DOWN, function(e) {
var button = $(this);
that._toggleDetails(button);
e.preventDefault();
return false;
});
},
_toggleDetails: function(button, omitAnimation) {
var that = this,
cell = button.closest("td.k-hierarchy-cell"),
expanding = button.is(CARET_ALT_RIGHT),
masterRow = button.closest("tr.k-master-row"),
masterRowIndex = masterRow.attr(ARIA_ROWINDEX),
detailRow,
detailTemplate = that.detailTemplate,
data,
hasDetails = that._hasDetails(),
ariaLabelText = expanding ? COLLAPSE : EXPAND,
ariaExpandText = expanding ? true : false;
if (!expanding) {
kendo.ui.icon(button, { icon: `caret-alt-${isRtl ? 'left' : 'right'}` });
} else {
kendo.ui.icon(button, { icon: "caret-alt-down" });
}
button.attr(ARIA_LABEL, ariaLabelText);
cell.attr(ARIA_EXPANDED, ariaExpandText);
detailRow = masterRow.next();
if (detailRow.hasClass("k-hidden")) {
detailRow.removeClass("k-hidden");
}
if (hasDetails && !detailRow.hasClass("k-detail-row")) {
data = that.dataItem(masterRow);
detailRow = $(detailTemplate(data))
.addClass(masterRow.hasClass("k-table-alt-row") ? "k-table-alt-row" : "")
.insertAfter(masterRow);
if (masterRowIndex || masterRowIndex === 0) {
detailRow.attr(ARIA_ROWINDEX, Number(masterRowIndex) + 1);
}
that.trigger(DETAILINIT, { masterRow: masterRow, detailRow: detailRow, data: data, detailCell: detailRow.find(".k-detail-cell") });
}
that.trigger(expanding ? DETAILEXPAND : DETAILCOLLAPSE, { masterRow: masterRow, detailRow: detailRow });
if (omitAnimation) {
toggleRow(detailRow, expanding);
} else {
detailRow.toggle(expanding);
}
},
dataItem: function(tr) {
tr = $(tr)[0];
if (!tr) {
return null;
}
var rows = this.tbody.children(),
classesRegEx = /k-grouping-row|k-detail-row|k-group-footer/,
idx = tr.sectionRowIndex,
j, correctIdx;
correctIdx = idx;
for (j = 0; j < idx; j++) {
if (classesRegEx.test(rows[j].className)) {
correctIdx--;
}
}
return this._data[correctIdx];
},
expandRow: function(tr, omitAnimation) {
var button = $(tr).find('> td ' + CARET_ALT_RIGHT);
if (button.length) {
this._toggleDetails(button, omitAnimation);
}
},
collapseRow: function(tr, omitAnimation) {
var button = $(tr).find('> td ' + CARET_ALT_DOWN);
if (button.length) {
this._toggleDetails(button, omitAnimation);
}
},
_createHeaderCells: function(columns, rowSpan) {
var that = this,
idx,
th,
text,
html = "",
length,
title,
columnMenu = that.options.columnMenu;
that.options.sortable;
var filterable = that._hasFilterMenu(),
messages = that.options.messages,
leafs = leafColumns(that.columns),
groups = that.dataSource.group(),
field;
for (idx = 0, length = columns.length; idx < length; idx++) {
th = columns[idx].column || columns[idx];
text = that._headerCellText(th);
title = th.title;
field = "";
let index = inArray(th, leafs);
let currentTh = "";
if (th.selectable) {
currentTh += "<th scope='col'" + stringifyAttributes(th.headerAttributes);
if (rowSpan && !columns[idx].colSpan) {
currentTh += " rowspan='" + rowSpan + "'";
}
if (index > -1) {
currentTh += kendo.attr("index") + "='" + index + "'";
}
text = th.headerTemplate ? text : kendo.template(SELECTCOLUMNHEADERTMPL)({ size: kendo.getValidCssClass("k-checkbox-", "size", that.options.size) });
currentTh += ">" + text + "</th>";
} else if (th.draggable) {
currentTh += "<th class='k-header' ref-grid-drag-cell scope='col'" + stringifyAttributes(th.headerAttributes);
if (rowSpan && !columns[idx].colSpan) {
currentTh += " rowspan='" + rowSpan + "'";
}
if (index > -1) {
currentTh += kendo.attr("index") + "='" + index + "'";
}
text = th.headerTemplate ? text : "";
currentTh += ">" + text + "</th>";
} else if (th.command) {
currentTh += "<th scope='col'" + stringifyAttributes(th.headerAttributes);
if (rowSpan && !columns[idx].colSpan) {
currentTh += " rowspan='" + rowSpan + "'";
}
if (index > -1) {
currentTh += kendo.attr("index") + "='" + index + "'";
}
currentTh += ">" + ((!text || text === " ") ? text : kendo.template(DEFAULTHEADERTEMPLATE)({ text: text })) + "</th>";
} else {
if (th.field) {
field = kendo.attr("field") + "='" + th.field + "' ";
}
currentTh += "<th scope='col' " + field;
if ((columnMenu && th.field && th.menu !== false)) {
currentTh += " aria-haspopup='menu'";
} else if (filterable && th.filterable !== false && !th.command) {
currentTh += " aria-haspopup='dialog'";
}
if (rowSpan && !columns[idx].colSpan) {
currentTh += " rowspan='" + rowSpan + "'";
}
if (columns[idx].colSpan > 1) {
currentTh += 'colspan="' + (columns[idx].colSpan - hiddenLeafColumnsCount(th.columns)) + '" ';
currentTh += kendo.attr("colspan") + "='" + columns[idx].colSpan + "'";
} else if (columns[idx].colSpan === 1) {
currentTh += kendo.attr("colspan") + "='" + columns[idx].colSpan + "'";
}
if (title) {
title = title && (that.options.encodeTitles ? htmlEncode(title, true) : title);
currentTh += kendo.attr("title") + '="' + title + '" ';
}
if (th.groupable !== undefined$1) {
currentTh += kendo.attr("groupable") + "='" + th.groupable + "' ";
}
if (isColumnGroupable(that, th) && (!th.headerAttributes || !th.headerAttributes.title)) {
currentTh += "title='";
currentTh += isGroupedBy(groups, th.field) ? messages.ungroupHeader : messages.groupHeader;
currentTh += "' ";
}
if (th.aggregates && th.aggregates.length) {
currentTh += kendo.attr("aggregates") + "='" + th.aggregates + "'";
}
if (index > -1) {
currentTh += kendo.attr("index") + "='" + index + "'";
}
currentTh += stringifyAttributes(th.headerAttributes);
text = kendo.template(DEFAULTHEADERTEMPLATE)({ text: text });
currentTh += ">" + text + "</th>";
}
if (that.options.resizable) {
html += $(currentTh).attr("data-resizable", (th.resizable !== false).toString()).addClass("k-table-th")[0].outerHTML;
} else {
html += $(currentTh).addClass("k-table-th")[0].outerHTML;
}
}
return html;
},
_appendLockedColumnContent: function() {
var columns = this.columns,
idx,
colgroup = this.table.find("colgroup"),
cols = colgroup.find(COLGROUP),
length,
lockedCols = $(),
skipHiddenCount = 0,
container,
colSpan,
spanIdx,
colOffset = 0;
for (idx = 0, length = columns.length; idx < length; idx++) {
if (columns[idx].locked) {
if (isVisible(columns[idx])) {
colSpan = 1;
if (columns[idx].columns) {
colSpan = leafColumns(columns[idx].columns).length - hiddenLeafColumnsCount(columns[idx].columns);
}
colSpan = colSpan || 1;
for (spanIdx = 0; spanIdx < colSpan; spanIdx++) {
lockedCols = lockedCols.add(cols.eq(idx + colOffset + spanIdx - skipHiddenCount));
}
colOffset += colSpan - 1;
} else {
skipHiddenCount++;
}
}
}
container = $('<div class="k-grid-content-locked"><table class="k-grid-table k-table"><colgroup></colgroup><tbody class="k-table-tbody"></tbody></table></div>');
// detach is required for IE8, otherwise it switches to compatibility mode
colgroup.detach();
container.find("colgroup").append(lockedCols);
colgroup.insertBefore(this.table.find("tbody"));
this.lockedContent = container.insertBefore(this.content);
this.lockedTable = container.children("table");
this.lockedTable.addClass(kendo.getValidCssClass("k-table-", "size", this.options.size));
},
_appendLockedColumnFooter: function() {
var that = this;
var footer = that.footer;
var cells = footer.find(".k-footer-template>td");
var cols = footer.find(".k-grid-footer-wrap>table>colgroup>col");
var html = $('<div class="k-grid-footer-locked"><table class="k-grid-footer-table k-table"><colgroup></colgroup><tfoot class="k-table-tfoot"><tr class="k-footer-template k-table-row"></tr></tfoot></table></div>');
var idx, length;
var groups = that._groups();
var lockedCells = $(), lockedCols = $();
html.find("table").addClass(kendo.getValidCssClass("k-table-", "size", this.options.size));
lockedCells = lockedCells.add(cells.filter(".k-group-cell"));
for (idx = 0, length = leafColumns(lockedColumns(that.columns)).length; idx < length; idx++) {
lockedCells = lockedCells.add(cells.eq(idx + groups));
}
lockedCols = lockedCols.add(cols.filter(".k-group-col"));
for (idx = 0, length = visibleColumns(leafColumns(visibleLockedColumns(that.columns))).length; idx < length; idx++) {
lockedCols = lockedCols.add(cols.eq(idx + groups));
}
lockedCells.appendTo(html.find(TR));
lockedCols.appendTo(html.find("colgroup"));
that.lockedFooter = html.prependTo(footer);
},
_appendLockedColumnHeader: function(container) {
var that = this,
columns = this.columns,
idx,
html,
length,
colgroup,
tr,
trFilter,
table,
header,
filtercellCells,
rows = [],
skipHiddenCount = 0,
cols = $(),
hasFilterRow = that._hasFilterRow(),
filterCellOffset = 0,
filterCells = $(),
cell,
leafColumnsCount = 0,
cells = $();
colgroup = that.thead.prev().find(COLGROUP);
header = that.thead.find(TR).first().find(".k-header:not(.k-group-cell,.k-hierarchy-cell)");
filtercellCells = that.thead.find(".k-filter-row").find("td:not(.k-group-cell,.k-hierarchy-cell)");
var colOffset = 0;
for (idx = 0, length = columns.length; idx < length; idx++) {
if (columns[idx].locked) {
cell = header.eq(idx);
leafColumnsCount = leafColumns(columns[idx].columns || []).length;
if (isVisible(columns[idx])) {
var colSpan = null;
if (columns[idx].columns) {
colSpan = leafColumnsCount - hiddenLeafColumnsCount(columns[idx].columns);
}
colSpan = colSpan || 1;
for (var spanIdx = 0; spanIdx < colSpan; spanIdx++) {
cols = cols.add(colgroup.eq(idx + colOffset + spanIdx - skipHiddenCount));
}
colOffset += colSpan - 1;
}
mapColumnToCellRows([columns[idx]], childColumnsCells(cell), rows, 0, 0);
leafColumnsCount = leafColumnsCount || 1;
for (var j = 0; j < leafColumnsCount; j++) {
filterCells = filterCells.add(filtercellCells.eq(filterCellOffset + j));
}
filterCellOffset += leafColumnsCount;
}
if (columns[idx].columns) {
skipHiddenCount += hiddenLeafColumnsCount(columns[idx].columns);
}
if (!isVisible(columns[idx])) {
skipHiddenCount++;
}
}
if (rows.length) {
html = '<div class="k-grid-header-locked"><table class="k-grid-header-table k-table"><colgroup></colgroup><thead class="k-table-thead">';
html += new Array(rows.length + 1).join("<tr class='k-table-row'></tr>");
html += (hasFilterRow ? '<tr class="k-filter-row k-table-row"></tr>' : '') + '</thead></table></div>';
table = $(html);
table.find('.k-grid-header-locked').css('width', '1px');
table.find("table").addClass(kendo.getValidCssClass("k-table-", "size", that.options.size));
colgroup = table.find("colgroup");
colgroup.append(that.thead.prev().find("col.k-group-col").add(cols));
tr = table.find("thead tr:not(.k-filter-row)");
for (idx = 0, length = rows.length; idx < length; idx++) {
cells = toJQuery(rows[idx]);
tr.eq(idx).append(that.thead.find(TR).eq(idx).find(".k-group-cell").add(cells));
}
var count = removeEmptyRows(this.thead);
if (rows.length < count) {
removeRowSpanValue(table, count - rows.length);
}
trFilter = table.find(".k-filter-row");
trFilter.append(that.thead.find(".k-filter-row .k-group-cell").add(filterCells));
this.lockedHeader = table.prependTo(container);
this.thead.find(".k-group-cell").remove();
return true;
}
return false;
},
_removeLockedContainers: function() {
var elements = this.lockedHeader
.add(this.lockedContent)
.add(this.lockedFooter);
kendo.destroy(elements);
elements.off(NS).remove();
this.lockedHeader = this.lockedContent = this.lockedFooter = null;
this.selectable = null;
},
_thead: function() {
var that = this,
columns = that.columns,
hasDetails = that._hasDetails() && columns.length,
hasFilterRow = that._hasFilterRow(),
idx,
html = "",
thead = that.table.find(">thead"),
hasTHead = that.element.find("thead").first().length > 0,
headerContent = that.options.messages.expandCollapseColumnHeader,
tr;
if (!thead.length) {
thead = $("<thead/>").insertBefore(that.tbody);
}
thead.addClass("k-table-thead");
if (that.lockedHeader && that.thead) {
tr = that.thead.find("tr:has(th):not(.k-filter-row)").html("");
tr.remove();
tr = $();
that._removeLockedContainers();
} else if (hasTHead) {
tr = that.element.find("thead").first().find("tr:has(th):not(.k-filter-row)");
} else {
tr = that.element.find("tr:has(th)").first();
}
if (!tr.length) {
tr = thead.children().first();
if (!tr.length) {
var rows = [{ rowSpan: 1, cells: [], index: 0 }];
that._prepareColumns(rows, columns);
for (idx = 0; idx < rows.length; idx++) {
html += "<tr class='k-table-row'>";
if (hasDetails) {
html += '<th class="k-hierarchy-cell k-table-th" scope="col">' + headerContent + '</th>';
}
html += that._createHeaderCells(rows[idx].cells, rows[idx].rowSpan);
html += "</tr>";
}
tr = $(html);
kendo.applyStylesFromKendoAttributes(tr, ["display", "left", "right"]);
}
} else {
for (idx = 0; idx < columns.length; idx++) {
let columnIndex = inArray(columns[idx], leafColumns(columns));
let cell = leafDataCells(tr.parent()).filter("th:not(.k-group-cell):not(.k-hierarchy-cell)").eq(columnIndex);
cell.addClass("k-table-th");
const cellElement = cell[0];
const cellChildNodes = cellElement?.childNodes || [];
// Apply the default template only if the cell contains a single text node.
// In all other cases the structure must remain unchanged. It is up to the developer to provide a custom template.
if (cellChildNodes.length === 1 && cellChildNodes[0].nodeType === 3) {
cell.html(DEFAULTHEADERTEMPLATE({ text: htmlEncode(cell.text()) }));
}
if (columns[idx].hidden && columnIndex >= 0) {
cellElement.style.display = NONE;
}
}
that._updateHeadersAttr(childColumns(columns));
}
if (hasFilterRow) {
var filterRow = $("<tr/>");
filterRow.addClass("k-filter-row k-table-row");
if (hasDetails || tr.find(".k-hierarchy-cell").length) { // handles server side detail template
filterRow.prepend('<td class="k-table-td k-hierarchy-cell"> </td>');
}
var existingFilterRow = (that.thead || thead).find(".k-filter-row");
if (existingFilterRow.length) {
kendo.destroy(existingFilterRow);
existingFilterRow.remove();
}
thead.append(filterRow);
}
if (!tr.children().length) {
html = "";
if (hasDetails) {
html += '<th class="k-hierarchy-cell k-table-th" scope="col"> </th>';
}
html += that._createHeaderCells(columns);
tr.html(html);
} else if (hasDetails && !tr.find(".k-hierarchy-cell")[0]) {
tr.prepend('<th class="k-hierarchy-cell k-table-th" scope="col">' + (headerContent ? headerContent : ' ') + '</th>');
}
const th = tr.find(TH);
th.addClass(HEADER_CLASS);
if (th.length > 0) {
thead.attr(ROLE, ROWGROUP);
}
if (!that.options.scrollable) {
thead.addClass("k-grid-header");
}
tr.find("script").remove().end().prependTo(thead);
if (that.thead) {
that._destroyColumnAttachments();
}
that.thead = thead;
that._sortable();
that._filterable();
that._filterRow();
that._scrollable();
that._columnMenu();
var syncHeight;
var hasLockedColumns = this.options.scrollable && lockedColumns(this.columns).length;
if (hasLockedColumns) {
syncHeight = that._appendLockedColumnHeader(that.thead.closest(".k-grid-header"));
that._appendLockedColumnContent();
that.lockedContent.on("DOMMouseScroll" + NS + " mousewheel" + NS, that._wheelScroll.bind(that));
if (kendo.support.touch) {
that._lockedContentUserEvents = new kendo.UserEvents(that.lockedContent, {
move: function(e) {
that.content.scrollTop(that.content.scrollTop() + (-e.y.delta));
e.preventDefault();
}
});
}
that._updateLockedCols();
}
that._updateCols();
that._updateColumnCellIndex();
that._updateFirstColumnClass();
that._resizable();
that._draggable();
that._reorderable();
that._updateHeader(that._groups());
that._updateStickyColumns();
if (hasLockedColumns) {
if (syncHeight) {
that._syncLockedHeaderHeight();
}
that._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,
columns = that.columns || [],
hasDetails = that._hasDetails() && columns.length;
if (!hasDetails && !that._groups()) {
var tr = that.thead.find(">tr:not(.k-filter-row):not(:first)");
columns = nonLockedColumns(columns);
var rows = that._retrieveFirstColumn(columns, tr);
if (that._isLocked()) {
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");
});
}
},
_prepareColumns: function(rows, columns, parentCell, parentRow) {
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 = { column: columns[idx], colSpan: 0 };
row.cells.push(cell);
if (columns[idx].columns && columns[idx].columns.length) {
if (!childRow) {
childRow = { rowSpan: 0, cells: [], index: rows.length };
rows.push(childRow);
}
cell.colSpan = columns[idx].columns.length;
this._prepareColumns(rows, columns[idx].columns, cell, childRow);
totalColSpan += cell.colSpan - 1;
row.rowSpan = rows.length - row.index;
}
}
if (parentCell) {
parentCell.colSpan += totalColSpan;
}
},
_wheelScroll: function(e) {
if (e.ctrlKey) {
return;
}
var content = this.content;
if (this.virtualScroll && this.virtualScroll.rows) {
content = this.virtualScrollable.verticalScrollbar;
}
var scrollTop = content.scrollTop(),
delta = kendo.wheelDeltaY(e);
if (delta) {
if (content[0].scrollHeight > content[0].clientHeight &&
(content[0].scrollTop < content[0].scrollHeight - content[0].clientHeight && delta < 0 ||
content[0].scrollTop > 0 && delta > 0)) {
e.preventDefault();
}
content.scrollTop(scrollTop + (-delta));
}
},
_isLocked: function() {
return this.lockedHeader != null;
},
_updateHeaderCols: function() {
var table = this.thead.parent().add(this.table);
if (this._isLocked()) {
normalizeCols(table, visibleLeafColumns(visibleNonLockedColumns(this.columns)), this._hasDetails(), 0);
} else {
normalizeCols(table, visibleLeafColumns(visibleColumns(this.columns)), this._hasDetails(), 0);
}
},
_updateColumnSorters: function() {
var that = this;
var cells = leafDataCells(that.thead);
var columns = leafColumns(that.columns);
var column;
var cell;
var sorterInstance;
if (!that.options.sortable) {
return;
}
for (var idx = 0, length = cells.length; idx < length; idx++) {
column = columns[idx];
if (column.sortable !== false && !column.command && column.field) {
cell = cells.eq(idx);
sorterInstance = cell.data("kendoColumnSorter");
if (sorterInstance) {
sorterInstance.refresh();
}
}
}
},
_updateHeadersAttr: function(columns) {
if (!columns.length) {
return;
}
var that = this;
for (var i = 0; i < columns.length; i++) {
if (columns[i].headerAttributes) {
var th = that.element.find("[id='" + columns[i].headerAttributes.id + "']");
th.attr("headers", columns[i].headerAttributes.headers);
}
}
that._updateHeadersAttr(childColumns(columns));
},
_updateCols: function(table) {
table = table || this.thead.parent().add(this.table);
this._appendCols(table, this._isLocked());
},
_updateLockedCols: function(table) {
if (this._isLocked()) {
table = table || this.lockedHeader.find("table").add(this.lockedTable);
normalizeCols(table, visibleLeafColumns(visibleLockedColumns(this.columns)), this._hasDetails(), this._groups());
}
},
_appendCols: function(table, locked) {
if (locked) {
normalizeCols(table, visibleLeafColumns(visibleNonLockedColumns(this.columns)), this._hasDetails(), 0);
} else {
normalizeCols(table, visibleLeafColumns(visibleColumns(this.columns)), this._hasDetails(), this._groups());
}
},
_autoColumns: function(schema) {
if (schema && schema.toJSON) {
var that = this,
field,
encoded;
schema = schema.toJSON();
encoded = !(that.table.find("tbody tr").length > 0 && (!that.dataSource || !that.dataSource.transport));
for (field in schema) {
that.columns.push({ field: field, encoded: encoded, headerAttributes: { id: kendo.guid() } });
}
that._thead();
that._templates();
}
},
_setRowCachedHeight: function(row, uid) {
var cachedHeights = this._cachedRowsHeight,
cachedHeight = cachedHeights[uid],
$row;
if (cachedHeight) {
$row = $(row);
$row[0].style.height = cachedHeight + "px";
row = $row.prop("outerHTML");
}
return row;
},
_rowsHtml: function(data, templates) {
var that = this,
html = "",
idx,
rowTemplate = templates.rowTemplate,
altRowTemplate = templates.altRowTemplate,
cachedHeights = that._cachedRowsHeight,
length, row;
for (idx = 0, length = data.length; idx < length; idx++) {
if (that._skipRerenderItemsCount > 0) {
that._skipRerenderItemsCount--;
} else {
if (idx % 2) {
row = altRowTemplate(data[idx]);
} else {
row = rowTemplate(data[idx]);
}
if (cachedHeights) {
row = that._setRowCachedHeight(row, data[idx].uid);
}
html += row;
}
that._data.push(data[idx]);
}
return html;
},
_groupData: function(group, skipFooter, firstColumn) {
var that = this,
footerDefaults = that._groupAggregatesDefaultObject || {},
groupItems = group.items,
aggregates = extend({}, footerDefaults, group.aggregates),
headerData = extend({}, {
field: group.field,
value: group.value,
items: groupItems,
aggregates: aggregates
}, group.aggregates[firstColumn ? firstColumn.field : group.field]),
footerData = {};
if (!skipFooter) {
for (var aggregate in aggregates) {
footerData[aggregate] = extend({}, aggregates[aggregate],
{ group: { field: group.field, value: group.value, items: groupItems } }
);
}
}
return extend({}, footerData, headerData);
},
_removeGroupIfEmpty: function(row) {
var that = this,
itemsCount,
subgroupsCount,
length = that.dataSource._group.length;
for (var i = 0; i < length; i++) {
row = row.prev();
itemsCount = +row.attr('data-group-item-count');
subgroupsCount = +row.attr('data-sub-group-count');
if (itemsCount == 1 || subgroupsCount == 1) {
row.hide();
}
}
},
_groupRowHtml: function(group, colspan, level, groupHeaderBuilder, templates, skipColspan, skipLastGroup, isLockedTable) {
var that = this,
html = "",
idx,
length,
isLocked = that.lockedContent != null,
field = group.field,
column = grep(leafColumns(that.columns), function(column) { return column.field == field; })[0] || {},
firstColumn = visibleColumns(that.columns)[0],
firstVisibleColumnGroupHeaderTemplate = firstColumn ? firstColumn.groupHeaderColumnTemplate : null,
template = column.groupHeaderTemplate ? column.groupHeaderTemplate : firstVisibleColumnGroupHeaderTemplate,
text = (column.title && (that.options.encodeTitles ? htmlEncode(column.title, true) : column.title) || htmlEncode(field, true)) + ': ' + formatGroupValue(group.value, column.format, column.values, column.encoded),
groupItems = group.currentItems || group.items,
groups = that._groups(),
groupFooterTemplate = templates.groupFooterTemplate,
groupHeaderColumnTemplate = templates.groupHeaderColumnTemplate,
groupData,
isGroupPaged = that.dataSource._isGroupPaged(),
expanded = isGroupPaged ? that.dataSource._groupsState[group.uid] : true;
if (that.options.editable && group.items && group.items[0] && group.items[0].isNew && group.items[0].isNew()) {
expanded = true;
}
if (templates.groupFooterTemplate || templates.groupHeaderColumnTemplate || column.groupHeaderTemplate) {
groupData = that._groupData(group, false, !column.groupHeaderTemplate && visibleColumns(that.columns)[0].groupHeaderColumnTemplate ? visibleColumns(that.columns)[0] : false);
}
if (template && !skipColspan) {
text = typeof template === FUNCTION ? template(groupData) : kendo.template(template)(groupData);
}
if (!that._skipRerenderItemsCount) {
if (!group.excludeHeader) {
html += groupHtmlBuilder(groupHeaderColumnTemplate, groupHeaderBuilder, colspan, groups - level, groupData, level, text, expanded, group, isGroupPaged);
} else if (isLocked) {
group.excludeHeader = isLockedTable ? false : true;
} else {
group.excludeHeader = false;
}
} else {
groupHeaderBuilder(colspan, level, text, expanded, group.uid, isGroupPaged);
}
if (expanded) {
if (group.hasSubgroups) {
for (idx = 0, length = groupItems.length; idx < length; idx++) {
html += that._groupRowHtml(groupItems[idx], skipColspan ? colspan : colspan - 1, level + 1, groupHeaderBuilder, templates, skipColspan, skipLastGroup && idx === groupItems.length - 1, isLockedTable);
}
} else {
html += that._rowsHtml(groupItems, templates);
}
}
if (groupFooterTemplate) {
if (skipLastGroup) {
if (!inArray(group.value, that._skippedGroups)) {
that._skippedGroups.push(group.value);
}
} else {
if (that._skippedGroups.length && that._skippedGroups[0] === group.value) {
that._skippedGroups.shift();
}
if (!that._skipRerenderItemsCount) {
html += groupFooterTemplate(groupData);
}
}
}
return html;
},
collapseGroup: function(group) {
var level,
that = this,
groupToCollapse = group,
groupable = this.options.groupable,
showFooter = groupable.showFooter,
footerCount = showFooter ? 0 : 1,
offset,
relatedGroup = $(),
idx,
length,
tr;
group = $(group);
level = group.find(".k-group-cell").length;
if (this.dataSource._isGroupPaged()) {
var groupUid = group.attr("data-group-uid");
var groupObject = that.dataSource._getGroupByUid(groupUid);
var currentGroupCount = that.dataSource._calculateGroupsTotal([groupObject], true);
var groupCountAfterCollapse;
that.dataSource._groupsState[groupUid] = false;
groupCountAfterCollapse = that.dataSource._calculateGroupsTotal([groupObject], true);
that.dataSource._serverGroupsTotal -= currentGroupCount - groupCountAfterCollapse;
that._progress(true);
that.dataSource.range(that.dataSource._currentRangeStart, that.dataSource.take(), function() {
that._progress(false);
}, "collapseGroup");
return;
}
if (this._isLocked()) {
if (!group.closest(DIV).hasClass("k-grid-content-locked")) {
relatedGroup = group.nextAll(TR);
group = this.lockedTable.find(">tbody>tr").eq(group.index());
} else {
relatedGroup = this.tbody.children(TR).eq(group.index()).nextAll(TR);
}
}
if (group.find(CARET_ALT_DOWN).length) {
kendo.ui.icon(group.find(CARET_ALT_DOWN), { icon: `caret-alt-${isRtl ? 'left' : 'right'}` });
}
group.find("td[aria-expanded='true']").first().attr(ARIA_EXPANDED, false)
.find("a").attr(ARIA_LABEL, EXPAND);
group = group.nextAll(TR);
var toHide = [];
for (idx = 0, length = group.length; idx < length; idx++) {
tr = group.eq(idx);
offset = tr.find(".k-group-cell").length;
if (tr.hasClass(GROUPING_ROW)) {
footerCount++;
} else if (tr.hasClass("k-group-footer")) {
footerCount--;
}
if (offset <= level || (tr.hasClass("k-group-footer") && footerCount < 0)) {
break;
}
if (relatedGroup.length) {
toHide.push(relatedGroup[idx]);
}
toHide.push(tr[0]);
}
$(toHide).hide();
if (this.options.scrollable.endless && this.content) {
clearTimeout(that._collapseGroupsTimeOut);
that._collapseGroupsTimeOut = setTimeout(function() {
that.content.scroll();
that._groupToCollapse = groupToCollapse;
});
}
},
expandGroup: function(group) {
group = $(group);
var that = this,
showFooter = that.options.groupable.showFooter,
level,
tr,
offset,
relatedGroup = $(),
idx,
length,
footersVisibility = [],
groupsCount = 1;
level = group.find(".k-group-cell").length;
if (this.dataSource._isGroupPaged()) {
var groupUid = group.attr("data-group-uid");
var groupObject = that.dataSource._getGroupByUid(groupUid);
var groupCount = that.dataSource._calculateGroupsTotal([groupObject], true);
var groupCountAfterExpand;
that.dataSource._groupsState[groupUid] = true;
if (groupObject.items && groupObject.items.length) {
groupCountAfterExpand = that.dataSource._calculateGroupsTotal([groupObject], true);
that.dataSource._serverGroupsTotal += groupCountAfterExpand - groupCount;
}
that._progress(true);
that.dataSource.range(that.dataSource._currentRangeStart, that.dataSource.take(), function() {
that._progress(false);
}, "expandGroup");
return;
}
if (this._isLocked()) {
if (!group.closest(DIV).hasClass("k-grid-content-locked")) {
relatedGroup = group.nextAll(TR);
group = this.lockedTable.find(">tbody>tr").eq(group.index());
} else {
relatedGroup = this.tbody.children(TR).eq(group.index()).nextAll(TR);
}
}
if (group.find(CARET_ALT_RIGHT).length) {
kendo.ui.icon(group.find(CARET_ALT_RIGHT), { icon: "caret-alt-down" });
}
group.find("td[aria-expanded='false']").first().attr(ARIA_EXPANDED, true)
.find("a").attr(ARIA_LABEL, COLLAPSE);
group = group.nextAll(TR);
for (idx = 0, length = group.length; idx < length; idx++) {
tr = group.eq(idx);
offset = tr.find(".k-group-cell").length;
if (offset <= level) {
break;
}
if (offset == level + 1 && !tr.hasClass("k-detail-row")) {
tr.show();
relatedGroup.eq(idx).show();
if (tr.hasClass(GROUPING_ROW) && tr.find(".k-icon,.k-svg-icon").is(CARET_ALT_DOWN)) {
that.expandGroup(tr);
}
if (tr.hasClass("k-master-row") && tr.find(".k-icon,.k-svg-icon").is(CARET_ALT_DOWN)) {
tr.next().show();
relatedGroup.eq(idx + 1).show();
}
}
if (tr.hasClass(GROUPING_ROW)) {
if (showFooter) {
footersVisibility.push(tr.is(":visible"));
}
groupsCount++;
}
if (tr.hasClass("k-group-footer")) {
if (showFooter) {
var toggleVisibility = footersVisibility.pop();
tr.toggle(toggleVisibility);
relatedGroup.eq(idx).toggle(toggleVisibility);
}
if (groupsCount == 1) {
tr.show();
relatedGroup.eq(idx).show();
} else {
groupsCount--;
}
}
}
if ((level === 0 && that.options.scrollable.endless && this._isLocked()) ||
(!that.options.scrollable.endless && this._isLocked())) {
that._syncLockedContentHeight();
}
},
_updateHeader: function(groups) {
var that = this,
container = that._isLocked() ? that.lockedHeader.find("thead") : that.thead,
filterCells = container.find("tr.k-filter-row").find("td.k-group-cell").length,
length = container.find(TR).first().find("th.k-group-cell").length,
rows = container.children("tr:not(:first)").filter(function() {
return !$(this).children(":visible").length;
});
if (groups > length) {
$(new Array(groups - length + 1).join('<th class="k-group-cell k-header k-table-th" scope="col">' + encode(that.options.messages.expandCollapseColumnHeader) + '</th>')).prependTo(container.children("tr:not(.k-filter-row)"));
if (that.element.is(":visible")) {
rows.find("th.k-group-cell").hide();
}
} else if (groups < length) {
container.find(TR).each(function() {
$(this).find(".k-group-cell").eq(groups).remove();
$(this).find(".k-group-cell").slice(groups).remove();
});
}
if (groups > filterCells) {
$(new Array(groups - filterCells + 1).join('<td class="k-group-cell k-table-group-td k-table-td"> </td>')).prependTo(container.find(".k-filter-row"));
}
},
_firstDataItem: function(data, grouped) {
if (data && grouped) {
if (data.hasSubgroups) {
data = this._firstDataItem(data.items[0], grouped);
} else {
data = data.items[0];
}
}
return data;
},
_updateTablesWidth: function() {
var that = this,
tables;
if (!that._isLocked()) {
return;
}
tables =
$(">.k-grid-footer>.k-grid-footer-wrap>table", that.wrapper)
.add(that.thead.parent())
.add(that.table);
that._footerWidth = tableWidth(tables.eq(0));
tables.width(that._footerWidth);
tables =
$(">.k-grid-footer>.k-grid-footer-locked>table", that.wrapper)
.add(that.lockedHeader.find(">table"))
.add(that.lockedTable);
tables.width(tableWidth(tables.eq(0)));
},
hideColumn: function(column) {
var that = this,
cell,
tables,
idx,
cols,
colWidth,
position,
width = 0,
headerCellIndex,
length,
footer = that.footer || that.wrapper.find(".k-grid-footer"),
virtualScroll = that.virtualScroll || {},
columns = that.columns,
visibleLocked = that.lockedHeader ? leafDataCells(that.lockedHeader.find(">table>thead")).filter(isCellVisible).length : 0,
columnIndex,
groupHeaderColumnTemplateColumns,
columnsToHide;
if (!Array.isArray(column)) {
columnsToHide = [column];
} else {
columnsToHide = column;
}
columnsToHide.forEach((column) => {
groupHeaderColumnTemplateColumns = grep(leafColumns(that.columns), function(column) { return column.groupHeaderColumnTemplate; });
if (typeof column == "number") {
column = columns[column];
} else if (isPlainObject(column)) {
column = grep(flatColumns(columns), function(item) {
return item === column;
})[0];
} else {
column = grep(flatColumns(columns), function(item) {
return item.field === column;
})[0];
}
if (!column || !isVisible(column)) {
return;
}
var setColumnVisibility = that._columnVisibilitySetter(column);
if (column.columns && column.columns.length) {
position = columnVisiblePosition(column, columns);
setColumnVisibility(column, false);
setCellVisibility(elements($(">table>thead", that.lockedHeader), that.thead, ">tr:eq(" + position.row + ")>th"), position.cell, false);
for (idx = 0; idx < column.columns.length; idx++) {
this.hideColumn(column.columns[idx]);
}
that._ariaAddHiddenColIndex();
that.trigger(COLUMNHIDE, { column: column });
return;
}
columnIndex = inArray(column, visibleColumns(leafColumns(columns)));
setColumnVisibility(column, false);
that._setParentsVisibility(column, false);
that._templates();
that._updateCols();
that._updateLockedCols();
var container = that.thead;
headerCellIndex = columnIndex;
if (that.lockedHeader && visibleLocked > columnIndex) {
container = that.lockedHeader.find(">table>thead");
} else {
headerCellIndex -= visibleLocked;
}
cell = leafDataCells(container).filter(isCellVisible).eq(headerCellIndex);
cell[0].style.display = NONE;
setCellVisibility(elements($(">table>thead", that.lockedHeader), that.thead, ">tr.k-filter-row>td"), columnIndex, false);
if (footer[0]) {
that._updateCols(footer.find(">.k-grid-footer-wrap>table"));
that._updateLockedCols(footer.find(">.k-grid-footer-locked>table"));
setCellVisibility(footer.find(".k-footer-template>td"), columnIndex, false);
}
if (virtualScroll.columns && !column.locked) {
that._updateContentWidth();
that.trigger(COLUMNHIDE, { column: column });
return;
}
if (that.lockedTable && visibleLocked > columnIndex) {
hideColumnCells(that.lockedTable.find(">tbody>tr"), columnIndex);
} else {
hideColumnCells(that.tbody.children(), columnIndex - visibleLocked);
}
if (that.lockedTable) {
that._updateTablesWidth();
that._applyLockedContainersWidth();
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
that._syncLockedFooterHeight();
} else {
cols = that.thead.prev().find("col");
for (idx = 0, length = cols.length; idx < length; idx += 1) {
colWidth = cols[idx].style.width;
if (cols[idx].className.indexOf("k-hierarchy-col") > -1) {
width += outerWidth(cols[idx]);
continue;
}
if (cols[idx].className.indexOf("k-group-col") > -1) {
width += outerWidth(cols[idx]);
continue;
}
if (colWidth && colWidth.indexOf("%") == -1) {
width += parseInt(colWidth, 10);
} else {
width = 0;
break;
}
}
tables = that.wrapper.find(">.k-grid-header table").first().add(that.wrapper.find(">.k-grid-footer table").first()).add(that.table);
that._footerWidth = null;
if (width) {
tables.each(function() {
this.style.width = width + PX;
});
that._footerWidth = width;
that._setContentWidth();
}
}
that._updateFirstColumnClass();
that._updateStickyColumns();
if (groupHeaderColumnTemplateColumns.length > 0) {
that._renderGroupRows();
}
that._ariaAddHiddenColIndex();
that.trigger(COLUMNHIDE, { column: column });
});
},
_setParentsVisibility: function(column, visible) {
var that = this;
var columns = that.columns;
var idx;
var parents = [];
var parent;
var position;
var cell;
var colSpan;
var setColumnVisibility = that._columnVisibilitySetter(column);
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];
position = columnPosition(parent, columns);
cell = elements($(">table>thead", this.lockedHeader), this.thead, ">tr:eq(" + position.row + ")>th:not(.k-group-cell):not(.k-hierarchy-cell)").eq(position.cell);
if (predicate(parent)) {
setColumnVisibility(parent, visible);
cell[0].style.display = visible ? "" : NONE;
}
if (cell.filter("[" + kendo.attr("colspan") + "]").length) {
colSpan = parseInt(cell.attr(kendo.attr("colspan")), 10);
cell[0].colSpan = (colSpan - hiddenLeafColumnsCount(parent.columns)) || 1;
}
}
}
},
_updateContentWidth: function() {
var that = this;
var tables = that.table.add(that.thead.parent());
tables.css({
width: sumWidths(visibleLeafColumns(visibleNonLockedColumns(that.columns)))
});
that.refresh();
},
showColumn: function(column) {
var that = this,
idx,
length,
cell,
tables,
width,
headerCellIndex,
position,
colWidth,
cols,
columns = that.columns,
virtualScroll = that.virtualScroll || {},
footer = that.footer || that.wrapper.find(".k-grid-footer"),
lockedColumnsCount = that.lockedHeader ? leafDataCells(that.lockedHeader.find(">table>thead")).length : 0,
columnIndex,
originalColumn,
columnLeafIndex,
groupHeaderColumnTemplateColumns,
columnsToShow;
if (!Array.isArray(column)) {
columnsToShow = [column];
} else {
columnsToShow = column;
}
columnsToShow.forEach((column) => {
groupHeaderColumnTemplateColumns = grep(leafColumns(that.columns), function(column) { return column.groupHeaderColumnTemplate; });
if (typeof column == "number") {
columnIndex = column;
column = columns[column];
} else if (isPlainObject(column)) {
$.each(flatColumns(columns), function(index, item) {
if (item === column) {
column = item;
columnIndex = index;
return false;
}
});
} else {
$.each(flatColumns(columns), function(index, item) {
if (item.field === column) {
column = item;
columnIndex = index;
return false;
}
});
}
if (!column || isVisible(column)) {
return;
}
var setColumnVisibility = that._columnVisibilitySetter(column);
if (column.columns && column.columns.length) {
position = columnPosition(column, columns);
originalColumn = flatColumns(that.options.columns)[columnIndex];
setColumnVisibility(column, true);
setCellVisibility(elements($(">table>thead", that.lockedHeader), that.thead, ">tr:eq(" + position.row + ")>th"), position.cell, true);
for (idx = 0; idx < column.columns.length; idx++) {
if (!originalColumn.columns[idx].hidden) {
this.showColumn(column.columns[idx]);
}
}
that._ariaRemoveHiddenColIndex();
that.trigger(COLUMNSHOW, { column: column });
return;
}
columnLeafIndex = inArray(column, leafColumns(columns));
setColumnVisibility(column, true);
that._setParentsVisibility(column, true);
that._templates();
that._updateCols();
that._updateLockedCols();
var container = that.thead;
headerCellIndex = columnLeafIndex;
if (that.lockedHeader && lockedColumnsCount > columnLeafIndex) {
container = that.lockedHeader.find(">table>thead");
} else {
headerCellIndex -= lockedColumnsCount;
}
cell = leafDataCells(container).eq(headerCellIndex);
cell[0].style.display = "";
cell[0].classList.remove("k-hidden");
setCellVisibility(elements($(">table>thead", that.lockedHeader), that.thead, ">tr.k-filter-row>td"), columnLeafIndex, true);
if (footer[0]) {
that._updateCols(footer.find(">.k-grid-footer-wrap>table"));
that._updateLockedCols(footer.find(">.k-grid-footer-locked>table"));
setCellVisibility(footer.find(".k-footer-template>td"), columnLeafIndex, true);
}
if (virtualScroll.columns && !column.locked) {
that._updateContentWidth();
that.trigger(COLUMNSHOW, { column: column });
return;
}
if (that.lockedTable && lockedColumnsCount > columnLeafIndex) {
showColumnCells(that.lockedTable.find(">tbody>tr"), columnLeafIndex);
} else {
showColumnCells(that.tbody.children(), columnLeafIndex - lockedColumnsCount);
}
if (that.lockedTable) {
that._updateTablesWidth();
that._applyLockedContainersWidth();
that._syncLockedContentHeight();
that._syncLockedHeaderHeight();
} else {
tables = that.wrapper.find(">.k-grid-header table").first().add(that.wrapper.find(">.k-grid-footer table").first()).add(that.table);
if (!column.width) {
tables.width("");
} else {
width = 0;
cols = that.thead.prev().find("col");
for (idx = 0, length = cols.length; idx < length; idx += 1) {
colWidth = cols[idx].style.width;
if (cols[idx].className.indexOf("k-hierarchy-col") > -1) {
width += outerWidth(cols[idx]);
continue;
}
if (cols[idx].className.indexOf("k-group-col") > -1) {
width += outerWidth(cols[idx]);
continue;
}
if (colWidth.indexOf("%") > -1) {
width = 0;
break;
}
width += parseInt(colWidth, 10);
}
that._footerWidth = null;
if (width) {
tables.each(function() {
this.style.width = width + PX;
});
that._footerWidth = width;
that._setContentWidth();
}
}
}
that._updateFirstColumnClass();
that._updateStickyColumns();
if (groupHeaderColumnTemplateColumns.length > 0) {
that._renderGroupRows();
}
that._ariaRemoveHiddenColIndex();
that.trigger(COLUMNSHOW, { column: column });
});
},
_columnVisibilitySetter: function(column) {
var col = column || {};
if (isUndefined(col.media)) {
return setColumnVisibility;
} else {
return setColumnMediaVisibility;
}
},
_buildSkeleton: function() {
var visibleColumns = this.virtualCols ? this.virtualCols : visibleLeafColumns(this.columns);
var pageSize = this.dataSource.pageSize() || this.dataSource.total();
var loaderHTML = "";
var colspan;
var groups = this._groups();
var columnsCount = visibleColumns.length + groups;
if (this._hasDetails()) {
columnsCount++;
}
if (this._hasVirtualColumns()) {
colspan = parseInt(this.content.find(TR).first().find("td").first().attr("colspan"), 10);
}
for (var i = 0; i < pageSize; i++) {
loaderHTML += "<tr class='k-table-row' data-skeleton-row>";
for (var j = 0; j < columnsCount; j++) {
if (colspan && !j) {
loaderHTML += "<td colspan='" + colspan + "'><span class='k-skeleton k-skeleton-text k-skeleton-pulse k-table-td'></span></td>";
} else {
loaderHTML += "<td><span class='k-skeleton k-skeleton-text k-skeleton-pulse k-table-td'></span></td>";
}
}
loaderHTML += "</tr>";
}
return loaderHTML;
},
_progress: function(toggle) {
var element = this.element;
var endless = this.options.scrollable && this.options.scrollable.endless;
var loaderType = this.options.loaderType;
var isVirtualization = this.options.scrollable && this.options.scrollable.virtual;
var skeleton;
if (isVirtualization) {
element = this.content;
} else if (this._editContainer && this._editMode() === "popup") {
element = this._editContainer;
} else if (this.lockedContent || endless) {
element = this.wrapper;
} else if (this.element.is("table")) {
element = this.element.parent();
} else if (this.content && this.content.length) {
element = this.content;
}
if (loaderType == "skeleton" && !this._isExport) {
const tbody = element.find("tbody");
if (toggle) {
skeleton = this._buildSkeleton();
if (endless) {
this._currentEndlessRows = tbody.children();
}
tbody.empty().append(skeleton);
} else {
if (endless) {
element.find("[data-skeleton-row]").remove();
tbody.prepend(this._currentEndlessRows);
} else {
element.find(".k-skeleton").closest("tbody").empty();
}
}
} else {
if (this._isExport) {
this._loaderContainer(toggle, { message: this.options.messages.loader.exporting });
} else if (endless && toggle) {
kendo.ui.progress(element, toggle, { height: this.content.height(), top: this.content.parent()[0].offsetTop, opacity: true });
} else {
kendo.ui.progress(element, toggle);
}
}
},
_resize: function(size, force) {
this._syncLockedContentHeight();
this._syncLockedHeaderHeight();
if (this.content) {
this._setContentWidth();
this._setContentHeight();
}
if (this.lockedTable) {
this._syncLockedScroll();
}
if (this.virtualScrollable && (force || this._rowHeight)) {
if (force) {
this._rowHeight = null;
}
this.virtualScrollable.repaintScrollbar();
}
if (this.pager && this.pager.element) {
this.pager.resize(force);
}
if (this._anyStickyColumns()) {
this._updateStickyColumns(false);
}
},
_isActiveInTable: function() {
var active = activeElement();
if (!active) { return false; }
return this.table[0] === active ||
$.contains(this.table[0], active) ||
(this._isLocked() &&
(this.lockedTable[0] === active || $.contains(this.lockedTable[0], active))
);
},
refresh: function(e) {
var that = this,
data = that.dataSource.view(),
navigatable = that.options.navigatable,
virtualScroll = that.virtualScroll || {},
currentIndex,
current = $(that.current()),
isCurrentInHeader = false,
groups = that._groups(),
colspan = groups + visibleLeafColumns(visibleColumns(that.columns)).length,
hasMultiColumnHeaders = grep(that.columns, function(item) {
return item.columns !== undefined$1;
}).length > 0,
contentScrollLeft,
cachedItemsToSkip,
multiColumnHeaderIndex = 0;
if (e && e.action === "itemchange" && (that.editable || that.options.scrollable.endless)) { // skip rebinding if editing is in progress
if (this._editMode() != "popup" || this._editMode() === "popup" && !that._editableIsClosing) { // popup editing animation has not finished yet and the editable is not destoyed
return;
}
}
if (that._shouldMapHights) {
that._mapCachedRowsHeight("get", "uid");
that._shouldMapHights = false;
}
if (virtualScroll.columns) {
that._templates();
}
//someone remove the edited item
if (e && e.action === "remove" && that.editable &&
that.editable.options.model && inArray(that.editable.options.model, e.items) > -1) {
that.editable.options.model.unbind(CHANGE, that._modelChangeHandler);
}
e = e || {};
if (that.trigger("dataBinding", { action: e.action || "rebind", index: e.index, items: e.items })) {
return;
}
if (e.action === SYNC && that._isVirtualEditable()) {
that._destroyEditable();
that._clearEditableState();
}
if (!that._endlessFetchInProgress) {
const component = that._isAdaptive() ? "kendoActionSheet" : "kendoWindow";
if (navigatable && (that._isActiveInTable() || (that._editContainer && that._editContainer.data(component)))) {
isCurrentInHeader = current.is("th");
currentIndex = isCurrentInHeader ? current.parent().children(":not(.k-group-cell)").index(current[0]) : Math.max(that.cellIndex(current), 0);
if (isCurrentInHeader && hasMultiColumnHeaders) {
multiColumnHeaderIndex = current.parent().index();
}
}
that._destroyEditable();
}
if (that.options.scrollable && that.options.scrollable.endless && !that._pdfInitialized) {
clearTimeout(that._progressTimeOut);
that._progressTimeOut = setTimeout(function() {
if (!that._endlessFetchInProgress) {
that._progress(false);
}
}, 250);
} else {
if (!that._isExport) {
that._progress(false);
}
}
if (current.length) {
that._currentRowIndex = current.parent().index();
}
that._hideResizeHandle();
that._data = [];
if (!that.columns.length) {
that._autoColumns(that._firstDataItem(data[0], groups));
colspan = groups + that.columns.length;
}
that._group = groups > 0 || that._group;
if (that._group) {
that._templates();
that._updateCols();
that._updateLockedCols();
if (!that._virtualColScroll) {
that._updateHeader(groups);
}
that._group = groups > 0;
that._groupRows = groupRows(data);
}
if (that.content) {
contentScrollLeft = kendo.scrollLeft(that.content);
}
if (that.options.loaderType !== "skeleton" && e && e.action === "sync" && e.partialUpdate && e.changedItems && e.changedItems.length) {
that._data = that.dataSource.flatView();
e.changedItems.forEach((changedItem) => {
const row = that.tbody.find("[" + kendo.attr("uid") + "=" + changedItem.uid + "]");
if (that._editMode() === INCELL && that.dataSource.options.autoSync && that.dataSource.isLocalTransport()) {
that.trigger(CELLCLOSE, { type: "save", model: e.changedItems[0], container: row.find(".k-edit-cell") });
}
that._displayRow(row);
if (that._groupRows && that._groupRows.length) {
that._rerenderGroupFooterTemplate(changedItem);
}
});
that._progress(false);
that._destroyEditable();
} else {
cachedItemsToSkip = that._skipRerenderItemsCount;
that._renderContent(data, colspan, groups);
if (that.options.scrollable && that.options.scrollable.endless && this.lockedContent) {
that._skipRerenderItemsCount = cachedItemsToSkip;
}
that._renderLockedContent(data, colspan, groups);
}
if (!that._virtualColScroll) {
that._footer();
that._renderNoRecordsContent();
that._togglePagerVisibility();
that._setContentHeight();
that._setContentWidth(that.content && contentScrollLeft);
}
if (that.lockedTable) {
//requires manual trigger of scroll to sync both tables
if (virtualScroll.rows) {
that.content.find(">.k-virtual-scrollable-wrap").trigger("scroll");
} else if (that.touchScroller) {
that.touchScroller.movable.trigger("change");
} else {
that.wrapper.one("scroll", function(e) { e.stopPropagation(); });
that.content.trigger("scroll");
}
}
if (!that._endlessFetchInProgress && !that._rowDropping) {
that._restoreCurrent(currentIndex, isCurrentInHeader, multiColumnHeaderIndex);
}
if (that.touchScroller) {
that.touchScroller.contentResized();
}
if (that.selectable) {
that.selectable.resetTouchEvents();
}
if (that._checkBoxSelection) {
that._toggleHeaderCheckState(false);
}
if (that.options.persistSelection &&
((that.selectable && !kendo.ui.Selectable.parseOptions(that.options.selectable).cell) || that._checkBoxSelection) &&
(that.items().length || that.dataSource._isGroupPaged())) {
that._restoreSelection();
}
if (!that.options.persistSelection) {
that._selectedIds = {};
}
if (that._hasReorderableRows()) {
that._draggableRows();
that._reorderableRows();
}
if (that.options.selectable && that.options.selectable.cellAggregates) {
that._calculateAggregatesForSelected();
}
that._aria();
that.trigger(DATABOUND);
},
_getSchemaIdField: function() {
const that = this;
const model = that.dataSource.options.schema.model;
return isFunction(model) ? model.fn.idField : model && model.id;
},
_restoreCurrent: function(currentIndex, isCurrentInHeader, multiColumnHeaderIndex) {
if (currentIndex === undefined$1 || currentIndex < 0) {
return;
}
this._removeCurrent();
if (isCurrentInHeader) {
this._setCurrent(this.thead.find(`tr:eq(${multiColumnHeaderIndex}) th:not(.k-group-cell)`).eq(currentIndex), false, this._hasVirtualColumns());
} else {
var rowIndex = 0;
var virtualScroll = this.virtualScroll || {};
if (this._rowVirtualIndex) {
if (virtualScroll.rows) {
rowIndex = this.virtualScrollable.position(this._rowVirtualIndex);
} else {
rowIndex = this._rowVirtualIndex;
}
} else if (this._currentRowIndex) {
rowIndex = this._currentRowIndex;
} else {
currentIndex = 0;
}
var row = $();
var colspan;
if (this.lockedTable) {
if (this._shouldFocusInLastRow) {
row = this.lockedTable.find(">tbody>tr").last();
} else if (this._shouldFocusInFirstRow) {
row = this.lockedTable.find(">tbody>tr").first();
} else {
row = this.lockedTable.find(">tbody>tr").eq(rowIndex);
}
}
let nonLockedRow;
if (this._shouldFocusInLastRow) {
nonLockedRow = this.tbody.children().last();
} else if (this._shouldFocusInFirstRow) {
nonLockedRow = this.tbody.children().first();
} else {
nonLockedRow = this.tbody.children().eq(rowIndex);
}
row = row.add(nonLockedRow);
if (this._hasVirtualColumns()) {
colspan = parseInt(row.find("td").first().attr("colspan"), 10);
currentIndex = this._virtualCellIndex - (colspan > 1 ? colspan - 1 : 0);
}
var td = row.find(">td:not(.k-group-cell):not(.k-hierarchy-cell)")
.eq(currentIndex);
if (!td.length || currentIndex < 0) {
return;
}
if (this._hasVirtualColumns()) {
this._setCurrent(td, true, true);
} else {
this._setCurrent(td);
}
}
if (this._current) {
focusTable(this.table, true);
}
},
_restoreSelection: function() {
var that = this,
allRows = that.items(),
selectedRows,
id = that._getSchemaIdField();
selectedRows = grep(allRows, function(row) {
var dataItemKey = that.dataItem(row)[id];
if (that._selectedIds[dataItemKey]) {
return row;
}
});
that.select(selectedRows);
},
_getSelectedRowUids: function() {
var that = this,
selected = that.select(),
row,
uid,
result = [];
for (let i = 0; i < selected.length; i++) {
row = $(selected[i]);
if (kendo.ui.Selectable.parseOptions(that.options.selectable).cell) {
row = row.closest(TR);
}
uid = row.data("uid");
if (result.indexOf(uid) === -1) {
result.push(uid);
}
}
return result;
},
_getSelectedColumnFields: function() {
var that = this,
selected = that.select(),
field,
index,
visibleColumns = visibleLeafColumns(that.columns).filter(col => !col.selectable && !col.draggable & !col.command),
result = [];
// If the mode is in row selection, then return all of the visible columns.
if (!kendo.ui.Selectable.parseOptions(that.options.selectable).cell) {
return visibleColumns.map(vc => vc.field);
}
for (let i = 0; i < selected.length; i++) {
index = $(selected[i]).index();
field = that.thead.find("th:eq(" + index + ")").data("field");
if (result.indexOf(field) === -1) {
result.push(field);
}
}
return result;
},
_cleanupDetailItems: function() {
var that = this;
if (that._hasDetails()) {
that.tbody.find(".k-detail-cell").empty();
}
},
_renderContent: function(data, colspan, groups) {
var that = this,
idx,
length,
html = "",
isLocked = that.lockedContent != null,
endlessAppend = null,
skipLastGroup,
flatViewLength,
scrollable = that.options.scrollable,
templates = {
rowTemplate: that.rowTemplate,
altRowTemplate: that.altRowTemplate,
groupFooterTemplate: that.groupFooterTemplate,
groupHeaderColumnTemplate: that.groupHeaderColumnTemplate
};
if (scrollable && scrollable.endless && !that.dataSource.options.endless) {
that._skipRerenderItemsCount = 0;
if (that.content) {
that.content[0].scrollTop = 0;
}
}
endlessAppend = that._skipRerenderItemsCount > 0;
colspan = isLocked ? colspan - visibleLeafColumns(visibleLockedColumns(that.columns)).length : colspan;
if (groups > 0) {
colspan = isLocked ? colspan - groups : colspan;
if (that.detailTemplate) {
colspan++;
}
if (that.groupFooterTemplate) {
that._groupAggregatesDefaultObject = that.dataSource.aggregates();
}
if (that.options.scrollable.endless) {
flatViewLength = that.dataSource.flatView().length;
}
for (idx = 0, length = data.length; idx < length; idx++) {
if (!that._skippedGroups) {
that._skippedGroups = [];
}
skipLastGroup = flatViewLength && idx === data.length - 1 && flatViewLength !== that.dataSource.total();
html += that._groupRowHtml(data[idx], colspan, 0, isLocked ? groupRowLockedContentBuilder : groupRowBuilder, templates, isLocked, skipLastGroup, false);
}
} else {
html += that._rowsHtml(data, templates);
}
if (endlessAppend) {
that.tbody.append(html);
kendo.applyStylesFromKendoAttributes(that.tbody, ["display", "left", "right"]);
clearTimeout(that._endlessFetchTimeOut);
that._endlessFetchTimeOut = setTimeout(function() {
if (that._groupToCollapse) {
that.collapseGroup(that._groupToCollapse);
that._groupToCollapse = null;
}
});
that._endlessFetchInProgress = null;
} else {
that.tbody = appendContent(that.tbody, that.table, html, this.options.size);
}
},
_renderGroupRows: function() {
var that = this,
data = that._groupRows,
groupRows = that.wrapper.find(DOT + GROUPING_ROW),
groups = that._groups(),
groupRowBuilderFunc,
isLocked = that.lockedContent != null,
columns,
colspan,
group,
field,
column,
template,
text,
groupHeaderData,
tableContainer,
isInLockedContainer,
prevElement,
newGroupRowElement,
currentRow,
level,
groupHeaderColumnTemplate,
firstColumnGroupData;
groupRows.each(function(index, row) {
currentRow = $(row);
tableContainer = currentRow.closest("table").parent();
isInLockedContainer = tableContainer.is("." + CONTENTRLOCKEDCONTAINER);
columns = isInLockedContainer ? visibleLeafColumns(visibleColumns(lockedColumns(that.columns))) : visibleLeafColumns(visibleColumns(nonLockedColumns(that.columns)));
level = currentRow.find("." + GROUPCELLCLASS).length;
if (isLocked) {
groupRowBuilderFunc = isInLockedContainer ? groupRowBuilder : groupRowLockedContentBuilder;
colspan = isInLockedContainer ? columns.length + groups - level : columns.length;
}
else {
groupRowBuilderFunc = groupRowBuilder;
colspan = columns.length + groups - level;
}
group = index >= data.length ? data[index - data.length] : data[index];
field = group.field;
column = grep(leafColumns(that.columns), function(column) { return column.field == field; })[0] || {};
firstColumnGroupData = !column.groupHeaderTemplate && visibleColumns(that.columns)[0].groupHeaderColumnTemplate ? visibleColumns(that.columns)[0] : false;
template = column.groupHeaderTemplate ? column.groupHeaderTemplate : visibleColumns(that.columns)[0].groupHeaderColumnTemplate;
text = (column.title && (that.options.encodeTitles ? htmlEncode(column.title, true) : column.title) || htmlEncode(field, true)) + ': ' + formatGroupValue(group.value, column.format, column.values, column.encoded);
groups = groups;
groupHeaderData = that._groupData(group, false, firstColumnGroupData);
groupHeaderColumnTemplate = isInLockedContainer ? that.lockedGroupHeaderColumnTemplate : that.groupHeaderColumnTemplate;
if (template) {
text = typeof template === FUNCTION ? template(groupHeaderData) : kendo.template(template)(groupHeaderData);
}
prevElement = currentRow.prev().length ? currentRow.prev() : currentRow.parent();
newGroupRowElement = $(groupHeaderColumnTemplate ?
groupHeaderColumnTemplate(extend({}, groupHeaderData, { groupCells: level, colspan: groups - level, text: text })) :
groupRowBuilderFunc(colspan, level, text, null, null, null, isRtl)
);
kendo.applyStylesFromKendoAttributes(newGroupRowElement, ["display", "left", "right"]);
if (prevElement.is("tbody")) {
prevElement.prepend(newGroupRowElement);
}
else {
prevElement.after(newGroupRowElement);
}
currentRow.remove();
});
},
_renderLockedContent: function(data, colspan, groups) {
var html = "",
idx,
length,
skipLastGroup,
endlessAppend = null,
flatViewLength,
templates = {
rowTemplate: this.lockedRowTemplate,
altRowTemplate: this.lockedAltRowTemplate,
groupFooterTemplate: this.lockedGroupFooterTemplate,
groupHeaderColumnTemplate: this.lockedGroupHeaderColumnTemplate
};
if (this.lockedContent) {
var table = this.lockedTable;
endlessAppend = this._skipRerenderItemsCount > 0;
if (groups > 0) {
colspan = colspan - visibleColumns(leafColumns(nonLockedColumns(this.columns))).length;
if (this.options.scrollable.endless) {
flatViewLength = this.dataSource.flatView().length;
}
for (idx = 0, length = data.length; idx < length; idx++) {
skipLastGroup = flatViewLength && idx === data.length - 1 && flatViewLength !== this.dataSource.total();
html += this._groupRowHtml(data[idx], colspan, 0, groupRowBuilder, templates, false, skipLastGroup, true);
}
} else {
html = this._rowsHtml(data, templates);
}
if (endlessAppend) {
table.children("tbody").append(html);
} else {
appendContent(table.children("tbody"), table, html, this.options.size);
}
this._syncLockedContentHeight();
}
},
_togglePagerVisibility: function() {
if (this.options.pageable.alwaysVisible === false) {
this.wrapper.find(".k-grid-pager").toggle(this.dataSource.total() >= this.dataSource.pageSize());
}
},
_adjustRowsHeight: function(table1, table2) {
var rows = table1[0].rows,
length = rows.length,
idx,
rows2 = table2[0].rows,
containers = table1.add(table2),
containersLength = containers.length,
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]) {
rows[idx].style.height = rows2[idx].style.height = heights[idx] + PX;
}
}
for (idx = 0; idx < containersLength; idx++) {
containers[idx].style.display = "";
}
}
});
if (kendo.ExcelMixin) {
kendo.ExcelMixin.extend(Grid.prototype);
}
if (kendo.PDFMixin) {
kendo.PDFMixin.extend(Grid.prototype);
Grid.prototype._drawPDF_autoPageBreak = function(progress) {
var grid = this;
var result = new $.Deferred();
var dataSource = grid.dataSource;
var allPages = grid.options.pdf.allPages;
var origBody = grid.wrapper.find('> table > tbody, .k-grid-content > table > tbody').first();
var cont = $("<div>")
.css({ position: "absolute", left: -1e4, top: -1e4 });
var clone;
grid.toggleUnexportableColumns(grid.columns);
clone = grid.wrapper.clone().css({
height: AUTO, width: AUTO
}).appendTo(cont);
clone.find(".k-grid-content").css({ height: AUTO, width: AUTO, overflow: "visible" });
clone.find('> table, .k-grid-header table, .k-grid-content > table, .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, .k-auto-scrollable").css({ paddingRight: 0 });
var body = clone.find('> table > tbody, .k-grid-content > table > tbody').first().empty();
var startingPage = dataSource.page();
function resolve() {
if (allPages && startingPage !== undefined$1) {
dataSource.one("change", draw);
dataSource.page(startingPage);
} else {
grid.refresh();
draw();
}
}
function draw() {
cont.appendTo(document.body);
var options = $.extend({}, grid.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);
grid.toggleUnexportableColumns(grid.columns, true);
})
.fail(function(err) {
result.reject(err);
});
}
function renderPage() {
var pageNum = dataSource.page();
var totalPages = allPages ? dataSource.totalPages() : 1;
body.append(origBody.children("tr:not(.k-detail-row)"));
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();
};
Grid.prototype.toggleUnexportableColumns = function(columns, restore) {
var length = columns.length;
var column;
var exportable;
var visibleInExport;
var visibleInExportOnly;
for (var i = 0; i < length; i++) {
column = columns[i];
exportable = column.exportable;
if (!restore) {
if (typeof column.exportable === "object") {
exportable = column.exportable.pdf;
}
visibleInExport = !column.hidden && exportable !== false;
visibleInExportOnly = column.hidden && exportable === true;
exportable = visibleInExport || visibleInExportOnly;
if (!exportable && !column.hidden) {
column._toggledDuringExport = true;
this.hideColumn(column);
} else if (exportable && column.hidden) {
column._toggledDuringExport = true;
this.showColumn(column);
} else if (exportable && column.columns) {
this.toggleUnexportableColumns(column.columns);
}
} else {
if (column._toggledDuringExport) {
column._toggledDuringExport = false;
if (column.hidden) {
this.showColumn(column);
} else {
this.hideColumn(column);
}
} else if (column.columns) {
this.toggleUnexportableColumns(column.columns, restore);
}
}
}
};
Grid.prototype._drawPDF = function(progress) {
var grid = this;
if (grid.options.pdf.paperSize && grid.options.pdf.paperSize != AUTO) {
return grid._drawPDF_autoPageBreak(progress);
}
var result = new $.Deferred();
var dataSource = grid.dataSource;
var allPages = grid.options.pdf.allPages;
// 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() {
grid.toggleUnexportableColumns(grid.columns);
grid._drawPDFShadow({
width: grid.wrapper.width()
}, {
avoidLinks: grid.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
};
grid.toggleUnexportableColumns(grid.columns, true);
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();
};
}
function syncTableHeight(table1, table2) {
table1 = table1[0];
table2 = table2[0];
if (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;
}
}
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 getCommand(commands, name) {
var idx, length, command;
if (typeof commands === STRING && commands === name) {
return commands;
}
if (isPlainObject(commands) && commands.name === name) {
return commands;
}
if (isArray(commands)) {
for (idx = 0, length = commands.length; idx < length; idx++) {
command = commands[idx];
if ((typeof command === STRING && command === name) || (command.name === name)) {
return command;
}
}
}
return null;
}
function compareElements(element, toCompare) {
if (element.length !== toCompare.length) {
return false;
}
for (var i = 0; i < element.length; i++) {
if (element[i] !== toCompare[i]) {
return false;
}
}
return true;
}
function focusTable(table, direct) {
if (!table || table.length === 0) {
return;
}
if (direct === true) {
table = $(table);
var scrollLeft = kendo.scrollLeft(table.parent());
kendo.focusElement(table);
kendo.scrollLeft(table.parent(), scrollLeft);
} else {
$(table).one("focusin", function(e) { e.preventDefault(); }).trigger("focus");
}
}
function isColumnGroupable(grid, column) {
return grid.options.groupable && (column.groupable || column.groupable === undefined$1);
}
function isGroupedBy(groups, field) {
return !!$.grep(groups, function(item) {
return item.field === field;
}).length;
}
function isColumnEditable(column, model) {
if (!column.field || column.selectable) {
return false;
}
if (model.editable && !model.editable(column.field)) {
return false;
}
if (column.editable && !column.editable(model)) {
return false;
}
return true;
}
function isInputElement(element) {
return $(element).is(INPUT_SELECTORS);
}
function tableClick(e) {
var that = this,
currentTarget = $(e.currentTarget),
isHeader = currentTarget.is("th"),
table = this.table.add(this.lockedTable),
headerTable = this.thead.parent().add($(">table", this.lockedHeader)),
isInput = isInputElement(e.target),
preventScroll = $(e.target).is('.k-checkbox'),
target = $(e.target),
currentTable = currentTarget.closest("table")[0];
if (isInput && currentTarget.find(kendo.roleSelector("filtercell")).length) {
this._setCurrent(currentTarget, null, null, true);
return;
}
if (currentTable !== table[0] && currentTable !== table[1] && currentTable !== headerTable[0] && currentTable !== headerTable[1]) {
return;
}
if (target.is(CARET_ALT_RIGHT + "," + CARET_ALT_DOWN)) {
return;
}
if (this.options.navigatable) {
this._focusFocusable(currentTarget, currentTarget, false, preventScroll, e);
}
if (isHeader || !isInput) {
setTimeout(function() {
var activeEl = $(kendo._activeElement());
if ((activeEl.hasClass("k-widget") || activeEl.hasClass("k-dropdownlist") || activeEl.is(".k-upload .k-upload-button")) && !activeEl.hasClass("k-grid-pager") || activeEl.hasClass("k-select-checkbox")) {
return;
}
//Only if input element is not selected yet and it is not descendant of the grid's table
if (that.table && (activeEl.is(CHECKBOXINPUT) || !isInputElement(kendo._activeElement()) || !$.contains(currentTable, kendo._activeElement()))) {
//DOMElement.focus() only for header, because IE doesn't really focus the table
focusTable(that.table[0], true);
}
});
}
if (isHeader && !kendo.support.touch) {
e.preventDefault(); //if any problem occurs, call preventDefault only for the clicked header links
}
}
function leftMostPosition(element, rtl) {
if (!rtl) {
return 0;
}
var result = 0;
if (kendo.support.browser.webkit) {
result = element.width();
}
return result;
}
function parseVirtualSettings(options) {
var asLowerString;
if (typeof options === "string") {
asLowerString = options.toLowerCase();
if (asLowerString === "true") {
return {
rows: true
};
} else {
return {
rows: asLowerString.indexOf("rows") > -1,
columns: asLowerString.indexOf("columns") > -1
};
}
} else if (options === true) {
return {
rows: true
};
}
}
function isElementVisibleInWrapper(wrapper, element) {
var offsetTop;
var halfHeight;
if (!wrapper) {
return false;
}
element = $(element);
if (element[0] && contains(wrapper[0], element[0])) {
offsetTop = element.offset().top - wrapper.offset().top;
halfHeight = element.outerHeight() / 2;
if ((offsetTop >= 0 || math.abs(offsetTop) <= halfHeight) && (math.floor(offsetTop + halfHeight) <= wrapper.height())) {
return true;
}
}
return false;
}
function isInEdit(cell) {
return cell &&
(cell.hasClass("k-edit-cell") ||
cell.parent().hasClass("k-grid-edit-row"));
}
function groupHtmlBuilder(groupHeaderColumnTemplate, groupHeaderBuilder, colspan, templateColspan, groupData, level, text, expanded, group, isGroupPaged) {
var html;
if (groupHeaderColumnTemplate) {
html = groupHeaderColumnTemplate(extend({}, groupData, {
groupCells: level,
colspan: templateColspan,
text: text,
expanded: expanded,
isRtl: isRtl,
uid: group.uid
}));
} else {
html = groupHeaderBuilder(colspan, level, text, expanded, group.uid, isGroupPaged, isRtl);
}
return html;
}
function groupCellBuilder(headerTemplateIndex) {
return ({ colspan, text, expanded, isRtl }) => {
let collapsedClass = `caret-alt-${isRtl ? 'left' : 'right'}`;
return `<td class="k-table-td" colspan="${colspan + headerTemplateIndex}">` +
'<p class="k-reset">' +
kendo.ui.icon($(`<a href="\\#" tabindex="-1" ${ARIA_LABEL}="${(expanded ? COLLAPSE : EXPAND)}"></a>`), { icon: (expanded ? 'caret-alt-down' : collapsedClass) }) + text +
`</p></td>${new Array(colspan + headerTemplateIndex).join("<td hidden group-header-spanned-hidden></td>")}`;
};
}
function groupCellLockedContentBuilder(headerTemplateIndex) {
return '<td class="k-table-td" colspan="' + headerTemplateIndex + '">' +
`<p class="k-reset"> </p></td>${new Array(headerTemplateIndex).join("<td hidden group-header-spanned-hidden></td>")}`;
}
function groupRowBuilder(colspan, level, text, expanded, uid, includeAdditionalData, isRtl) {
return '<tr ' + (includeAdditionalData ? 'data-group-uid="' + uid + '"' : '') + 'class="k-table-group-row k-grouping-row k-table-row">' + groupCells(level) +
'<td class="k-table-td" colspan="' + colspan + '" aria-expanded="' + !!expanded + '">' +
'<p class="k-reset">' +
kendo.ui.icon($('<a href="#" tabindex="-1" ' + ARIA_LABEL + '="' + (expanded ? COLLAPSE : EXPAND) + '"></a>'), { icon: (expanded ? 'caret-alt-down' : `caret-alt-${isRtl ? 'left' : 'right'}`) }) + text +
`</p></td>${new Array(colspan).join("<td hidden group-header-spanned-hidden></td>")}</tr>`;
}
function groupRowLockedContentBuilder(colspan) {
return '<tr class="k-table-group-row k-grouping-row k-table-row">' +
'<td class="k-table-td" colspan="' + colspan + '" aria-expanded="true">' +
`<p class="k-reset"> </p></td>${new Array(colspan).join("<td hidden group-header-spanned-hidden></td>")}</tr>`;
}
function toggleRow(row, visible) {
row = $(row)[0];
if (visible) {
row.style.display = "";
} else {
row.style.display = NONE;
}
}
function htmlEncode(value, backslashEscapeQuotes) {
var ampRegExp = /&/g,
ltRegExp = /</g,
quoteRegExp = /"/g,
aposRegExp = /'/g,
gtRegExp = />/g;
return ("" + value)
.replace(ampRegExp, "&")
.replace(ltRegExp, "<")
.replace(gtRegExp, ">")
.replace(quoteRegExp, function(match) {
if (backslashEscapeQuotes) {
return "\\" + match;
}
return """;
})
.replace(aposRegExp, "'");
}
function isEmptyString(value) {
return !/\S/.test(value);
}
function getTitle(field, columns) {
return columns.filter(function(col) {
return col.field === field;
})[0].title || field;
}
function exportDataSort(a, b) {
return this.dataSource.indexOf(this.dataSource.getByUid(a.uid)) - this.dataSource.indexOf(this.dataSource.getByUid(b.uid));
}
function isExcelExportableColumn(column) {
return !(column.exportable === false || (column.exportable && column.exportable.excel === false));
}
ui.plugin(Grid);
ui.plugin(VirtualScrollable);
extend(kendo.ui.grid, {
defaultBodyContextMenu: defaultBodyContextMenu,
defaultHeadContextMenu: defaultHeadContextMenu,
defaultGroupsContextMenu: defaultGroupsContextMenu
});
})(window.kendo.jQuery);
var kendo$1 = kendo;
exports.__meta__ = __meta__;
exports.default = kendo$1;