tabulator-tables
Version:
Interactive table generation JavaScript library
275 lines (211 loc) • 6.99 kB
JavaScript
/* Tabulator v4.9.3 (c) Oliver Folkerd */
var FrozenColumns = function FrozenColumns(table) {
this.table = table; //hold Tabulator object
this.leftColumns = [];
this.rightColumns = [];
this.leftMargin = 0;
this.rightMargin = 0;
this.rightPadding = 0;
this.initializationMode = "left";
this.active = false;
this.scrollEndTimer = false;
};
//reset initial state
FrozenColumns.prototype.reset = function () {
this.initializationMode = "left";
this.leftColumns = [];
this.rightColumns = [];
this.leftMargin = 0;
this.rightMargin = 0;
this.rightMargin = 0;
this.active = false;
this.table.columnManager.headersElement.style.marginLeft = 0;
this.table.columnManager.element.style.paddingRight = 0;
};
//initialize specific column
FrozenColumns.prototype.initializeColumn = function (column) {
var config = { margin: 0, edge: false };
if (!column.isGroup) {
if (this.frozenCheck(column)) {
config.position = this.initializationMode;
if (this.initializationMode == "left") {
this.leftColumns.push(column);
} else {
this.rightColumns.unshift(column);
}
this.active = true;
column.modules.frozen = config;
} else {
this.initializationMode = "right";
}
}
};
FrozenColumns.prototype.frozenCheck = function (column) {
var frozen = false;
if (column.parent.isGroup && column.definition.frozen) {
console.warn("Frozen Column Error - Parent column group must be frozen, not individual columns or sub column groups");
}
if (column.parent.isGroup) {
return this.frozenCheck(column.parent);
} else {
return column.definition.frozen;
}
return frozen;
};
//quick layout to smooth horizontal scrolling
FrozenColumns.prototype.scrollHorizontal = function () {
var _this = this;
var rows;
if (this.active) {
clearTimeout(this.scrollEndTimer);
//layout all rows after scroll is complete
this.scrollEndTimer = setTimeout(function () {
_this.layout();
}, 100);
rows = this.table.rowManager.getVisibleRows();
this.calcMargins();
this.layoutColumnPosition();
this.layoutCalcRows();
rows.forEach(function (row) {
if (row.type === "row") {
_this.layoutRow(row);
}
});
this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
}
};
//calculate margins for rows
FrozenColumns.prototype.calcMargins = function () {
this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px";
this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px";
this.table.columnManager.element.style.paddingRight = this.rightMargin;
//calculate right frozen columns
this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft;
};
//layout calculation rows
FrozenColumns.prototype.layoutCalcRows = function () {
if (this.table.modExists("columnCalcs")) {
if (this.table.modules.columnCalcs.topInitialized && this.table.modules.columnCalcs.topRow) {
this.layoutRow(this.table.modules.columnCalcs.topRow);
}
if (this.table.modules.columnCalcs.botInitialized && this.table.modules.columnCalcs.botRow) {
this.layoutRow(this.table.modules.columnCalcs.botRow);
}
}
};
//calculate column positions and layout headers
FrozenColumns.prototype.layoutColumnPosition = function (allCells) {
var _this2 = this;
var leftParents = [];
this.leftColumns.forEach(function (column, i) {
column.modules.frozen.margin = _this2._calcSpace(_this2.leftColumns, i) + _this2.table.columnManager.scrollLeft + "px";
if (i == _this2.leftColumns.length - 1) {
column.modules.frozen.edge = true;
} else {
column.modules.frozen.edge = false;
}
if (column.parent.isGroup) {
var parentEl = _this2.getColGroupParentElement(column);
if (!leftParents.includes(parentEl)) {
_this2.layoutElement(parentEl, column);
leftParents.push(parentEl);
}
if (column.modules.frozen.edge) {
parentEl.classList.add("tabulator-frozen-" + column.modules.frozen.position);
}
} else {
_this2.layoutElement(column.getElement(), column);
}
if (allCells) {
column.cells.forEach(function (cell) {
_this2.layoutElement(cell.getElement(true), column);
});
}
});
this.rightColumns.forEach(function (column, i) {
column.modules.frozen.margin = _this2.rightPadding - _this2._calcSpace(_this2.rightColumns, i + 1) + "px";
if (i == _this2.rightColumns.length - 1) {
column.modules.frozen.edge = true;
} else {
column.modules.frozen.edge = false;
}
if (column.parent.isGroup) {
_this2.layoutElement(_this2.getColGroupParentElement(column), column);
} else {
_this2.layoutElement(column.getElement(), column);
}
if (allCells) {
column.cells.forEach(function (cell) {
_this2.layoutElement(cell.getElement(true), column);
});
}
});
};
FrozenColumns.prototype.getColGroupParentElement = function (column) {
return column.parent.isGroup ? this.getColGroupParentElement(column.parent) : column.getElement();
};
//layout columns appropropriatly
FrozenColumns.prototype.layout = function () {
var self = this,
rightMargin = 0;
if (self.active) {
//calculate row padding
this.calcMargins();
// self.table.rowManager.activeRows.forEach(function(row){
// self.layoutRow(row);
// });
// if(self.table.options.dataTree){
self.table.rowManager.getDisplayRows().forEach(function (row) {
if (row.type === "row") {
self.layoutRow(row);
}
});
// }
this.layoutCalcRows();
//calculate left columns
this.layoutColumnPosition(true);
// if(tableHolder.scrollHeight > tableHolder.clientHeight){
// rightMargin -= tableHolder.offsetWidth - tableHolder.clientWidth;
// }
this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
}
};
FrozenColumns.prototype.layoutRow = function (row) {
var _this3 = this;
var rowEl = row.getElement();
rowEl.style.paddingLeft = this.leftMargin;
// rowEl.style.paddingRight = this.rightMargin + "px";
this.leftColumns.forEach(function (column) {
var cell = row.getCell(column);
if (cell) {
_this3.layoutElement(cell.getElement(true), column);
}
});
this.rightColumns.forEach(function (column) {
var cell = row.getCell(column);
if (cell) {
_this3.layoutElement(cell.getElement(true), column);
}
});
};
FrozenColumns.prototype.layoutElement = function (element, column) {
if (column.modules.frozen) {
element.style.position = "absolute";
element.style.left = column.modules.frozen.margin;
element.classList.add("tabulator-frozen");
if (column.modules.frozen.edge) {
element.classList.add("tabulator-frozen-" + column.modules.frozen.position);
}
}
};
FrozenColumns.prototype._calcSpace = function (columns, index) {
var width = 0;
for (var i = 0; i < index; i++) {
if (columns[i].visible) {
width += columns[i].getWidth();
}
}
return width;
};
Tabulator.prototype.registerModule("frozenColumns", FrozenColumns);