tabulator-tables
Version:
Interactive table generation JavaScript library
363 lines (272 loc) • 9.92 kB
JavaScript
var HtmlTableExport = function(table){
this.table = table; //hold Tabulator object
this.config = {};
this.cloneTableStyle = true;
this.colVisProp = "";
};
HtmlTableExport.prototype.genereateTable = function(config, style, visible, colVisProp){
this.cloneTableStyle = style;
this.config = config || {};
this.colVisProp = colVisProp;
var headers = this.generateHeaderElements();
var body = this.generateBodyElements(visible);
var table = document.createElement("table");
table.classList.add("tabulator-print-table");
table.appendChild(headers);
table.appendChild(body);
this.mapElementStyles(this.table.element, table, ["border-top", "border-left", "border-right", "border-bottom"]);
return table;
};
HtmlTableExport.prototype.generateColumnGroupHeaders = function(){
var output = [];
var columns = this.config.columnGroups !== false ? this.table.columnManager.columns : this.table.columnManager.columnsByIndex;
columns.forEach((column) => {
var colData = this.processColumnGroup(column);
if(colData){
output.push(colData);
}
});
return output;
};
HtmlTableExport.prototype.processColumnGroup = function(column){
var subGroups = column.columns,
maxDepth = 0;
var groupData = {
title:column.definition.title,
column:column,
depth:1,
};
if(subGroups.length){
groupData.subGroups = [];
groupData.width = 0;
subGroups.forEach((subGroup) => {
var subGroupData = this.processColumnGroup(subGroup);
if(subGroupData){
groupData.width += subGroupData.width;
groupData.subGroups.push(subGroupData);
if(subGroupData.depth > maxDepth){
maxDepth = subGroupData.depth;
}
}
});
groupData.depth += maxDepth;
if(!groupData.width){
return false;
}
}else{
if(column.field && this.columnVisCheck(column)){
groupData.width = 1;
}else{
return false;
}
}
return groupData;
};
HtmlTableExport.prototype.groupHeadersToRows = function(columns){
var headers = [], headerDepth = 0;
function parseColumnGroup(column, level){
var depth = headerDepth - level;
if(typeof headers[level] === "undefined"){
headers[level] = [];
}
column.height = column.subGroups ? 1 : (depth - column.depth) + 1;
headers[level].push(column);
if(column.subGroups){
column.subGroups.forEach(function(subGroup){
parseColumnGroup(subGroup, level+1);
});
}
}
//calculate maximum header debth
columns.forEach(function(column){
if(column.depth > headerDepth){
headerDepth = column.depth;
}
});
columns.forEach(function(column){
parseColumnGroup(column,0);
});
return headers;
};
HtmlTableExport.prototype.generateHeaderElements = function(){
var headerEl = document.createElement("thead");
var rows = this.groupHeadersToRows(this.generateColumnGroupHeaders());
rows.forEach((row) => {
var rowEl = document.createElement("tr");
this.mapElementStyles(this.table.columnManager.getHeadersElement(), headerEl, ["border-top", "border-left", "border-right", "border-bottom", "background-color", "color", "font-weight", "font-family", "font-size"]);
row.forEach((column) => {
var cellEl = document.createElement("th");
cellEl.colSpan = column.width;
cellEl.rowSpan = column.height;
cellEl.innerHTML = column.column.definition.title;
if(this.cloneTableStyle){
cellEl.style.boxSizing = "border-box";
}
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"]);
this.mapElementStyles(column.column.contentElement, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom"]);
if(column.column.visible){
this.mapElementStyles(column.column.getElement(), cellEl, ["width"]);
}else{
if(column.column.definition.width){
cellEl.style.width = column.column.definition.width + "px";
}
}
if(column.column.parent){
this.mapElementStyles(column.column.parent.groupElement, cellEl, ["border-top"]);
}
rowEl.appendChild(cellEl);
});
headerEl.appendChild(rowEl);
});
return headerEl;
};
HtmlTableExport.prototype.generateBodyElements = function(visible){
var oddRow, evenRow, calcRow, firstRow, firstCell, firstGroup, lastCell, styleCells, styleRow;
//lookup row styles
if(this.cloneTableStyle && window.getComputedStyle){
oddRow = this.table.element.querySelector(".tabulator-row-odd:not(.tabulator-group):not(.tabulator-calcs)");
evenRow = this.table.element.querySelector(".tabulator-row-even:not(.tabulator-group):not(.tabulator-calcs)");
calcRow = this.table.element.querySelector(".tabulator-row.tabulator-calcs");
firstRow = this.table.element.querySelector(".tabulator-row:not(.tabulator-group):not(.tabulator-calcs)");
firstGroup = this.table.element.getElementsByClassName("tabulator-group")[0];
if(firstRow){
styleCells = firstRow.getElementsByClassName("tabulator-cell");
firstCell = styleCells[0];
lastCell = styleCells[styleCells.length - 1];
}
}
var bodyEl = document.createElement("tbody");
var rows = visible ? this.table.rowManager.getVisibleRows(true) : this.table.rowManager.getDisplayRows();
var columns = [];
this.table.columnManager.columnsByIndex.forEach((column) => {
if (this.columnVisCheck(column)) {
columns.push(column);
}
});
rows = rows.filter((row) => {
switch(row.type){
case "group":
return this.config.rowGroups !== false;
break;
case "calc":
return this.config.columnCalcs !== false;
break;
}
return true;
});
if(rows.length > 1000){
console.warn("It may take a long time to render an HTML table with more than 1000 rows");
}
rows.forEach((row, i) => {
var rowData = row.getData();
var rowEl = document.createElement("tr");
rowEl.classList.add("tabulator-print-table-row");
switch(row.type){
case "group":
var cellEl = document.createElement("td");
cellEl.colSpan = columns.length;
cellEl.innerHTML = row.key;
rowEl.classList.add("tabulator-print-table-group");
this.mapElementStyles(firstGroup, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
this.mapElementStyles(firstGroup, cellEl, ["padding-top", "padding-left", "padding-right", "padding-bottom"]);
rowEl.appendChild(cellEl);
break;
case "calc" :
rowEl.classList.add("tabulator-print-table-calcs");
case "row" :
columns.forEach((column) =>{
var cellEl = document.createElement("td");
var value = column.getFieldValue(rowData);
var cellWrapper = {
getValue:function(){
return value;
},
getField:function(){
return column.definition.field;
},
getElement:function(){
return cellEl;
},
getColumn:function(){
return column.getComponent();
},
getRow:function(){
return {
normalizeHeight:function(){
}
};
},
getComponent:function(){
return cellWrapper;
},
column:column,
};
if(this.table.modExists("format")){
value = this.table.modules.format.formatValue(cellWrapper);
}else{
switch(typeof value){
case "object":
value = JSON.stringify(value);
break;
case "undefined":
case "null":
value = "";
break;
default:
value = value;
}
}
if(value instanceof Node){
cellEl.appendChild(value);
}else{
cellEl.innerHTML = value;
}
if(firstCell){
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"]);
}
rowEl.appendChild(cellEl);
});
styleRow = row.type == "calc" ? calcRow : (((i % 2) && evenRow) ? evenRow : oddRow);
this.mapElementStyles(styleRow, rowEl, ["border-top", "border-left", "border-right", "border-bottom", "color", "font-weight", "font-family", "font-size", "background-color"]);
break;
}
bodyEl.appendChild(rowEl);
});
return bodyEl;
};
HtmlTableExport.prototype.columnVisCheck = function(column){
return column.definition[this.colVisProp] !== false && (column.visible || (!column.visible && column.definition[this.colVisProp]));
};
HtmlTableExport.prototype.getHtml = function(visible, style, config){
var holder = document.createElement("div");
holder.appendChild(this.genereateTable(config || this.table.options.htmlOutputConfig, style, visible, "htmlOutput"));
return holder.innerHTML;
};
HtmlTableExport.prototype.mapElementStyles = function(from, to, props){
if(this.cloneTableStyle && from && to){
var lookup = {
"background-color" : "backgroundColor",
"color" : "fontColor",
"width" : "width",
"font-weight" : "fontWeight",
"font-family" : "fontFamily",
"font-size" : "fontSize",
"text-align" : "textAlign",
"border-top" : "borderTop",
"border-left" : "borderLeft",
"border-right" : "borderRight",
"border-bottom" : "borderBottom",
"padding-top" : "paddingTop",
"padding-left" : "paddingLeft",
"padding-right" : "paddingRight",
"padding-bottom" : "paddingBottom",
};
if(window.getComputedStyle){
var fromStyle = window.getComputedStyle(from);
props.forEach(function(prop){
to.style[lookup[prop]] = fromStyle.getPropertyValue(prop);
});
}
}
};
Tabulator.prototype.registerModule("htmlTableExport", HtmlTableExport);