UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

606 lines (465 loc) 14.9 kB
import Helpers from '../../core/tools/Helpers.js'; import GroupComponent from './GroupComponent.js'; //Group functions class Group{ constructor(groupManager, parent, level, key, field, generator, oldGroup){ this.groupManager = groupManager; this.parent = parent; this.key = key; this.level = level; this.field = field; this.hasSubGroups = level < (groupManager.groupIDLookups.length - 1); this.addRow = this.hasSubGroups ? this._addRowToGroup : this._addRow; this.type = "group"; //type of element this.old = oldGroup; this.rows = []; this.groups = []; this.groupList = []; this.generator = generator; this.element = false; this.elementContents = false; this.height = 0; this.outerHeight = 0; this.initialized = false; this.calcs = {}; this.initialized = false; this.modules = {}; this.arrowElement = false; this.visible = oldGroup ? oldGroup.visible : (typeof groupManager.startOpen[level] !== "undefined" ? groupManager.startOpen[level] : groupManager.startOpen[0]); this.component = null; this.createElements(); this.addBindings(); this.createValueGroups(); } wipe(){ if(this.groupList.length){ this.groupList.forEach(function(group){ group.wipe(); }); }else{ this.rows.forEach((row) => { if(row.modules){ delete row.modules.group; } }); } this.element = false; this.arrowElement = false; this.elementContents = false; } createElements(){ var arrow = document.createElement("div"); arrow.classList.add("tabulator-arrow"); this.element = document.createElement("div"); this.element.classList.add("tabulator-row"); this.element.classList.add("tabulator-group"); this.element.classList.add("tabulator-group-level-" + this.level); this.element.setAttribute("role", "rowgroup"); this.arrowElement = document.createElement("div"); this.arrowElement.classList.add("tabulator-group-toggle"); this.arrowElement.appendChild(arrow); //setup movable rows if(this.groupManager.table.options.movableRows !== false && this.groupManager.table.modExists("moveRow")){ this.groupManager.table.modules.moveRow.initializeGroupHeader(this); } } createValueGroups(){ var level = this.level + 1; if(this.groupManager.allowedValues && this.groupManager.allowedValues[level]){ this.groupManager.allowedValues[level].forEach((value) => { this._createGroup(value, level); }); } } addBindings(){ var toggleElement; if(this.groupManager.table.options.groupToggleElement){ toggleElement = this.groupManager.table.options.groupToggleElement == "arrow" ? this.arrowElement : this.element; toggleElement.addEventListener("click", (e) => { e.stopPropagation(); e.stopImmediatePropagation(); this.toggleVisibility(); }); } } _createGroup(groupID, level){ var groupKey = level + "_" + groupID; var group = new Group(this.groupManager, this, level, groupID, this.groupManager.groupIDLookups[level].field, this.groupManager.headerGenerator[level] || this.groupManager.headerGenerator[0], this.old ? this.old.groups[groupKey] : false); this.groups[groupKey] = group; this.groupList.push(group); } _addRowToGroup(row){ var level = this.level + 1; if(this.hasSubGroups){ var groupID = this.groupManager.groupIDLookups[level].func(row.getData()), groupKey = level + "_" + groupID; if(this.groupManager.allowedValues && this.groupManager.allowedValues[level]){ if(this.groups[groupKey]){ this.groups[groupKey].addRow(row); } }else{ if(!this.groups[groupKey]){ this._createGroup(groupID, level); } this.groups[groupKey].addRow(row); } } } _addRow(row){ this.rows.push(row); row.modules.group = this; } insertRow(row, to, after){ var data = this.conformRowData({}); row.updateData(data); var toIndex = this.rows.indexOf(to); if(toIndex > -1){ if(after){ this.rows.splice(toIndex+1, 0, row); }else{ this.rows.splice(toIndex, 0, row); } }else{ if(after){ this.rows.push(row); }else{ this.rows.unshift(row); } } row.modules.group = this; this.generateGroupHeaderContents(); if(this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table"){ this.groupManager.table.modules.columnCalcs.recalcGroup(this); } this.groupManager.updateGroupRows(true); } scrollHeader(left){ if(this.arrowElement){ this.arrowElement.style.marginLeft = left; this.groupList.forEach(function(child){ child.scrollHeader(left); }); } } getRowIndex(row){} //update row data to match grouping constraints conformRowData(data){ if(this.field){ data[this.field] = this.key; }else{ console.warn("Data Conforming Error - Cannot conform row data to match new group as groupBy is a function"); } if(this.parent){ data = this.parent.conformRowData(data); } return data; } removeRow(row){ var index = this.rows.indexOf(row); var el = row.getElement(); if(index > -1){ this.rows.splice(index, 1); } if(!this.groupManager.table.options.groupValues && !this.rows.length){ if(this.parent){ this.parent.removeGroup(this); }else{ this.groupManager.removeGroup(this); } this.groupManager.updateGroupRows(true); }else{ if(el.parentNode){ el.parentNode.removeChild(el); } this.generateGroupHeaderContents(); if(this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.options.columnCalcs != "table"){ this.groupManager.table.modules.columnCalcs.recalcGroup(this); } } } removeGroup(group){ var groupKey = group.level + "_" + group.key, index; if(this.groups[groupKey]){ delete this.groups[groupKey]; index = this.groupList.indexOf(group); if(index > -1){ this.groupList.splice(index, 1); } if(!this.groupList.length){ if(this.parent){ this.parent.removeGroup(this); }else{ this.groupManager.removeGroup(this); } } } } getHeadersAndRows(noCalc){ var output = []; output.push(this); this._visSet(); if(this.visible){ if(this.groupList.length){ this.groupList.forEach(function(group){ output = output.concat(group.getHeadersAndRows(noCalc)); }); }else{ if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){ if(this.calcs.top){ this.calcs.top.detachElement(); this.calcs.top.deleteCells(); } this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows); output.push(this.calcs.top); } output = output.concat(this.rows); if(!noCalc && this.groupManager.table.options.columnCalcs != "table" && this.groupManager.table.modExists("columnCalcs") && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){ if(this.calcs.bottom){ this.calcs.bottom.detachElement(); this.calcs.bottom.deleteCells(); } this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows); output.push(this.calcs.bottom); } } }else{ if(!this.groupList.length && this.groupManager.table.options.columnCalcs != "table"){ if(this.groupManager.table.modExists("columnCalcs")){ if(!noCalc && this.groupManager.table.modules.columnCalcs.hasTopCalcs()){ if(this.calcs.top){ this.calcs.top.detachElement(); this.calcs.top.deleteCells(); } if(this.groupManager.table.options.groupClosedShowCalcs){ this.calcs.top = this.groupManager.table.modules.columnCalcs.generateTopRow(this.rows); output.push(this.calcs.top); } } if(!noCalc && this.groupManager.table.modules.columnCalcs.hasBottomCalcs()){ if(this.calcs.bottom){ this.calcs.bottom.detachElement(); this.calcs.bottom.deleteCells(); } if(this.groupManager.table.options.groupClosedShowCalcs){ this.calcs.bottom = this.groupManager.table.modules.columnCalcs.generateBottomRow(this.rows); output.push(this.calcs.bottom); } } } } } return output; } getData(visible, transform){ var output = []; this._visSet(); if(!visible || (visible && this.visible)){ this.rows.forEach((row) => { output.push(row.getData(transform || "data")); }); } return output; } getRowCount(){ var count = 0; if(this.groupList.length){ this.groupList.forEach((group) => { count += group.getRowCount(); }); }else{ count = this.rows.length; } return count; } toggleVisibility(){ if(this.visible){ this.hide(); }else{ this.show(); } } hide(){ this.visible = false; if(this.groupManager.table.rowManager.getRenderMode() == "basic" && !this.groupManager.table.options.pagination){ this.element.classList.remove("tabulator-group-visible"); if(this.groupList.length){ this.groupList.forEach((group) => { var rows = group.getHeadersAndRows(); rows.forEach((row) => { row.detachElement(); }); }); }else{ this.rows.forEach((row) => { var rowEl = row.getElement(); rowEl.parentNode.removeChild(rowEl); }); } this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex()); this.groupManager.checkBasicModeGroupHeaderWidth(); }else{ this.groupManager.updateGroupRows(true); } this.groupManager.table.externalEvents.dispatch("groupVisibilityChanged", this.getComponent(), false); } show(){ this.visible = true; if(this.groupManager.table.rowManager.getRenderMode() == "basic" && !this.groupManager.table.options.pagination){ this.element.classList.add("tabulator-group-visible"); var prev = this.generateElement(); if(this.groupList.length){ this.groupList.forEach((group) => { var rows = group.getHeadersAndRows(); rows.forEach((row) => { var rowEl = row.getElement(); prev.parentNode.insertBefore(rowEl, prev.nextSibling); row.initialize(); prev = rowEl; }); }); }else{ this.rows.forEach((row) => { var rowEl = row.getElement(); prev.parentNode.insertBefore(rowEl, prev.nextSibling); row.initialize(); prev = rowEl; }); } this.groupManager.table.rowManager.setDisplayRows(this.groupManager.updateGroupRows(), this.groupManager.getDisplayIndex()); this.groupManager.checkBasicModeGroupHeaderWidth(); }else{ this.groupManager.updateGroupRows(true); } this.groupManager.table.externalEvents.dispatch("groupVisibilityChanged", this.getComponent(), true); } _visSet(){ var data = []; if(typeof this.visible == "function"){ this.rows.forEach(function(row){ data.push(row.getData()); }); this.visible = this.visible(this.key, this.getRowCount(), data, this.getComponent()); } } getRowGroup(row){ var match = false; if(this.groupList.length){ this.groupList.forEach(function(group){ var result = group.getRowGroup(row); if(result){ match = result; } }); }else{ if(this.rows.find(function(item){ return item === row; })){ match = this; } } return match; } getSubGroups(component){ var output = []; this.groupList.forEach(function(child){ output.push(component ? child.getComponent() : child); }); return output; } getRows(component){ var output = []; this.rows.forEach(function(row){ output.push(component ? row.getComponent() : row); }); return output; } generateGroupHeaderContents(){ var data = []; this.rows.forEach(function(row){ data.push(row.getData()); }); this.elementContents = this.generator(this.key, this.getRowCount(), data, this.getComponent()); while(this.element.firstChild) this.element.removeChild(this.element.firstChild); if(typeof this.elementContents === "string"){ this.element.innerHTML = this.elementContents; }else{ this.element.appendChild(this.elementContents); } this.element.insertBefore(this.arrowElement, this.element.firstChild); } getPath(path = []) { path.unshift(this.key); if(this.parent) { this.parent.getPath(path); } return path; } ////////////// Standard Row Functions ////////////// getElement(){ return this.elementContents ? this.element : this.generateElement(); } generateElement(){ this.addBindings = false; this._visSet(); if(this.visible){ this.element.classList.add("tabulator-group-visible"); }else{ this.element.classList.remove("tabulator-group-visible"); } for(var i = 0; i < this.element.childNodes.length; ++i){ this.element.childNodes[i].parentNode.removeChild(this.element.childNodes[i]); } this.generateGroupHeaderContents(); // this.addBindings(); return this.element; } detachElement(){ if (this.element && this.element.parentNode){ this.element.parentNode.removeChild(this.element); } } //normalize the height of elements in the row normalizeHeight(){ this.setHeight(this.element.clientHeight); } initialize(force){ if(!this.initialized || force){ this.normalizeHeight(); this.initialized = true; } } reinitialize(){ this.initialized = false; this.height = 0; if(Helpers.elVisible(this.element)){ this.initialize(true); } } setHeight(height){ if(this.height != height){ this.height = height; this.outerHeight = this.element.offsetHeight; } } //return rows outer height getHeight(){ return this.outerHeight; } getGroup(){ return this; } reinitializeHeight(){} calcHeight(){} setCellHeight(){} clearCellHeight(){} deinitializeHeight(){} //////////////// Object Generation ///////////////// getComponent(){ if(!this.component){ this.component = new GroupComponent(this); } return this.component; } } export default Group;