otsdaq_utilities  v2_05_02_indev
frozen_columns.js
1 var FrozenColumns = function(table){
2  this.table = table; //hold Tabulator object
3  this.leftColumns = [];
4  this.rightColumns = [];
5  this.leftMargin = 0;
6  this.rightMargin = 0;
7  this.rightPadding = 0;
8  this.initializationMode = "left";
9  this.active = false;
10  this.scrollEndTimer = false;
11 };
12 
13 //reset initial state
14 FrozenColumns.prototype.reset = function(){
15  this.initializationMode = "left";
16  this.leftColumns = [];
17  this.rightColumns = [];
18  this.leftMargin = 0;
19  this.rightMargin = 0;
20  this.rightMargin = 0;
21  this.active = false;
22 
23  this.table.columnManager.headersElement.style.marginLeft = 0;
24  this.table.columnManager.element.style.paddingRight = 0;
25 };
26 
27 //initialize specific column
28 FrozenColumns.prototype.initializeColumn = function(column){
29  var config = {margin:0, edge:false};
30 
31  if(column.definition.frozen){
32 
33  if(!column.parent.isGroup){
34 
35 
36  if(!column.isGroup){
37  config.position = this.initializationMode;
38 
39  if(this.initializationMode == "left"){
40  this.leftColumns.push(column);
41  }else{
42  this.rightColumns.unshift(column);
43  }
44 
45  this.active = true;
46 
47  column.modules.frozen = config;
48  }else{
49  console.warn("Frozen Column Error - Column Groups cannot be frozen");
50  }
51  }else{
52  console.warn("Frozen Column Error - Grouped columns cannot be frozen");
53  }
54 
55  }else{
56  this.initializationMode = "right";
57  }
58 };
59 
60 //quick layout to smooth horizontal scrolling
61 FrozenColumns.prototype.scrollHorizontal = function(){
62  var rows;
63 
64  if(this.active){
65  clearTimeout(this.scrollEndTimer);
66 
67  //layout all rows after scroll is complete
68  this.scrollEndTimer = setTimeout(() => {
69  this.layout();
70  }, 100);
71 
72  rows = this.table.rowManager.getVisibleRows();
73 
74  this.calcMargins();
75 
76  this.layoutColumnPosition();
77 
78  this.layoutCalcRows();
79 
80  rows.forEach((row) => {
81  if(row.type === "row"){
82  this.layoutRow(row);
83  }
84  });
85 
86  this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
87  }
88 };
89 
90 //calculate margins for rows
91 FrozenColumns.prototype.calcMargins = function(){
92  this.leftMargin = this._calcSpace(this.leftColumns, this.leftColumns.length) + "px";
93  this.table.columnManager.headersElement.style.marginLeft = this.leftMargin;
94 
95  this.rightMargin = this._calcSpace(this.rightColumns, this.rightColumns.length) + "px";
96  this.table.columnManager.element.style.paddingRight = this.rightMargin;
97 
98  //calculate right frozen columns
99  this.rightPadding = this.table.rowManager.element.clientWidth + this.table.columnManager.scrollLeft;
100 };
101 
102 //layout calculation rows
103 FrozenColumns.prototype.layoutCalcRows = function(){
104  if(this.table.modExists("columnCalcs")){
105  if(this.table.modules.columnCalcs.topInitialized && this.table.modules.columnCalcs.topRow){
106  this.layoutRow(this.table.modules.columnCalcs.topRow);
107  }
108  if(this.table.modules.columnCalcs.botInitialized && this.table.modules.columnCalcs.botRow){
109  this.layoutRow(this.table.modules.columnCalcs.botRow);
110  }
111  }
112 }
113 
114 //calculate column positions and layout headers
115 FrozenColumns.prototype.layoutColumnPosition = function( allCells){
116  this.leftColumns.forEach((column, i) => {
117  column.modules.frozen.margin = (this._calcSpace(this.leftColumns, i) + this.table.columnManager.scrollLeft) + "px";
118 
119  if(i == this.leftColumns.length - 1){
120  column.modules.frozen.edge = true;
121  }else{
122  column.modules.frozen.edge = false;
123  }
124 
125  this.layoutElement(column.getElement(), column);
126 
127  if(allCells){
128  column.cells.forEach((cell) => {
129  this.layoutElement(cell.getElement(), column);
130  });
131  }
132  });
133 
134  this.rightColumns.forEach((column, i) => {
135  column.modules.frozen.margin = (this.rightPadding - this._calcSpace(this.rightColumns, i + 1)) + "px";
136 
137  if(i == this.rightColumns.length - 1){
138  column.modules.frozen.edge = true;
139  }else{
140  column.modules.frozen.edge = false;
141  }
142 
143  this.layoutElement(column.getElement(), column);
144 
145  if(allCells){
146  column.cells.forEach((cell) => {
147  this.layoutElement(cell.getElement(), column);
148  });
149  }
150  });
151 }
152 
153 //layout columns appropropriatly
154 FrozenColumns.prototype.layout = function(){
155  var self = this,
156  rightMargin = 0;
157 
158  if(self.active){
159 
160  //calculate row padding
161  this.calcMargins();
162 
163  // self.table.rowManager.activeRows.forEach(function(row){
164  // self.layoutRow(row);
165  // });
166 
167  // if(self.table.options.dataTree){
168  self.table.rowManager.getDisplayRows().forEach(function(row){
169  if(row.type === "row"){
170  self.layoutRow(row);
171  }
172  });
173  // }
174 
175  this.layoutCalcRows();
176 
177  //calculate left columns
178  this.layoutColumnPosition(true);
179 
180  // if(tableHolder.scrollHeight > tableHolder.clientHeight){
181  // rightMargin -= tableHolder.offsetWidth - tableHolder.clientWidth;
182  // }
183 
184  this.table.rowManager.tableElement.style.marginRight = this.rightMargin;
185  }
186 };
187 
188 
189 FrozenColumns.prototype.layoutRow = function(row){
190  var rowEl = row.getElement();
191 
192  rowEl.style.paddingLeft = this.leftMargin;
193  // rowEl.style.paddingRight = this.rightMargin + "px";
194 
195  this.leftColumns.forEach((column) => {
196  var cell = row.getCell(column);
197 
198  if(cell){
199  this.layoutElement(cell.getElement(), column);
200  }
201  });
202 
203  this.rightColumns.forEach((column) => {
204  var cell = row.getCell(column);
205 
206  if(cell){
207  this.layoutElement(cell.getElement(), column);
208  }
209  });
210 };
211 
212 FrozenColumns.prototype.layoutElement = function(element, column){
213 
214  if(column.modules.frozen){
215  element.style.position = "absolute";
216  element.style.left = column.modules.frozen.margin;
217 
218  element.classList.add("tabulator-frozen");
219 
220  if(column.modules.frozen.edge){
221  element.classList.add("tabulator-frozen-" + column.modules.frozen.position);
222  }
223  }
224 };
225 
226 FrozenColumns.prototype._calcSpace = function(columns, index){
227  var width = 0;
228 
229  for (let i = 0; i < index; i++){
230  if(columns[i].visible){
231  width += columns[i].getWidth();
232  }
233  }
234 
235  return width;
236 };
237 
238 Tabulator.prototype.registerModule("frozenColumns", FrozenColumns);