@syncfusion/ej2-grids
Version:
Feature-rich JavaScript datagrid (datatable) control with built-in support for editing, filtering, grouping, paging, sorting, and exporting to Excel.
922 lines (921 loc) • 44.3 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
import { createElement, formatUnit, isNullOrUndefined, updateCSSText, closest, extend, Browser } from '@syncfusion/ej2-base';
import { ContentRender } from './content-renderer';
import * as literals from '../base/string-literals';
import { getScrollBarWidth, ensureLastRow, ensureFirstRow, parentsUntil, getEditedDataIndex } from '../base/util';
import * as events from '../base/constant';
import { dataReady, modelChanged, contentReady } from '../base/constant';
import { InterSectionObserver } from '../services/intersection-observer';
/**
* @hidden
*/
var DomVirtualElementHandler = /** @class */ (function () {
function DomVirtualElementHandler() {
}
DomVirtualElementHandler.prototype.renderWrapper = function (height) {
this.wrapper = createElement('div', { className: 'e-virtualtable e-dom-virtualtable' });
updateCSSText(this.wrapper, "min-height: " + formatUnit(height) + "; position: absolute;");
this.wrapper.appendChild(this.table);
this.content.appendChild(this.wrapper);
};
DomVirtualElementHandler.prototype.renderPlaceHolder = function () {
this.placeholder = createElement('div', { className: 'e-virtualtrack e-dom-virtualtrack' });
updateCSSText(this.placeholder, 'position: relative;');
this.content.appendChild(this.placeholder);
};
DomVirtualElementHandler.prototype.renderVerticalScrollbar = function () {
this.verticalScrollbar = createElement('div', { className: 'e-virtual-vertical-scrollbar e-dom-virtual-vertical-scrollbar' });
this.gridContent.appendChild(this.verticalScrollbar);
this.verticalScrollerContainer = createElement('div', { className: 'e-virtual-vertical-track e-dom-virtual-vertical-track' });
this.verticalScrollbar.appendChild(this.verticalScrollerContainer);
};
DomVirtualElementHandler.prototype.adjustTable = function (yValue) {
updateCSSText(this.wrapper, "transform: translateY(" + yValue + "px);");
};
DomVirtualElementHandler.prototype.setVirtualHeight = function (height) {
updateCSSText(this.placeholder, "height: " + (!isNullOrUndefined(height) ? height + "px" : '0px') + ";");
};
return DomVirtualElementHandler;
}());
export { DomVirtualElementHandler };
/**
* @hidden
*/
var DomVirtualContentRenderer = /** @class */ (function (_super) {
__extends(DomVirtualContentRenderer, _super);
function DomVirtualContentRenderer(parent, locator) {
var _this = _super.call(this, parent, locator) || this;
_this.virtualEle = new DomVirtualElementHandler();
_this.totalRecords = 0;
_this.rowHeight = _this.parent.getRowHeight();
_this.currentScrollTop = 0;
_this.prevScrollTop = -1;
_this.prevStartIndex = -1;
/**
* @hidden
*/
_this.currentStartIndex = 0;
_this.preventScroll = false;
_this.expandedDetailRows = new Map();
_this.pendingSelectIndex = -1;
_this.storedVirtualHeight = 0;
_this.rowHeightCache = new Map();
_this.dynamicHeightSum = 0;
_this.dynamicRowCount = 0;
_this.activeKey = '';
_this.rowIndex = 0;
_this.cellIndex = 0;
_this.isCancel = false;
/** @hidden */
_this.offsets = {};
/** @hidden */
_this.offsetKeys = [];
_this.actions = ['filtering', 'searching', 'grouping', 'ungrouping'];
_this.count = 0;
_this.maxPage = 0;
_this.previousPage = 0;
_this.pageSkip = -1;
_this.pageTake = -1;
_this.isNormaledit = _this.parent.editSettings.mode === 'Normal';
_this.editedRowIndex = undefined;
_this.isAdd = false;
/** @hidden */
_this.virtualData = {};
_this.emptyRowData = {};
_this.locator = locator;
_this.widthServices = locator.getService('widthService');
if (_this.parent.isRowDomVirtualization()) {
_this.parent.on(events.selectVirtualRow, _this.selectVirtualRow, _this);
_this.parent.on(events.virtaulCellFocus, _this.domVirtualCellFocus, _this);
_this.parent.on(events.resetVirtualFocus, _this.resetVirtualFocus, _this);
}
_this.parent.on(events.applyDomVirtualRowHeight, _this.onApplyDomVirtualRowHeight, _this);
_this.parent.on(events.refreshExpandandCollapse, _this.onGroupExpandCollapse, _this);
_this.parent.on(dataReady, _this.onDataReady, _this);
_this.parent.on(events.setVirtualPageQuery, _this.setDomVirtualPageQuery, _this);
_this.parent.on(events.virtualScrollEditActionBegin, _this.editActionBegin, _this);
_this.parent.on(events.virtualScrollAddActionBegin, _this.addActionBegin, _this);
_this.parent.on(events.virtualScrollEdit, _this.restoreEdit, _this);
_this.parent.on(events.virtualScrollEditSuccess, _this.editSuccess, _this);
_this.parent.on(events.editReset, _this.resetIsedit, _this);
_this.parent.on(events.getVirtualData, _this.getVirtualData, _this);
_this.parent.on(events.virtualScrollEditCancel, _this.editCancel, _this);
_this.boundActionComplete = _this.actionComplete.bind(_this);
_this.boundActionBegin = _this.actionBegin.bind(_this);
_this.parent.addEventListener(events.actionComplete, _this.boundActionComplete);
_this.parent.addEventListener(events.actionBegin, _this.boundActionBegin);
return _this;
}
DomVirtualContentRenderer.prototype.renderTable = function () {
_super.prototype.renderTable.call(this);
this.virtualEle.table = this.getTable();
this.virtualEle.gridContent = this.parent.element.querySelector('.' + literals.gridContent);
this.virtualEle.content = this.content = this.getPanel().querySelector('.' + literals.content);
updateCSSText(this.virtualEle.gridContent, 'position: relative;');
updateCSSText(this.virtualEle.content, 'position: relative;');
this.virtualEle.renderWrapper(this.parent.height);
this.virtualEle.renderPlaceHolder();
if (this.parent.isRowDomVirtualization()) {
this.virtualEle.renderVerticalScrollbar();
updateCSSText(this.virtualEle.verticalScrollbar, "width: " + (getScrollBarWidth() + 1) + "px; overflow-x: scroll;");
}
this.bindScrollEvents();
};
DomVirtualContentRenderer.prototype.refreshContentRows = function (args) {
if (args === void 0) { args = {}; }
var gObj = this.parent;
if (gObj.isRowDomVirtualization()) {
if (!gObj.currentViewData || gObj.currentViewData.length === 0) {
return;
}
if (args.requestType && args.requestType !== 'dom-virtualscroll') {
this.expandedDetailRows.clear();
this.rowHeightCache.clear();
this.dynamicHeightSum = 0;
this.dynamicRowCount = 0;
this.storedVirtualHeight = 0;
}
if (this.virtualEle.gridContent && this.virtualEle.gridContent.style.position !== 'relative') {
updateCSSText(this.virtualEle.gridContent, 'position: relative;');
}
if (this.virtualEle.content && this.virtualEle.content.style.position !== 'relative') {
updateCSSText(this.virtualEle.content, 'position: relative;');
}
var isGrouped = !!(gObj.groupSettings && gObj.groupSettings.columns && gObj.groupSettings.columns.length);
if (isGrouped) {
var gen = this.generator;
gen.buildGroupRowObj(gObj.currentViewData, args.requestType);
this.totalRecords = gen.getVisibleGroupRows().length;
}
else {
this.totalRecords = gObj.currentViewData.length;
if (this.parent.enableVirtualization) {
this.totalRecords = gObj.totalDataRecordsCount;
}
}
if (this.parent.frozenRows) {
this.totalRecords -= this.parent.frozenRows;
}
this.initializeRowHeight();
this.setVirtualDimensions();
var startIndex = this.getStartIndex(this.currentScrollTop);
var endIndex = this.getEndIndex(startIndex);
if (this.parent.enableVirtualization) {
var startPage = this.getPageFromIndex(startIndex);
this.parent.setProperties({ pageSettings: { currentPage: startPage } }, true);
var pageSize = this.parent.pageSettings.pageSize;
var pageOffset = (this.parent.pageSettings.currentPage - 1) * pageSize;
this.currentStartIndex = Math.max(startIndex, pageOffset);
}
else {
this.currentStartIndex = startIndex;
}
var frozenOffset = this.parent.frozenRows;
var isScrollRequest = args.requestType === 'dom-virtualscroll';
args.startIndex = startIndex + (isScrollRequest ? frozenOffset : 0);
args.endIndex = endIndex + (isScrollRequest ? frozenOffset : 0);
this.prevStartIndex = startIndex;
}
if (this.parent.enableVirtualization && !gObj.isInitialLoad && args.requestType !== 'dom-virtualscroll') {
var startIndex = this.getStartIndex(this.currentScrollTop);
var endIndex = this.getEndIndex(startIndex);
var currentData = this.parent.getCurrentViewRecords().length;
if (currentData > 0 && endIndex > currentData) {
this.checkAndFetchCrossPageData(startIndex);
return;
}
}
_super.prototype.refreshContentRows.call(this, args);
};
DomVirtualContentRenderer.prototype.appendContent = function (tbody, frag, args, tableName) {
_super.prototype.appendContent.call(this, tbody, frag, args, tableName);
if (this.parent.isRowDomVirtualization()) {
if (this.isAutoRowHeight()) {
this.measureRowHeights(tbody);
}
if (this.parent.enableVirtualization) {
this.refreshOffsets();
if (args.requestType === 'dom-virtualscroll') {
this.parent.removeMaskRow();
}
}
this.setVirtualDimensions();
this.virtualEle.adjustTable(this.getRowTopOffset(this.currentStartIndex));
if (this.pendingSelectIndex >= 0) {
var targetRow = this.parent.getRowByIndex(this.pendingSelectIndex);
if (targetRow) {
var indexToSelect = this.pendingSelectIndex;
this.pendingSelectIndex = -1;
this.parent.selectRow(indexToSelect);
}
}
this.focusCell();
this.restoreEdit(args);
}
};
DomVirtualContentRenderer.prototype.renderEmpty = function (tbody) {
this.getTable().appendChild(tbody);
if (this.parent.frozenRows || this.parent.pinnedTopRowModels.length) {
this.parent.getHeaderContent().querySelector(literals.tbody).innerHTML = '';
}
this.virtualEle.adjustTable(0);
this.virtualEle.setVirtualHeight(0);
if (this.virtualEle.verticalScrollerContainer) {
updateCSSText(this.virtualEle.verticalScrollerContainer, 'height: 0px;');
}
};
DomVirtualContentRenderer.prototype.bindScrollEvents = function () {
var _this = this;
var userThrottle = this.parent.domVirtualizationSettings.scrollThrottle;
var browserDefault = Browser.info.name === 'chrome' ? 200 : 100;
var scrollThrottle = (this.parent.enableVirtualization && this.parent.isRowDomVirtualization())
? (userThrottle > browserDefault ? userThrottle : browserDefault)
: userThrottle;
var opt = {
container: this.content,
pageHeight: this.content.clientHeight * 2,
debounceEvent: false,
axes: ['Y'],
verticalScrollbar: this.virtualEle.verticalScrollbar,
scrollThrottle: scrollThrottle
};
this.observer = new InterSectionObserver(this.virtualEle.wrapper, opt);
var fn = function () {
var pageHeight = _this.storedVirtualHeight > 0 ? _this.storedVirtualHeight
: _this.content.clientHeight * 2;
_this.observer.setPageHeight(pageHeight);
_this.observer.observe(function (scrollArgs) { return _this.domScrollListener(scrollArgs); }, _this.onEntered());
_this.parent.off(contentReady, fn);
};
this.parent.on(contentReady, fn, this);
};
DomVirtualContentRenderer.prototype.domScrollListener = function (scrollArgs) {
if (this.preventScroll) {
return;
}
if (!this.parent.isRowDomVirtualization() || this.totalRecords === 0) {
return;
}
this.currentScrollTop = scrollArgs.offset.top;
this.prevScrollTop = this.currentScrollTop;
this.scrollAfterEdit();
var startIndex = this.getStartIndex(this.currentScrollTop);
if (startIndex === this.prevStartIndex) {
return;
}
if (this.parent.enableVirtualization) {
this.checkAndFetchCrossPageData(startIndex);
}
else {
this.refreshContentRows({ requestType: 'dom-virtualscroll' });
}
};
DomVirtualContentRenderer.prototype.checkAndFetchCrossPageData = function (startIndex) {
var pageSize = this.parent.pageSettings.pageSize;
var endIndex = this.getEndIndex(startIndex);
var startPage = this.getPageFromIndex(startIndex);
var endPage = this.getPageFromIndex(Math.max(0, endIndex - 1));
var isCrossPage = endPage > startPage;
var newSkip = isCrossPage ? (startPage - 1) * pageSize : -1;
var newTake = isCrossPage ? (endPage - startPage + 1) * pageSize : -1;
var pageChanged = startPage !== this.parent.pageSettings.currentPage;
var rangeChanged = newSkip !== this.pageSkip;
if (pageChanged || rangeChanged) {
this.pageSkip = newSkip;
this.pageTake = newTake;
this.parent.setProperties({ pageSettings: { currentPage: startPage } }, true);
if (this.previousPage !== startPage || rangeChanged) {
this.previousPage = startPage;
if (this.parent.enableVirtualMaskRow) {
this.parent.showMaskRow();
this.parent.addShimmerEffect();
}
this.parent.notify(modelChanged, { requestType: 'dom-virtualscroll' });
}
}
};
DomVirtualContentRenderer.prototype.onEntered = function () {
var _this = this;
return function (_element, _current, direction, e) {
if (_this.parent.enableVirtualization && _this.parent.isRowDomVirtualization()
&& (direction === 'down' || direction === 'up')) {
var pageSize = _this.parent.pageSettings.pageSize;
_this.currentScrollTop = e.top;
var startIndex = _this.getStartIndex(_this.currentScrollTop);
var endIndex = _this.getEndIndex(startIndex);
var startPage = _this.getPageFromIndex(startIndex);
var endPage = _this.getPageFromIndex(Math.max(0, endIndex - 1));
var isCrossPage = endPage > startPage;
var newSkip = isCrossPage ? (startPage - 1) * pageSize : -1;
var pageChanged = startPage !== _this.parent.pageSettings.currentPage;
var rangeChanged = newSkip !== _this.pageSkip;
if ((pageChanged || rangeChanged) && _this.parent.enableVirtualMaskRow) {
_this.parent.showMaskRow();
}
else {
_this.refreshContentRows({ requestType: 'dom-virtualscroll' });
_this.virtualEle.adjustTable(_this.getRowTopOffset(_this.currentStartIndex));
}
}
};
};
DomVirtualContentRenderer.prototype.onDataReady = function (e) {
if (e && !isNullOrUndefined(e.count)) {
this.count = e.count;
this.maxPage = Math.ceil(e.count / this.parent.pageSettings.pageSize);
}
var requestType = e ? e.requestType : undefined;
var resetActions = ['refresh', 'filtering', 'searching', 'grouping', 'ungrouping', 'reorder'];
if (resetActions.some(function (value) { return value === requestType; }) || isNullOrUndefined(requestType)) {
this.previousPage = 0;
this.pageSkip = -1;
this.pageTake = -1;
this.refreshOffsets();
}
this.resetScrollPosition(e.requestType);
};
DomVirtualContentRenderer.prototype.setDomVirtualPageQuery = function (args) {
if (!this.parent.enableVirtualization || !this.parent.isRowDomVirtualization()) {
return;
}
var isCrossPageFetch = this.pageSkip >= 0;
if (!isCrossPageFetch) {
return;
}
args.query.skip(this.pageSkip);
args.query.take(this.pageTake);
args.skipPage = true;
};
/**
* @returns {void}
* @hidden */
DomVirtualContentRenderer.prototype.refreshOffsets = function () {
if (!this.parent.enableVirtualization || !this.parent.isRowDomVirtualization()) {
return;
}
var pageSize = this.parent.pageSettings.pageSize;
var blockSize = pageSize >> 1;
if (blockSize <= 0 || this.count <= 0) {
return;
}
var totalBlocks = Math.ceil(this.count / blockSize);
this.maxPage = Math.ceil(this.count / pageSize);
this.offsets = {};
var rowHeight = this.rowHeight > 0 ? this.rowHeight : this.parent.getRowHeight();
for (var block = 1; block <= totalBlocks; block++) {
var startRow = (block - 1) * blockSize;
var endRow = Math.min(block * blockSize, this.count);
var blockRowCount = endRow - startRow;
this.offsets[parseInt(block.toString(), 10)] = (this.offsets[parseInt((block - 1).toString(), 10)] || 0)
+ blockRowCount * rowHeight;
}
this.offsetKeys = Object.keys(this.offsets);
};
DomVirtualContentRenderer.prototype.getPageFromIndex = function (absoluteIndex) {
if (this.maxPage <= 0) {
return 1;
}
var pageSize = this.parent.pageSettings.pageSize;
return Math.max(1, Math.min(Math.floor(absoluteIndex / pageSize) + 1, this.maxPage));
};
DomVirtualContentRenderer.prototype.isAutoRowHeight = function () {
var gObj = this.parent;
var settings = gObj.domVirtualizationSettings;
return settings.autoRowHeight !== false;
};
DomVirtualContentRenderer.prototype.hasRowHeightCallback = function () {
return !this.isAutoRowHeight() && typeof this.parent.setRowHeight === 'function';
};
DomVirtualContentRenderer.prototype.isDynamicHeight = function () {
return this.isAutoRowHeight() || this.hasRowHeightCallback();
};
DomVirtualContentRenderer.prototype.measureRowHeights = function (tbody) {
var rowObjects = this.getRows();
var dataRows = tbody.querySelectorAll('tr');
for (var i = 0; i < dataRows.length; i++) {
var h = dataRows[parseInt(i.toString(), 10)].offsetHeight;
if (h > 0 && rowObjects[parseInt(i.toString(), 10)]) {
rowObjects[parseInt(i.toString(), 10)].rowHeight = h;
var absoluteIndex = this.currentStartIndex + i;
var prev = this.rowHeightCache.get(absoluteIndex);
if (prev === undefined) {
this.dynamicRowCount++;
}
else {
this.dynamicHeightSum -= prev;
}
this.dynamicHeightSum += h;
this.rowHeightCache.set(absoluteIndex, h);
}
}
};
DomVirtualContentRenderer.prototype.getAvgRowHeight = function () {
if (!this.isDynamicHeight()) {
return this.rowHeight;
}
if (this.dynamicRowCount > 0) {
return Math.ceil(this.dynamicHeightSum / this.dynamicRowCount);
}
return this.rowHeight;
};
DomVirtualContentRenderer.prototype.getDataRowIndexByScrollTop = function (scrollTop) {
if (!this.isDynamicHeight() && this.expandedDetailRows.size === 0) {
if (this.rowHeight <= 0) {
return 0;
}
return Math.min(Math.floor(scrollTop / this.rowHeight), Math.max(0, this.totalRecords - 1));
}
var avgRowHeight = this.getAvgRowHeight();
if (avgRowHeight <= 0) {
return 0;
}
var rowTopOffset = 0;
for (var i = 0; i < this.totalRecords; i++) {
var cachedRowHeight = this.rowHeightCache.get(i);
var effectiveRowHeight = cachedRowHeight !== undefined ? cachedRowHeight : avgRowHeight;
if (rowTopOffset + effectiveRowHeight > scrollTop) {
return i;
}
rowTopOffset += effectiveRowHeight;
var detailRowHeight = this.expandedDetailRows.get(i);
if (detailRowHeight !== undefined) {
if (rowTopOffset + detailRowHeight > scrollTop) {
return i;
}
rowTopOffset += detailRowHeight;
}
}
return Math.max(0, this.totalRecords - 1);
};
DomVirtualContentRenderer.prototype.getStartIndex = function (scrollTop) {
var firstVisible = this.getDataRowIndexByScrollTop(scrollTop);
var bufferCount = this.getBufferRowCount();
return Math.max(0, firstVisible - bufferCount);
};
DomVirtualContentRenderer.prototype.getEndIndex = function (startIndex) {
var firstVisible = this.getDataRowIndexByScrollTop(this.currentScrollTop);
var visibleCount = this.getVisibleRowCount();
var bufferCount = this.getBufferRowCount();
var endIndex = Math.min(firstVisible + visibleCount + bufferCount, this.totalRecords);
var maxPool = this.parent.domVirtualizationSettings.maxPoolSize;
if (endIndex - startIndex > maxPool) {
endIndex = startIndex + maxPool;
}
return endIndex;
};
DomVirtualContentRenderer.prototype.getVisibleRowCount = function () {
var avgRowHeight = this.getAvgRowHeight();
if (avgRowHeight <= 0) {
return 20;
}
var viewportHeight = this.content.clientHeight;
return Math.ceil(viewportHeight / avgRowHeight);
};
DomVirtualContentRenderer.prototype.getBufferRowCount = function () {
return this.parent.domVirtualizationSettings.rowBuffer;
};
DomVirtualContentRenderer.prototype.initializeRowHeight = function () {
this.rowHeight = this.parent.getRowHeight();
};
DomVirtualContentRenderer.prototype.setVirtualDimensions = function () {
var totalExpandedHeight = 0;
this.expandedDetailRows.forEach(function (height) { totalExpandedHeight += height; });
var totalHeight;
if (this.isDynamicHeight()) {
if (this.dynamicRowCount > 0) {
var estimated = Math.ceil(this.dynamicHeightSum / this.dynamicRowCount);
var unmeasuredCount = Math.max(0, this.totalRecords - this.dynamicRowCount);
totalHeight = this.dynamicHeightSum + unmeasuredCount * estimated + totalExpandedHeight;
}
else {
totalHeight = this.totalRecords * this.rowHeight + totalExpandedHeight;
}
}
else {
totalHeight = this.totalRecords * this.rowHeight + totalExpandedHeight;
}
if (this.observer) {
this.observer.setPageHeight(totalHeight);
}
var previousHeight = this.storedVirtualHeight;
if (previousHeight > 0 && totalHeight !== previousHeight && this.currentScrollTop > 0) {
var scrollRatio = this.currentScrollTop / previousHeight;
var newScrollTop = scrollRatio * totalHeight;
this.storedVirtualHeight = totalHeight;
this.virtualEle.setVirtualHeight(totalHeight);
if (this.virtualEle.verticalScrollerContainer) {
updateCSSText(this.virtualEle.verticalScrollerContainer, "height: " + totalHeight + "px;");
}
this.preventScroll = true;
this.content.scrollTop = newScrollTop;
this.virtualEle.verticalScrollbar.scrollTop = newScrollTop;
this.preventScroll = false;
this.currentScrollTop = newScrollTop;
this.prevScrollTop = newScrollTop;
}
else {
this.storedVirtualHeight = totalHeight;
this.virtualEle.setVirtualHeight(totalHeight);
if (this.virtualEle.verticalScrollerContainer) {
updateCSSText(this.virtualEle.verticalScrollerContainer, "height: " + totalHeight + "px;");
}
}
};
DomVirtualContentRenderer.prototype.getRowTopOffset = function (dataRowIndex) {
if (dataRowIndex <= 0) {
return 0;
}
if (!this.isDynamicHeight() && this.expandedDetailRows.size === 0) {
return dataRowIndex * this.rowHeight;
}
var avgRowHeight = this.getAvgRowHeight();
var pixelOffset = 0;
for (var i = 0; i < dataRowIndex; i++) {
var cachedRowHeight = this.rowHeightCache.get(i);
pixelOffset += cachedRowHeight !== undefined ? cachedRowHeight : avgRowHeight;
var detailRowHeight = this.expandedDetailRows.get(i);
if (detailRowHeight !== undefined) {
pixelOffset += detailRowHeight;
}
}
return pixelOffset;
};
DomVirtualContentRenderer.prototype.updateDetailRowHeight = function (rowIndex, isExpand, detailRowHeight) {
var detailHeight = detailRowHeight !== undefined ? detailRowHeight : 500;
if (isExpand) {
this.expandedDetailRows.set(rowIndex, detailHeight);
}
else {
this.expandedDetailRows.delete(rowIndex);
}
this.initializeRowHeight();
if (this.parent.isRowDomVirtualization()) {
this.setVirtualDimensions();
}
};
DomVirtualContentRenderer.prototype.clearExpandedDetailRows = function () {
this.expandedDetailRows.clear();
this.rowHeightCache.clear();
this.dynamicHeightSum = 0;
this.dynamicRowCount = 0;
this.storedVirtualHeight = 0;
};
DomVirtualContentRenderer.prototype.removeEventListeners = function () {
this.observer = null;
};
DomVirtualContentRenderer.prototype.destroy = function () {
this.removeEventListeners();
};
DomVirtualContentRenderer.prototype.domVirtualCellFocus = function (e) {
if (!e || !e.action) {
return;
}
if ((e.action === 'enter' || e.action === 'shiftEnter') && this.parent.editSettings &&
this.parent.editSettings.mode === 'Cell') {
return;
}
var element = document.activeElement;
if (element && !element.classList.contains(literals.rowCell) &&
(element instanceof HTMLInputElement || !isNullOrUndefined(element.closest('.e-templatecell')))) {
element = element.closest('.e-rowcell');
}
if (this.parent.allowGrouping && this.parent.groupSettings && this.parent.groupSettings.columns.length
&& element && (element.classList.contains(literals.rowCell)
|| !isNullOrUndefined(parentsUntil(element, literals.groupCaptionRow)))
&& e && (e.action === 'shiftEnter' || e.action === 'upArrow' || e.action === 'downArrow')) {
var scrollEleG = this.parent.getContent().firstElementChild;
var scrollEleInfo = scrollEleG.getBoundingClientRect();
var row = closest(element, 'tr');
var nextFocusRow = e.action === 'downArrow'
? row.nextElementSibling : row.previousElementSibling;
var nextFocusRowInfo = nextFocusRow
? nextFocusRow.getBoundingClientRect() : undefined;
if (isNullOrUndefined(nextFocusRow)
|| (e.action === 'downArrow' && !!nextFocusRowInfo && nextFocusRowInfo.bottom > scrollEleInfo.bottom)
|| ((e.action === 'upArrow' || e.action === 'shiftEnter')
&& !!nextFocusRowInfo && nextFocusRowInfo.top < scrollEleInfo.top)) {
this.activeKey = e.action;
if (this.parent.focusModule) {
this.parent.focusModule.virtualSelectionInfo = {
isPending: isNullOrUndefined(nextFocusRow), direction: e.action, event: e
};
}
var viewDiff = isNullOrUndefined(nextFocusRow) || !nextFocusRowInfo
? (this.parent.getRowHeight ? this.parent.getRowHeight() : 0)
: e.action === 'downArrow'
? nextFocusRowInfo.bottom - scrollEleInfo.bottom
: scrollEleInfo.top - nextFocusRowInfo.top;
scrollEleG.scrollTop = e.action === 'downArrow'
? scrollEleG.scrollTop + viewDiff
: scrollEleG.scrollTop - viewDiff;
}
else {
this.activeKey = '';
}
return;
}
if (element && element.classList.contains(literals.rowCell)
&& e && (e.action === 'upArrow' || e.action === 'downArrow'
|| e.action === 'shiftEnter' || e.action === 'enter')) {
var rowIndex = parseInt(element.parentElement.getAttribute(literals.ariaRowIndex), 10) - 1;
var scrollEle = this.parent.getContent().firstElementChild;
if (e.action === 'downArrow' || e.action === 'enter') {
rowIndex += 1;
}
else {
rowIndex -= 1;
}
if (rowIndex < 0 || rowIndex >= this.totalRecords) {
return;
}
this.rowIndex = rowIndex;
this.cellIndex = parseInt(element.getAttribute(literals.ariaColIndex), 10) - 1;
var row = this.parent.getRowByIndex(rowIndex);
var visibleRowCount = Math.floor(scrollEle.offsetHeight / this.parent.getRowHeight()) - 1;
var emptyRow = isNullOrUndefined(row);
if (emptyRow
|| (ensureLastRow(row, this.parent) && (e.action === 'downArrow' || e.action === 'enter'))
|| (ensureFirstRow(row, this.parent.getRowHeight() * 2, this.parent)
&& (e.action === 'upArrow' || e.action === 'shiftEnter'))) {
this.activeKey = e.action;
scrollEle.scrollTop = (e.action === 'downArrow' || e.action === 'enter')
? Math.max(0, this.getRowTopOffset(rowIndex - visibleRowCount))
: this.getRowTopOffset(rowIndex);
if (this.virtualEle.verticalScrollbar) {
this.virtualEle.verticalScrollbar.scrollTop = scrollEle.scrollTop;
}
}
else {
this.activeKey = '';
}
}
};
DomVirtualContentRenderer.prototype.focusCell = function () {
if (!this.activeKey) {
return;
}
var row = this.parent.getRowByIndex(this.rowIndex);
if (!row) {
return;
}
var cells = row.getElementsByClassName(literals.rowCell);
var cell = cells[parseInt(this.cellIndex.toString(), 10)];
if (cell) {
cell.focus({ preventScroll: true });
}
if (this.parent.selectionSettings && !this.parent.selectionSettings.checkboxOnly) {
this.parent.selectRow(parseInt(row.getAttribute(literals.ariaRowIndex), 10) - 1);
}
this.activeKey = '';
};
DomVirtualContentRenderer.prototype.resetVirtualFocus = function (e) {
this.isCancel = e.isCancel;
};
DomVirtualContentRenderer.prototype.onGroupExpandCollapse = function () {
if (!this.parent || !this.parent.groupSettings || !this.parent.groupSettings.columns.length) {
return;
}
if (this.parent.isRowDomVirtualization()) {
this.setVirtualDimensions();
}
this.refreshContentRows({ requestType: 'dom-virtualscroll' });
};
DomVirtualContentRenderer.prototype.onApplyDomVirtualRowHeight = function (args) {
if (!this.hasRowHeightCallback()) {
return;
}
var rowHeightCallback = this.parent.setRowHeight;
var customHeight = rowHeightCallback(args.row);
if (customHeight > 0) {
args.row.rowHeight = customHeight;
var globalRowIndex = args.row.index;
var prev = this.rowHeightCache.get(globalRowIndex);
if (prev === undefined) {
this.dynamicRowCount++;
}
else {
this.dynamicHeightSum -= prev;
}
this.dynamicHeightSum += customHeight;
this.rowHeightCache.set(globalRowIndex, customHeight);
}
};
DomVirtualContentRenderer.prototype.selectVirtualRow = function (args) {
args.isAvailable = args.selectedIndex >= 0 && args.selectedIndex < this.totalRecords;
if (!args.isAvailable) {
return;
}
var selectedRow = this.parent.getRowByIndex(args.selectedIndex);
if (selectedRow) {
return;
}
if (!this.parent.isRowDomVirtualization() || !this.virtualEle.verticalScrollbar) {
return;
}
var scrollTop = this.getRowTopOffset(args.selectedIndex);
this.pendingSelectIndex = args.selectedIndex;
this.virtualEle.verticalScrollbar.scrollTop = scrollTop;
};
DomVirtualContentRenderer.prototype.scrollAfterEdit = function () {
if (this.parent.editModule && this.parent.editSettings.allowEditing && this.isNormaledit) {
if (this.parent.element.querySelector('.e-gridform')) {
var editForm = this.parent.element.querySelector('.' + literals.editedRow);
var addForm = this.parent.element.querySelector('.' + literals.addedRow);
if (editForm || addForm) {
var rowData = editForm
? extend({}, this.parent.getCurrentViewRecords()[this.editedRowIndex])
: extend({}, this.emptyRowData);
var keys = Object.keys(this.virtualData);
this.virtualData = keys.length
? this.getVirtualEditedData(this.virtualData)
: this.getVirtualEditedData(rowData);
}
}
}
};
DomVirtualContentRenderer.prototype.restoreEdit = function (e) {
if (this.isNormaledit) {
if (this.parent.editSettings.allowEditing
&& this.parent.editModule && !isNullOrUndefined(this.editedRowIndex)) {
var row = this.parent.getRowByIndex(this.editedRowIndex);
var content = this.content;
var keys = Object.keys(this.virtualData);
if (keys.length && row && !content.querySelector('.' + literals.editedRow)
&& ['sorting', 'filtering', 'grouping', 'refresh', 'searching', 'ungrouping', 'reorder']
.indexOf(e ? e.requestType : null) === -1) {
var rowTop = row.getBoundingClientRect().top
- this.parent.element.getBoundingClientRect().top;
if (rowTop < this.content.offsetHeight && rowTop > this.parent.getRowHeight()) {
this.parent.isEdit = false;
this.parent.editModule.startEdit(row);
}
}
if (row && this.content.querySelector('.' + literals.editedRow) && !keys.length) {
var rowData = extend({}, this.parent.getCurrentViewRecords()[this.editedRowIndex]);
this.virtualData = this.getVirtualEditedData(rowData);
}
}
this.restoreAdd();
}
};
DomVirtualContentRenderer.prototype.restoreAdd = function () {
var startAdd = !this.parent.element.querySelector('.' + literals.addedRow);
if (this.isNormaledit && this.isAdd && startAdd) {
var isTop = this.parent.editSettings.newRowPosition === 'Top'
&& this.content.scrollTop < this.parent.getRowHeight();
var isBottom = this.parent.editSettings.newRowPosition === 'Bottom'
&& (!this.parent.enableVirtualization
? this.content.scrollTop >= this.getRowTopOffset(Math.max(0, this.totalRecords - 1))
: this.parent.pageSettings.currentPage === this.maxPage);
if (isTop || isBottom) {
this.parent.isEdit = false;
this.parent.addRecord();
}
}
};
DomVirtualContentRenderer.prototype.editActionBegin = function (e) {
this.editedRowIndex = e.index;
var editIndex = e.index;
if (this.parent.enableVirtualization) {
var pageSize = Number(this.parent.pageSettings.pageSize);
var currentPage = Number(this.parent.pageSettings.currentPage);
var pageOffset = (currentPage - 1) * pageSize;
editIndex = e.index - pageOffset;
}
var rowData = extend({}, this.parent.getCurrentViewRecords()[parseInt(editIndex.toString(), 10)]);
var keys = Object.keys(this.virtualData);
e.data = keys.length && !this.parent.editSettings.showAddNewRow ? this.virtualData : rowData;
e.isScroll = false;
};
DomVirtualContentRenderer.prototype.addActionBegin = function (args) {
if (this.isNormaledit) {
if (!Object.keys(this.emptyRowData).length) {
this.createEmptyRowdata();
}
this.isAdd = true;
if (!this.parent.frozenRows && this.content.scrollTop > 0
&& this.parent.editSettings.newRowPosition === 'Top') {
this.isAdd = true;
args.startEdit = false;
this.content.scrollTop = 0;
}
if (this.parent.editSettings.newRowPosition === 'Bottom' && this.totalRecords > 0) {
var bottomOffset = this.getRowTopOffset(this.totalRecords);
if (this.content.scrollTop < bottomOffset - this.content.clientHeight) {
this.isAdd = true;
args.startEdit = false;
this.content.scrollTop = bottomOffset;
}
}
}
};
DomVirtualContentRenderer.prototype.getVirtualEditedData = function (rowData) {
var editForms = [].slice.call(this.parent.element.getElementsByClassName('e-gridform'));
var isFormDestroyed = this.parent.editModule
&& this.parent.editModule.formObj
&& this.parent.editModule.formObj.isDestroyed;
if (!isFormDestroyed) {
for (var i = 0; i < editForms.length; i++) {
rowData = this.parent.editModule.getCurrentEditedData(editForms[parseInt(i.toString(), 10)], rowData);
}
}
return rowData;
};
DomVirtualContentRenderer.prototype.getVirtualData = function (data) {
if (this.isNormaledit) {
var error = this.parent.element.querySelector('.e-griderror:not([style*="display: none"])');
var keys = Object.keys(this.virtualData);
data.isScroll = false;
if (error) {
return;
}
this.virtualData = keys.length ? this.virtualData : data.virtualData;
this.getVirtualEditedData(this.virtualData);
data.virtualData = this.virtualData;
data.isAdd = this.isAdd || this.parent.editSettings.showAddNewRow;
data.isCancel = this.isCancel;
}
};
DomVirtualContentRenderer.prototype.getVirtualRowIndex = function (index) {
var startIdx = this.getStartIndex(this.currentScrollTop);
return startIdx + index;
};
DomVirtualContentRenderer.prototype.editCancel = function (args) {
var dataIndex = getEditedDataIndex(this.parent, args.data);
if (!isNullOrUndefined(dataIndex)) {
args.data = this.parent.getCurrentViewRecords()[parseInt(dataIndex.toString(), 10)];
}
};
DomVirtualContentRenderer.prototype.editSuccess = function (args) {
if (this.isNormaledit) {
if (!this.isAdd && args && args.data) {
this.updateCurrentViewData(args.data);
}
this.isAdd = false;
}
};
DomVirtualContentRenderer.prototype.updateCurrentViewData = function (data) {
var dataIndex = getEditedDataIndex(this.parent, data);
if (!isNullOrUndefined(dataIndex)) {
this.parent.getCurrentViewRecords()[parseInt(dataIndex.toString(), 10)] = data;
}
};
DomVirtualContentRenderer.prototype.createEmptyRowdata = function () {
var _this = this;
(this.parent.columnModel || []).forEach(function (col) {
_this.emptyRowData[col.field] = undefined;
});
};
DomVirtualContentRenderer.prototype.resetIsedit = function () {
if (this.parent.isRowDomVirtualization() && this.isNormaledit) {
if ((this.parent.editSettings.allowEditing && Object.keys(this.virtualData).length)
|| (this.parent.editSettings.allowAdding && this.isAdd)) {
this.parent.isEdit = true;
}
}
};
DomVirtualContentRenderer.prototype.resetScrollPosition = function (action) {
if (this.actions.some(function (value) { return value === action; })) {
this.content.scrollTop = 0;
}
};
DomVirtualContentRenderer.prototype.actionComplete = function (args) {
if (!this.parent.isRowDomVirtualization()) {
return;
}
var editRequestTypes = ['delete', 'save', 'cancel'];
var dataActionRequestTypes = [
'sorting', 'filtering', 'grouping', 'refresh', 'searching', 'ungrouping', 'reorder'
];
if (this.isNormaledit
&& (dataActionRequestTypes.some(function (v) { return v === args.requestType; })
|| editRequestTypes.some(function (v) { return v === args.requestType; }))) {
this.isCancel = true;
this.isAdd = false || this.parent.editSettings.showAddNewRow;
this.editedRowIndex = undefined;
this.virtualData = {};
if (this.parent.editModule) {
this.parent.editModule.editModule.previousData = undefined;
}
}
};
DomVirtualContentRenderer.prototype.actionBegin = function (args) {
if (args.cancel && args.requestType === 'beginEdit') {
this.virtualData = {};
}
};
return DomVirtualContentRenderer;
}(ContentRender));
export { DomVirtualContentRenderer };