UNPKG

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