UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

245 lines (244 loc) • 10.6 kB
/** * DevExtreme (esm/ui/grid_core/ui.grid_core.virtual_columns.js) * Version: 21.1.4 * Build date: Mon Jun 21 2021 * * Copyright (c) 2012 - 2021 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { hasWindow } from "../../core/utils/window"; import { createColumnsInfo } from "./ui.grid_core.virtual_columns_core"; var DEFAULT_COLUMN_WIDTH = 50; var VirtualScrollingRowsViewExtender = { _resizeCore: function() { this.callBase.apply(this, arguments); this._columnsController.resize() }, _handleScroll: function(e) { var that = this; var scrollable = this.getScrollable(); var left = e.scrollOffset.left; that.callBase.apply(that, arguments); if (that.option("rtlEnabled") && scrollable) { left = scrollable.$content().width() - scrollable.$element().width() - left } that._columnsController.setScrollPosition(left) } }; var HeaderViewExtender = { _renderCore: function() { this.callBase.apply(this, arguments); if (this._columnsController.isVirtualMode()) { this._updateScrollLeftPosition() } } }; var ColumnsControllerExtender = function() { var getWidths = function(columns) { return columns.map(column => column.visibleWidth || parseFloat(column.width) || DEFAULT_COLUMN_WIDTH) }; var members = { init: function() { this.callBase(); this._beginPageIndex = 0; this._endPageIndex = 0; this._position = 0; this._virtualVisibleColumns = {} }, resetColumnsCache: function() { this.callBase(); this._virtualVisibleColumns = {} }, getBeginPageIndex: function(position) { var visibleColumns = this.getVisibleColumns(void 0, true); var widths = getWidths(visibleColumns); var currentPosition = 0; for (var index = 0; index < widths.length; index++) { if (currentPosition >= position) { return Math.floor(index / this.getColumnPageSize()) } currentPosition += widths[index] } return 0 }, getTotalWidth: function() { var width = this.option("width"); if ("number" === typeof width) { return width } return this.getController("resizing")._lastWidth || this.component.$element().outerWidth() }, getEndPageIndex: function(position) { var visibleColumns = this.getVisibleColumns(void 0, true); var widths = getWidths(visibleColumns); var currentPosition = 0; position += this.getTotalWidth(); for (var index = 0; index < widths.length; index++) { if (currentPosition >= position) { return Math.ceil(index / this.getColumnPageSize()) } currentPosition += widths[index] } return Math.ceil(widths.length / this.getColumnPageSize()) }, getColumnPageSize: function() { return this.option("scrolling.columnPageSize") }, _fireColumnsChanged: function() { var date = new Date; this.columnsChanged.fire({ optionNames: { all: true, length: 1 }, changeTypes: { columns: true, length: 1 } }); this._renderTime = new Date - date }, setScrollPosition: function(position) { var that = this; var renderingThreshold = that.option("scrolling.columnRenderingThreshold"); if (that._renderTime > renderingThreshold) { clearTimeout(that._changedTimeout); that._changedTimeout = setTimeout((function() { that._setScrollPositionCore(position) }), that.option("scrolling.timeout")) } else { that._setScrollPositionCore(position) } }, isVirtualMode: function() { return hasWindow() && "virtual" === this.option("scrolling.columnRenderingMode") }, resize: function() { this._setScrollPositionCore(this._position) }, _setScrollPositionCore: function(position) { if (this.isVirtualMode()) { var beginPageIndex = this.getBeginPageIndex(position); var endPageIndex = this.getEndPageIndex(position); var needColumnsChanged = position < this._position ? this._beginPageIndex > beginPageIndex : this._endPageIndex < endPageIndex; this._position = position; if (needColumnsChanged) { this._beginPageIndex = beginPageIndex; this._endPageIndex = endPageIndex; this._fireColumnsChanged() } } }, getFixedColumns: function(rowIndex, isBase) { var fixedColumns = this.callBase(rowIndex); if (this.isVirtualMode() && !isBase && fixedColumns.length) { var transparentColumnIndex = fixedColumns.map(c => c.command).indexOf("transparent"); fixedColumns[transparentColumnIndex].colspan = this.getVisibleColumns().length - this.callBase().length + 1; return fixedColumns } return fixedColumns }, getVisibleColumns: function(rowIndex, isBase) { if (isBase || !this.isVirtualMode()) { return this.callBase(rowIndex) } if (!this._beginPageIndex && !this._endPageIndex) { this._beginPageIndex = this.getBeginPageIndex(this._position); this._endPageIndex = this.getEndPageIndex(this._position) } var beginPageIndex = this._beginPageIndex; var endPageIndex = this._endPageIndex; var visibleColumnsHash = rowIndex + "-" + beginPageIndex + "-" + endPageIndex; if (this._virtualVisibleColumns[visibleColumnsHash]) { return this._virtualVisibleColumns[visibleColumnsHash] } var visibleColumns = this.callBase(); var rowCount = this.getRowCount(); var pageSize = this.getColumnPageSize(); var startIndex = beginPageIndex * pageSize; var endIndex = endPageIndex * pageSize; var fixedColumns = this.getFixedColumns(void 0, true); var transparentColumnIndex = fixedColumns.map(c => c.command).indexOf("transparent"); var beginFixedColumnCount = fixedColumns.length ? transparentColumnIndex : 0; var beginFixedColumns = visibleColumns.slice(0, beginFixedColumnCount); var beginColumns = visibleColumns.slice(beginFixedColumnCount, startIndex); var beginWidth = getWidths(beginColumns).reduce((a, b) => a + b, 0); if (!beginWidth) { startIndex = 0 } var endFixedColumnCount = fixedColumns.length ? fixedColumns.length - transparentColumnIndex - 1 : 0; var endFixedColumns = visibleColumns.slice(visibleColumns.length - endFixedColumnCount); var endColumns = visibleColumns.slice(endIndex, visibleColumns.length - endFixedColumnCount); var endWidth = getWidths(endColumns).reduce((a, b) => a + b, 0); if (!endWidth) { endIndex = visibleColumns.length } if (rowCount > 1 && "number" === typeof rowIndex) { var columnsInfo = []; for (var i = 0; i < rowCount; i++) { columnsInfo.push(this.callBase(i)) } beginFixedColumns = createColumnsInfo(columnsInfo, 0, beginFixedColumns.length)[rowIndex] || []; endFixedColumns = createColumnsInfo(columnsInfo, visibleColumns.length - endFixedColumns.length, visibleColumns.length)[rowIndex] || []; visibleColumns = createColumnsInfo(columnsInfo, startIndex, endIndex)[rowIndex] || [] } else { visibleColumns = visibleColumns.slice(startIndex, endIndex) } if (beginWidth) { visibleColumns.unshift({ command: "virtual", width: beginWidth }); visibleColumns = beginFixedColumns.concat(visibleColumns) } if (endWidth) { visibleColumns.push({ command: "virtual", width: endWidth }); visibleColumns = visibleColumns.concat(endFixedColumns) } this._virtualVisibleColumns[visibleColumnsHash] = visibleColumns; return visibleColumns }, getColumnIndexOffset: function() { var offset = 0; if (this._beginPageIndex > 0) { var fixedColumns = this.getFixedColumns(); var transparentColumnIndex = fixedColumns.map(c => c.command).indexOf("transparent"); var leftFixedColumnCount = transparentColumnIndex >= 0 ? transparentColumnIndex : 0; offset = this._beginPageIndex * this.getColumnPageSize() - leftFixedColumnCount - 1 } return offset > 0 ? offset : 0 }, dispose: function() { clearTimeout(this._changedTimeout); this.callBase.apply(this, arguments) } }; return members }(); export var virtualColumnsModule = { defaultOptions: function() { return { scrolling: { columnRenderingMode: "standard", columnPageSize: 5, columnRenderingThreshold: 300 } } }, extenders: { controllers: { columns: ColumnsControllerExtender }, views: { columnHeadersView: HeaderViewExtender, rowsView: VirtualScrollingRowsViewExtender } } };