otsdaq_utilities  v2_05_02_indev
html_table_export.js
1 var HtmlTableExport = function(table){
2  this.table = table; //hold Tabulator object
3  this.config = {};
4  this.cloneTableStyle = true;
5  this.colVisProp = "";
6 };
7 
8 HtmlTableExport.prototype.genereateTable = function(config, style, visible, colVisProp){
9  this.cloneTableStyle = style;
10  this.config = config || {};
11  this.colVisProp = colVisProp;
12 
13  var headers = this.generateHeaderElements();
14  var body = this.generateBodyElements(visible);
15 
16  var table = document.createElement("table");
17  table.classList.add("tabulator-print-table");
18  table.appendChild(headers);
19  table.appendChild(body);
20 
21  this.mapElementStyles(this.table.element, table, ["border-top", "border-left", "border-right", "border-bottom"]);
22 
23  return table;
24 };
25 
26 
27 HtmlTableExport.prototype.generateColumnGroupHeaders = function(){
28  var output = [];
29 
30  var columns = this.config.columnGroups !== false ? this.table.columnManager.columns : this.table.columnManager.columnsByIndex;
31 
32  columns.forEach((column) => {
33  var colData = this.processColumnGroup(column);
34 
35  if(colData){
36  output.push(colData);
37  }
38  });
39 
40  return output;
41 };
42 
43 HtmlTableExport.prototype.processColumnGroup = function(column){
44  var subGroups = column.columns,
45  maxDepth = 0;
46 
47  var groupData = {
48  title:column.definition.title,
49  column:column,
50  depth:1,
51  };
52 
53  if(subGroups.length){
54  groupData.subGroups = [];
55  groupData.width = 0;
56 
57  subGroups.forEach((subGroup) => {
58  var subGroupData = this.processColumnGroup(subGroup);
59 
60  if(subGroupData){
61  groupData.width += subGroupData.width;
62  groupData.subGroups.push(subGroupData);
63 
64  if(subGroupData.depth > maxDepth){
65  maxDepth = subGroupData.depth;
66  }
67  }
68  });
69 
70  groupData.depth += maxDepth;
71 
72  if(!groupData.width){
73  return false;
74  }
75  }else{
76  if(this.columnVisCheck(column)){
77  groupData.width = 1;
78  }else{
79  return false;
80  }
81  }
82 
83  return groupData;
84 };
85 
86 
87 HtmlTableExport.prototype.groupHeadersToRows = function(columns){
88 
89  var headers = [], headerDepth = 0;
90 
91  function parseColumnGroup(column, level){
92 
93  var depth = headerDepth - level;
94 
95  if(typeof headers[level] === "undefined"){
96  headers[level] = [];
97  }
98 
99  column.height = column.subGroups ? 1 : (depth - column.depth) + 1;
100 
101  headers[level].push(column);
102 
103  if(column.subGroups){
104  column.subGroups.forEach(function(subGroup){
105  parseColumnGroup(subGroup, level+1);
106  });
107  }
108  }
109 
110  //calculate maximum header debth
111  columns.forEach(function(column){
112  if(column.depth > headerDepth){
113  headerDepth = column.depth;
114  }
115  });
116 
117  columns.forEach(function(column){
118  parseColumnGroup(column,0);
119  });
120 
121  return headers;
122 };
123 
124 
125 HtmlTableExport.prototype.generateHeaderElements = function(){
126 
127  var headerEl = document.createElement("thead");
128 
129  var rows = this.groupHeadersToRows(this.generateColumnGroupHeaders());
130 
131  rows.forEach((row) => {
132  var rowEl = document.createElement("tr");
133 
134  this.mapElementStyles(this.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
135 
136  row.forEach((column) => {
137  var cellEl = document.createElement("th");
138  var classNames = column.column.definition.cssClass ? column.column.definition.cssClass.split(" ") : [];
139 
140  cellEl.colSpan = column.width;
141  cellEl.rowSpan = column.height;
142 
143  cellEl.innerHTML = column.column.definition.title;
144 
145  if(this.cloneTableStyle){
146  cellEl.style.boxSizing = "border-box";
147  }
148 
149  classNames.forEach(function(className) {
150  cellEl.classList.add(className);
151  });
152 
153  this.mapElementStyles(column.column.getElement(), cellEl, ["text-align", "border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
154  this.mapElementStyles(column.column.contentElement, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom"]);
155 
156  if(column.column.visible){
157  this.mapElementStyles(column.column.getElement(), cellEl, ["width"]);
158  }else{
159  if(column.column.definition.width){
160  cellEl.style.width = column.column.definition.width + "px";
161  }
162  }
163 
164  if(column.column.parent){
165  this.mapElementStyles(column.column.parent.groupElement, cellEl, ["border-top"]);
166  }
167 
168  rowEl.appendChild(cellEl);
169  });
170 
171  headerEl.appendChild(rowEl);
172  });
173 
174  return headerEl;
175 };
176 
177 HtmlTableExport.prototype.generateBodyElements = function(visible){
178  var oddRow, evenRow, calcRow, firstRow, firstCell, firstGroup, lastCell, styleCells, styleRow;
179 
180  //lookup row styles
181  if(this.cloneTableStyle && window.getComputedStyle){
182  oddRow = this.table.element.querySelector(".tabulator-row-odd:not(.tabulator-group):not(.tabulator-calcs)");
183  evenRow = this.table.element.querySelector(".tabulator-row-even:not(.tabulator-group):not(.tabulator-calcs)");
184  calcRow = this.table.element.querySelector(".tabulator-row.tabulator-calcs");
185  firstRow = this.table.element.querySelector(".tabulator-row:not(.tabulator-group):not(.tabulator-calcs)");
186  firstGroup = this.table.element.getElementsByClassName("tabulator-group")[0];
187 
188  if(firstRow){
189  styleCells = firstRow.getElementsByClassName("tabulator-cell");
190  firstCell = styleCells[0];
191  lastCell = styleCells[styleCells.length - 1];
192  }
193  }
194 
195  var bodyEl = document.createElement("tbody");
196 
197  var rows = visible ? this.table.rowManager.getVisibleRows(true) : this.table.rowManager.getDisplayRows();
198  var columns = [];
199 
200  if(this.config.columnCalcs !== false && this.table.modExists("columnCalcs")){
201  if(this.table.modules.columnCalcs.topInitialized){
202  rows.unshift(this.table.modules.columnCalcs.topRow);
203  }
204 
205  if(this.table.modules.columnCalcs.botInitialized){
206  rows.push(this.table.modules.columnCalcs.botRow);
207  }
208  }
209 
210  this.table.columnManager.columnsByIndex.forEach((column) => {
211  if (this.columnVisCheck(column)) {
212  columns.push(column);
213  }
214  });
215 
216  rows = rows.filter((row) => {
217  switch(row.type){
218  case "group":
219  return this.config.rowGroups !== false;
220  break;
221 
222  case "calc":
223  return this.config.columnCalcs !== false;
224  break;
225  }
226 
227  return true;
228  });
229 
230  if(rows.length > 1000){
231  console.warn("It may take a long time to render an HTML table with more than 1000 rows");
232  }
233 
234  rows.forEach((row, i) => {
235  var rowData = row.getData();
236 
237  var rowEl = document.createElement("tr");
238  rowEl.classList.add("tabulator-print-table-row");
239 
240  switch(row.type){
241  case "group":
242  var cellEl = document.createElement("td");
243  cellEl.colSpan = columns.length;
244  cellEl.innerHTML = row.key;
245 
246  rowEl.classList.add("tabulator-print-table-group");
247 
248  this.mapElementStyles(firstGroup, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
249  this.mapElementStyles(firstGroup, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom"]);
250  rowEl.appendChild(cellEl);
251  break;
252 
253  case "calc" :
254  rowEl.classList.add("tabulator-print-table-calcs");
255 
256  case "row" :
257  columns.forEach((column) =>{
258  var cellEl = document.createElement("td");
259 
260  var value = column.getFieldValue(rowData);
261 
262  var cellWrapper = {
263  modules:{},
264  getValue:function(){
265  return value;
266  },
267  getField:function(){
268  return column.definition.field;
269  },
270  getElement:function(){
271  return cellEl;
272  },
273  getColumn:function(){
274  return column.getComponent();
275  },
276  getData:function(){
277  return rowData;
278  },
279  getRow:function(){
280  return row.getComponent();
281  },
282  getComponent:function(){
283  return cellWrapper;
284  },
285  column:column,
286  };
287 
288  var classNames = column.definition.cssClass ? column.definition.cssClass.split(" ") : [];
289 
290  classNames.forEach(function(className) {
291  cellEl.classList.add(className);
292  });
293 
294  if(this.table.modExists("format")){
295  value = this.table.modules.format.formatValue(cellWrapper);
296  }else{
297  switch(typeof value){
298  case "object":
299  value = JSON.stringify(value);
300  break;
301 
302  case "undefined":
303  case "null":
304  value = "";
305  break;
306 
307  default:
308  value = value;
309  }
310  }
311 
312  if(value instanceof Node){
313  cellEl.appendChild(value);
314  }else{
315  cellEl.innerHTML = value;
316  }
317 
318  if(firstCell){
319  this.mapElementStyles(firstCell, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom", "border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "text-align"]);
320  }
321 
322  rowEl.appendChild(cellEl);
323  });
324 
325 
326  styleRow = row.type == "calc" ? calcRow : (((i % 2) && evenRow) ? evenRow : oddRow);
327 
328  this.mapElementStyles(styleRow, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
329  break;
330  }
331 
332  bodyEl.appendChild(rowEl);
333  });
334 
335  return bodyEl;
336 };
337 
338 HtmlTableExport.prototype.columnVisCheck = function(column){
339  return column.definition[this.colVisProp] !== false && (column.visible || (!column.visible && column.definition[this.colVisProp]));
340 };
341 
342 
343 HtmlTableExport.prototype.getHtml = function(visible, style, config){
344  var holder = document.createElement("div");
345 
346  holder.appendChild(this.genereateTable(config || this.table.options.htmlOutputConfig, style, visible, "htmlOutput"));
347 
348  return holder.innerHTML;
349 };
350 
351 
352 HtmlTableExport.prototype.mapElementStyles = function(from, to, props){
353  if(this.cloneTableStyle && from && to){
354 
355  var lookup = {
356  "background-color" : "backgroundColor",
357  "color" : "fontColor",
358  "width" : "width",
359  "font-weight" : "fontWeight",
360  "font-family" : "fontFamily",
361  "font-size" : "fontSize",
362  "text-align" : "textAlign",
363  "border-top" : "borderTop",
364  "border-left" : "borderLeft",
365  "border-right" : "borderRight",
366  "border-bottom" : "borderBottom",
367  "padding-top" : "paddingTop",
368  "padding-left" : "paddingLeft",
369  "padding-right" : "paddingRight",
370  "padding-bottom" : "paddingBottom",
371  };
372 
373  if(window.getComputedStyle){
374  var fromStyle = window.getComputedStyle(from);
375 
376  props.forEach(function(prop){
377  to.style[lookup[prop]] = fromStyle.getPropertyValue(prop);
378  });
379  }
380  }
381 };
382 
383 
384 Tabulator.prototype.registerModule("htmlTableExport", HtmlTableExport);