UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

301 lines (243 loc) 7.66 kB
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);