devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
258 lines (221 loc) • 9.98 kB
JavaScript
"use strict";
var windowUtils = require("../../core/utils/window");
var virtualColumnsCore = require("./ui.grid_core.virtual_columns_core");
var DEFAULT_COLUMN_WIDTH = 50;
var VirtualScrollingRowsViewExtender = {
_handleScroll: function _handleScroll(e) {
var that = this,
scrollable = this.getScrollable(),
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 HeaderFooterViewExtender = {
_renderCore: function _renderCore() {
var that = this,
scrollLeft = that._scrollLeft;
that.callBase.apply(that, arguments);
if (that._columnsController.isVirtualMode() && scrollLeft >= 0) {
that._scrollLeft = 0;
that.scrollTo({ left: scrollLeft });
}
}
};
var ColumnsControllerExtender = function () {
var getWidths = function getWidths(columns) {
return columns.map(function (column) {
return column.visibleWidth || parseFloat(column.width) || DEFAULT_COLUMN_WIDTH;
});
};
var members = {
init: function init() {
var that = this;
that.callBase();
that._beginPageIndex = 0;
that._endPageIndex = 0;
that._position = 0;
that._virtualVisibleColumns = {};
},
resetColumnsCache: function resetColumnsCache() {
this.callBase();
this._virtualVisibleColumns = {};
},
getBeginPageIndex: function getBeginPageIndex(position) {
var visibleColumns = this.getVisibleColumns(undefined, true),
widths = getWidths(visibleColumns),
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 getTotalWidth() {
var width = this.option("width");
if (typeof width === "number") {
return width;
}
return this.getController("resizing")._lastWidth || this.component.$element().outerWidth();
},
getEndPageIndex: function getEndPageIndex(position) {
var visibleColumns = this.getVisibleColumns(undefined, true),
widths = getWidths(visibleColumns),
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 getColumnPageSize() {
return this.option("scrolling.columnPageSize");
},
_fireColumnsChanged: function _fireColumnsChanged() {
var date = new Date();
this.columnsChanged.fire({
optionNames: { all: true, length: 1 },
changeTypes: { columns: true, length: 1 }
});
this._renderTime = new Date() - date;
},
setScrollPosition: function setScrollPosition(position) {
var that = this,
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 isVirtualMode() {
return windowUtils.hasWindow() && this.option("scrolling.columnRenderingMode") === "virtual";
},
_setScrollPositionCore: function _setScrollPositionCore(position) {
var that = this;
if (that.isVirtualMode()) {
var beginPageIndex = that.getBeginPageIndex(position);
var endPageIndex = that.getEndPageIndex(position);
if (position < that._position ? that._beginPageIndex !== beginPageIndex : that._endPageIndex !== endPageIndex) {
that._beginPageIndex = beginPageIndex;
that._endPageIndex = endPageIndex;
that._fireColumnsChanged();
}
that._position = position;
}
},
getFixedColumns: function getFixedColumns(rowIndex, isBase) {
var fixedColumns = this.callBase(rowIndex);
if (this.isVirtualMode() && !isBase && fixedColumns.length) {
var transparentColumnIndex = fixedColumns.map(function (c) {
return c.command;
}).indexOf("transparent");
fixedColumns[transparentColumnIndex].colspan = this.getVisibleColumns().length - this.callBase().length + 1;
return fixedColumns;
}
return fixedColumns;
},
getVisibleColumns: function getVisibleColumns(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,
endPageIndex = this._endPageIndex,
visibleColumnsHash = rowIndex + "-" + beginPageIndex + "-" + endPageIndex;
if (this._virtualVisibleColumns[visibleColumnsHash]) {
return this._virtualVisibleColumns[visibleColumnsHash];
}
var visibleColumns = this.callBase(),
rowCount = this.getRowCount(),
pageSize = this.getColumnPageSize(),
startIndex = beginPageIndex * pageSize,
endIndex = endPageIndex * pageSize,
fixedColumns = this.getFixedColumns(undefined, true),
transparentColumnIndex = fixedColumns.map(function (c) {
return 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(function (a, b) {
return 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(function (a, b) {
return a + b;
}, 0);
if (!endWidth) {
endIndex = visibleColumns.length;
}
if (rowCount > 1 && typeof rowIndex === "number") {
var columnsInfo = [];
for (var i = 0; i < rowCount; i++) {
columnsInfo.push(this.callBase(i));
}
beginFixedColumns = virtualColumnsCore.createColumnsInfo(columnsInfo, 0, beginFixedColumns.length)[rowIndex] || [];
endFixedColumns = virtualColumnsCore.createColumnsInfo(columnsInfo, visibleColumns.length - endFixedColumns.length, visibleColumns.length)[rowIndex] || [];
visibleColumns = virtualColumnsCore.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;
}
};
return members;
}();
module.exports = {
defaultOptions: function defaultOptions() {
return {
scrolling: {
/**
* @name GridBaseOptions.scrolling.columnRenderingMode
* @publicName columnRenderingMode
* @type Enums.GridColumnRenderingMode
* @default "standard"
*/
columnRenderingMode: "standard",
columnPageSize: 5,
columnRenderingThreshold: 300
}
};
},
extenders: {
controllers: {
columns: ColumnsControllerExtender
},
views: {
columnHeadersView: HeaderFooterViewExtender,
footerView: HeaderFooterViewExtender,
rowsView: VirtualScrollingRowsViewExtender
}
}
};