tabulator-tables
Version:
Interactive table generation JavaScript library
301 lines (243 loc) • 7.66 kB
JavaScript
var ResponsiveLayout = function(table){
this.table = table; //hold Tabulator object
this.columns = [];
this.hiddenColumns = [];
this.mode = "";
this.index = 0;
this.collapseFormatter = [];
this.collapseStartOpen = true;
this.collapseHandleColumn = false;
};
//generate resposive columns list
ResponsiveLayout.prototype.initialize = function(){
var self = this,
columns = [];
this.mode = this.table.options.responsiveLayout;
this.collapseFormatter = this.table.options.responsiveLayoutCollapseFormatter || this.formatCollapsedData;
this.collapseStartOpen = this.table.options.responsiveLayoutCollapseStartOpen;
this.hiddenColumns = [];
//detemine level of responsivity for each column
this.table.columnManager.columnsByIndex.forEach(function(column, i){
if(column.modules.responsive){
if(column.modules.responsive.order && column.modules.responsive.visible){
column.modules.responsive.index = i;
columns.push(column);
if(!column.visible && self.mode === "collapse"){
self.hiddenColumns.push(column);
}
}
}
});
//sort list by responsivity
columns = columns.reverse();
columns = columns.sort(function(a, b){
var diff = b.modules.responsive.order - a.modules.responsive.order;
return diff || (b.modules.responsive.index - a.modules.responsive.index);
});
this.columns = columns;
if(this.mode === "collapse"){
this.generateCollapsedContent();
}
//assign collapse column
for (let col of this.table.columnManager.columnsByIndex){
if(col.definition.formatter == "responsiveCollapse"){
this.collapseHandleColumn = col;
break;
}
}
if(this.collapseHandleColumn){
if(this.hiddenColumns.length){
this.collapseHandleColumn.show();
}else{
this.collapseHandleColumn.hide();
}
}
};
//define layout information
ResponsiveLayout.prototype.initializeColumn = function(column){
var def = column.getDefinition();
column.modules.responsive = {order: typeof def.responsive === "undefined" ? 1 : def.responsive, visible:def.visible === false ? false : true};
};
ResponsiveLayout.prototype.initializeRow = function(row){
var el;
if(row.type !== "calc"){
el = document.createElement("div");
el.classList.add("tabulator-responsive-collapse");
row.modules.responsiveLayout = {
element:el,
open:this.collapseStartOpen,
};
if(!this.collapseStartOpen){
el.style.display = 'none';
}
}
};
ResponsiveLayout.prototype.layoutRow = function(row){
var rowEl = row.getElement();
if(row.modules.responsiveLayout){
rowEl.appendChild(row.modules.responsiveLayout.element);
this.generateCollapsedRowContent(row);
}
};
//update column visibility
ResponsiveLayout.prototype.updateColumnVisibility = function(column, visible){
var index;
if(column.modules.responsive){
column.modules.responsive.visible = visible;
this.initialize();
}
};
ResponsiveLayout.prototype.hideColumn = function(column){
var colCount = this.hiddenColumns.length;
column.hide(false, true);
if(this.mode === "collapse"){
this.hiddenColumns.unshift(column);
this.generateCollapsedContent();
if(this.collapseHandleColumn && !colCount){
this.collapseHandleColumn.show();
}
}
};
ResponsiveLayout.prototype.showColumn = function(column){
var index;
column.show(false, true);
//set column width to prevent calculation loops on uninitialized columns
column.setWidth(column.getWidth());
if(this.mode === "collapse"){
index = this.hiddenColumns.indexOf(column);
if(index > -1){
this.hiddenColumns.splice(index, 1);
}
this.generateCollapsedContent();
if(this.collapseHandleColumn && !this.hiddenColumns.length){
this.collapseHandleColumn.hide();
}
}
};
//redraw columns to fit space
ResponsiveLayout.prototype.update = function(){
var self = this,
working = true;
while(working){
let width = self.table.modules.layout.getMode() == "fitColumns" ? self.table.columnManager.getFlexBaseWidth() : self.table.columnManager.getWidth();
let diff = (self.table.options.headerVisible ? self.table.columnManager.element.clientWidth : self.table.element.clientWidth) - width;
if(diff < 0){
//table is too wide
let column = self.columns[self.index];
if(column){
self.hideColumn(column);
self.index ++;
}else{
working = false;
}
}else{
//table has spare space
let column = self.columns[self.index -1];
if(column){
if(diff > 0){
if(diff >= column.getWidth()){
self.showColumn(column);
self.index --;
}else{
working = false;
}
}else{
working = false;
}
}else{
working = false;
}
}
if(!self.table.rowManager.activeRowsCount){
self.table.rowManager.renderEmptyScroll();
}
}
};
ResponsiveLayout.prototype.generateCollapsedContent = function(){
var self = this,
rows = this.table.rowManager.getDisplayRows();
rows.forEach(function(row){
self.generateCollapsedRowContent(row);
});
};
ResponsiveLayout.prototype.generateCollapsedRowContent = function(row){
var el, contents;
if(row.modules.responsiveLayout){
el = row.modules.responsiveLayout.element;
while(el.firstChild) el.removeChild(el.firstChild);
contents = this.collapseFormatter(this.generateCollapsedRowData(row));
if(contents){
el.appendChild(contents);
}
}
};
ResponsiveLayout.prototype.generateCollapsedRowData = function(row){
var self = this,
data = row.getData(),
output = [],
mockCellComponent;
this.hiddenColumns.forEach(function(column){
var value = column.getFieldValue(data);
if(column.definition.title && column.field){
if(column.modules.format && self.table.options.responsiveLayoutCollapseUseFormatters){
mockCellComponent = {
value:false,
data:{},
getValue:function(){
return value;
},
getData:function(){
return data;
},
getElement:function(){
return document.createElement("div");
},
getRow:function(){
return row.getComponent();
},
getColumn:function(){
return column.getComponent();
},
};
output.push({
field: column.field,
title: column.definition.title,
value: column.modules.format.formatter.call(self.table.modules.format, mockCellComponent, column.modules.format.params)
});
}else{
output.push({
field: column.field,
title: column.definition.title,
value: value
});
}
}
});
return output;
};
ResponsiveLayout.prototype.formatCollapsedData = function(data){
var list = document.createElement("table");
data.forEach(function(item){
var row = document.createElement("tr");
var titleData = document.createElement("td");
var valueData = document.createElement("td");
var node_content;
var titleHighlight = document.createElement("strong");
titleData.appendChild(titleHighlight);
this.table.modules.localize.bind("columns|" + item.field, function(text){
titleHighlight.innerText = text || item.title;
});
if(item.value instanceof Node){
node_content = document.createElement("div");
node_content.appendChild(item.value);
valueData.appendChild(node_content);
}else{
valueData.innerHTML = item.value;
}
row.appendChild(titleData);
row.appendChild(valueData);
list.appendChild(row);
}, this);
return Object.keys(data).length ? list : "";
};
Tabulator.prototype.registerModule("responsiveLayout", ResponsiveLayout);