UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

333 lines (257 loc) 8.6 kB
import Module from '../../core/Module.js'; class FrozenColumns extends Module{ constructor(table){ super(table); this.leftColumns = []; this.rightColumns = []; this.leftMargin = 0; this.rightMargin = 0; this.rightPadding = 0; this.initializationMode = "left"; this.active = false; this.blocked = true; this.registerColumnOption("frozen"); } //reset initial state reset(){ 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(){ this.subscribe("cell-layout", this.layoutCell.bind(this)); this.subscribe("column-init", this.initializeColumn.bind(this)); this.subscribe("column-width", this.layout.bind(this)); this.subscribe("row-layout-after", this.layoutRow.bind(this)); this.subscribe("table-layout", this.layout.bind(this)); this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this)); this.subscribe("scroll-horizontal", this.scrollHorizontal.bind(this)); this.subscribe("columns-loading", this.reset.bind(this)); this.subscribe("column-add", this.reinitializeColumns.bind(this)); this.subscribe("column-delete", this.reinitializeColumns.bind(this)); this.subscribe("table-redraw", this.layout.bind(this)); this.subscribe("layout-refreshing", this.blockLayout.bind(this)); this.subscribe("layout-refreshed", this.unblockLayout.bind(this)); } blockLayout(){ this.blocked = true; } unblockLayout(){ this.blocked = false; } layoutCell(cell){ this.layoutElement(cell.element, cell.column); } reinitializeColumns(){ this.reset(); this.table.columnManager.columnsByIndex.forEach((column) => { this.initializeColumn(column); }); } //initialize specific column initializeColumn(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"; } } } frozenCheck(column){ 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; } } //quick layout to smooth horizontal scrolling scrollHorizontal(){ if(this.active){ this.calcMargins(true); this.layoutColumnPosition(); this.layoutCalcRows(); this.reinitializeRows(); } } //calculate margins for rows calcMargins(scroll){ if(!scroll){ this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px"; this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px"; this.table.rowManager.tableElement.style.marginRight = this.rightMargin; } //calculate right frozen columns this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft; } //layout calculation rows layoutCalcRows(){ 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); } if(this.table.modExists("groupRows")){ this.layoutGroupCalcs(this.table.modules.groupRows.getGroups()); } } } layoutGroupCalcs(groups){ groups.forEach((group) => { if(group.calcs.top){ this.layoutRow(group.calcs.top); } if(group.calcs.bottom){ this.layoutRow(group.calcs.bottom); } if(group.groupList && group.groupList.length){ this.layoutGroupCalcs(group.groupList); } }); } //calculate column positions and layout headers layoutColumnPosition(allCells){ var leftParents = []; var leftMargin = 0; var rightMargin = 0; this.table.columnManager.headersElement.style.marginLeft = this.leftMargin; this.table.columnManager.element.style.paddingRight = this.rightMargin; this.leftColumns.forEach((column, i) => { column.modules.frozen.marginValue = leftMargin + this.table.columnManager.scrollLeft; column.modules.frozen.margin = column.modules.frozen.marginValue + "px"; if(column.visible){ leftMargin += column.getWidth(); } if(i == this.leftColumns.length - 1){ column.modules.frozen.edge = true; }else{ column.modules.frozen.edge = false; } if(column.parent.isGroup){ var parentEl = this.getColGroupParentElement(column); if(!leftParents.includes(parentEl)){ this.layoutElement(parentEl, column); leftParents.push(parentEl); } if(column.modules.frozen.edge){ parentEl.classList.add("tabulator-frozen-" + column.modules.frozen.position); } }else{ this.layoutElement(column.getElement(), column); } if(allCells){ column.cells.forEach((cell) => { this.layoutElement(cell.getElement(true), column); }); } }); this.rightColumns.forEach((column, i) => { if(column.visible){ rightMargin += column.getWidth(); } column.modules.frozen.marginValue = this.rightPadding - rightMargin; column.modules.frozen.margin = column.modules.frozen.marginValue + "px"; if(i == this.rightColumns.length - 1){ column.modules.frozen.edge = true; }else{ column.modules.frozen.edge = false; } if(column.parent.isGroup){ this.layoutElement(this.getColGroupParentElement(column), column); }else{ this.layoutElement(column.getElement(), column); } if(allCells){ column.cells.forEach((cell) => { this.layoutElement(cell.getElement(true), column); }); } }); } getColGroupParentElement(column){ return column.parent.isGroup ? this.getColGroupParentElement(column.parent) : column.getElement(); } //layout columns appropriately layout(){ if(this.active && !this.blocked){ //calculate row padding this.calcMargins(); //calculate left columns this.layoutColumnPosition(); this.reinitializeRows(); this.layoutCalcRows(); } } reinitializeRows(){ var visibleRows = this.table.rowManager.getVisibleRows(true); var otherRows = this.table.rowManager.getRows().filter(row => !visibleRows.includes(row)); otherRows.forEach((row) =>{ row.deinitialize(); }); visibleRows.forEach((row) =>{ if(row.type === "row"){ this.layoutRow(row); } }); } layoutRow(row){ // console.trace("row") var rowEl = row.getElement(); rowEl.style.paddingLeft = this.leftMargin; if(this.table.options.layout === "fitDataFill" && this.rightColumns.length){ this.table.rowManager.getTableElement().style.minWidth = "calc(100% - " + this.rightMargin + ")"; } this.leftColumns.forEach((column) => { var cell = row.getCell(column); if(cell){ this.layoutElement(cell.getElement(true), column); } }); this.rightColumns.forEach((column) => { var cell = row.getCell(column); if(cell){ this.layoutElement(cell.getElement(true), column); } }); } layoutElement(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); } } } _calcSpace(columns, index){ var width = 0; for (let i = 0; i < index; i++){ if(columns[i].visible){ width += columns[i].getWidth(); } } return width; } } FrozenColumns.moduleName = "frozenColumns"; export default FrozenColumns;