otsdaq_utilities  v2_05_02_indev
responsive_layout.js
1 /* Tabulator v4.5.3 (c) Oliver Folkerd */
2 
3 var ResponsiveLayout = function ResponsiveLayout(table) {
4  this.table = table; //hold Tabulator object
5  this.columns = [];
6  this.hiddenColumns = [];
7  this.mode = "";
8  this.index = 0;
9  this.collapseFormatter = [];
10  this.collapseStartOpen = true;
11  this.collapseHandleColumn = false;
12 };
13 
14 //generate resposive columns list
15 ResponsiveLayout.prototype.initialize = function () {
16  var self = this,
17  columns = [];
18 
19  this.mode = this.table.options.responsiveLayout;
20  this.collapseFormatter = this.table.options.responsiveLayoutCollapseFormatter || this.formatCollapsedData;
21  this.collapseStartOpen = this.table.options.responsiveLayoutCollapseStartOpen;
22  this.hiddenColumns = [];
23 
24  //detemine level of responsivity for each column
25  this.table.columnManager.columnsByIndex.forEach(function (column, i) {
26  if (column.modules.responsive) {
27  if (column.modules.responsive.order && column.modules.responsive.visible) {
28  column.modules.responsive.index = i;
29  columns.push(column);
30 
31  if (!column.visible && self.mode === "collapse") {
32  self.hiddenColumns.push(column);
33  }
34  }
35  }
36  });
37 
38  //sort list by responsivity
39  columns = columns.reverse();
40  columns = columns.sort(function (a, b) {
41  var diff = b.modules.responsive.order - a.modules.responsive.order;
42  return diff || b.modules.responsive.index - a.modules.responsive.index;
43  });
44 
45  this.columns = columns;
46 
47  if (this.mode === "collapse") {
48  this.generateCollapsedContent();
49  }
50 
51  //assign collapse column
52  for (var _iterator = this.table.columnManager.columnsByIndex, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
53  var _ref;
54 
55  if (_isArray) {
56  if (_i >= _iterator.length) break;
57  _ref = _iterator[_i++];
58  } else {
59  _i = _iterator.next();
60  if (_i.done) break;
61  _ref = _i.value;
62  }
63 
64  var col = _ref;
65 
66  if (col.definition.formatter == "responsiveCollapse") {
67  this.collapseHandleColumn = col;
68  break;
69  }
70  }
71 
72  if (this.collapseHandleColumn) {
73  if (this.hiddenColumns.length) {
74  this.collapseHandleColumn.show();
75  } else {
76  this.collapseHandleColumn.hide();
77  }
78  }
79 };
80 
81 //define layout information
82 ResponsiveLayout.prototype.initializeColumn = function (column) {
83  var def = column.getDefinition();
84 
85  column.modules.responsive = { order: typeof def.responsive === "undefined" ? 1 : def.responsive, visible: def.visible === false ? false : true };
86 };
87 
88 ResponsiveLayout.prototype.initializeRow = function (row) {
89  var el;
90 
91  if (row.type !== "calc") {
92  el = document.createElement("div");
93  el.classList.add("tabulator-responsive-collapse");
94 
95  row.modules.responsiveLayout = {
96  element: el,
97  open: this.collapseStartOpen
98  };
99 
100  if (!this.collapseStartOpen) {
101  el.style.display = 'none';
102  }
103  }
104 };
105 
106 ResponsiveLayout.prototype.layoutRow = function (row) {
107  var rowEl = row.getElement();
108 
109  if (row.modules.responsiveLayout) {
110  rowEl.appendChild(row.modules.responsiveLayout.element);
111  this.generateCollapsedRowContent(row);
112  }
113 };
114 
115 //update column visibility
116 ResponsiveLayout.prototype.updateColumnVisibility = function (column, visible) {
117  var index;
118  if (column.modules.responsive) {
119  column.modules.responsive.visible = visible;
120  this.initialize();
121  }
122 };
123 
124 ResponsiveLayout.prototype.hideColumn = function (column) {
125  var colCount = this.hiddenColumns.length;
126 
127  column.hide(false, true);
128 
129  if (this.mode === "collapse") {
130  this.hiddenColumns.unshift(column);
131  this.generateCollapsedContent();
132 
133  if (this.collapseHandleColumn && !colCount) {
134  this.collapseHandleColumn.show();
135  }
136  }
137 };
138 
139 ResponsiveLayout.prototype.showColumn = function (column) {
140  var index;
141 
142  column.show(false, true);
143  //set column width to prevent calculation loops on uninitialized columns
144  column.setWidth(column.getWidth());
145 
146  if (this.mode === "collapse") {
147  index = this.hiddenColumns.indexOf(column);
148 
149  if (index > -1) {
150  this.hiddenColumns.splice(index, 1);
151  }
152 
153  this.generateCollapsedContent();
154 
155  if (this.collapseHandleColumn && !this.hiddenColumns.length) {
156  this.collapseHandleColumn.hide();
157  }
158  }
159 };
160 
161 //redraw columns to fit space
162 ResponsiveLayout.prototype.update = function () {
163  var self = this,
164  working = true;
165 
166  while (working) {
167 
168  var width = self.table.modules.layout.getMode() == "fitColumns" ? self.table.columnManager.getFlexBaseWidth() : self.table.columnManager.getWidth();
169 
170  var diff = (self.table.options.headerVisible ? self.table.columnManager.element.clientWidth : self.table.element.clientWidth) - width;
171 
172  if (diff < 0) {
173  //table is too wide
174  var column = self.columns[self.index];
175 
176  if (column) {
177  self.hideColumn(column);
178  self.index++;
179  } else {
180  working = false;
181  }
182  } else {
183 
184  //table has spare space
185  var _column = self.columns[self.index - 1];
186 
187  if (_column) {
188  if (diff > 0) {
189  if (diff >= _column.getWidth()) {
190  self.showColumn(_column);
191  self.index--;
192  } else {
193  working = false;
194  }
195  } else {
196  working = false;
197  }
198  } else {
199  working = false;
200  }
201  }
202 
203  if (!self.table.rowManager.activeRowsCount) {
204  self.table.rowManager.renderEmptyScroll();
205  }
206  }
207 };
208 
209 ResponsiveLayout.prototype.generateCollapsedContent = function () {
210  var self = this,
211  rows = this.table.rowManager.getDisplayRows();
212 
213  rows.forEach(function (row) {
214  self.generateCollapsedRowContent(row);
215  });
216 };
217 
218 ResponsiveLayout.prototype.generateCollapsedRowContent = function (row) {
219  var el, contents;
220 
221  if (row.modules.responsiveLayout) {
222  el = row.modules.responsiveLayout.element;
223 
224  while (el.firstChild) {
225  el.removeChild(el.firstChild);
226  }contents = this.collapseFormatter(this.generateCollapsedRowData(row));
227  if (contents) {
228  el.appendChild(contents);
229  }
230  }
231 };
232 
233 ResponsiveLayout.prototype.generateCollapsedRowData = function (row) {
234  var self = this,
235  data = row.getData(),
236  output = [],
237  mockCellComponent;
238 
239  this.hiddenColumns.forEach(function (column) {
240  var value = column.getFieldValue(data);
241 
242  if (column.definition.title && column.field) {
243  if (column.modules.format && self.table.options.responsiveLayoutCollapseUseFormatters) {
244 
245  mockCellComponent = {
246  value: false,
247  data: {},
248  getValue: function getValue() {
249  return value;
250  },
251  getData: function getData() {
252  return data;
253  },
254  getElement: function getElement() {
255  return document.createElement("div");
256  },
257  getRow: function getRow() {
258  return row.getComponent();
259  },
260  getColumn: function getColumn() {
261  return column.getComponent();
262  }
263  };
264 
265  output.push({
266  title: column.definition.title,
267  value: column.modules.format.formatter.call(self.table.modules.format, mockCellComponent, column.modules.format.params)
268  });
269  } else {
270  output.push({
271  title: column.definition.title,
272  value: value
273  });
274  }
275  }
276  });
277 
278  return output;
279 };
280 
281 ResponsiveLayout.prototype.formatCollapsedData = function (data) {
282  var list = document.createElement("table"),
283  listContents = "";
284 
285  data.forEach(function (item) {
286  var div = document.createElement("div");
287 
288  if (item.value instanceof Node) {
289  div.appendChild(item.value);
290  item.value = div.innerHTML;
291  }
292 
293  listContents += "<tr><td><strong>" + item.title + "</strong></td><td>" + item.value + "</td></tr>";
294  });
295 
296  list.innerHTML = listContents;
297 
298  return Object.keys(data).length ? list : "";
299 };
300 
301 Tabulator.prototype.registerModule("responsiveLayout", ResponsiveLayout);