UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

1,560 lines (1,225 loc) 38.9 kB
//public column object var ColumnComponent = function (column){ this._column = column; this.type = "ColumnComponent"; }; ColumnComponent.prototype.getElement = function(){ return this._column.getElement(); }; ColumnComponent.prototype.getDefinition = function(){ return this._column.getDefinition(); }; ColumnComponent.prototype.getField = function(){ return this._column.getField(); }; ColumnComponent.prototype.getCells = function(){ var cells = []; this._column.cells.forEach(function(cell){ cells.push(cell.getComponent()); }); return cells; }; ColumnComponent.prototype.getVisibility = function(){ console.warn("getVisibility function is deprecated, you should now use the isVisible function"); return this._column.visible; }; ColumnComponent.prototype.isVisible = function(){ return this._column.visible; }; ColumnComponent.prototype.show = function(){ if(this._column.isGroup){ this._column.columns.forEach(function(column){ column.show(); }); }else{ this._column.show(); } }; ColumnComponent.prototype.hide = function(){ if(this._column.isGroup){ this._column.columns.forEach(function(column){ column.hide(); }); }else{ this._column.hide(); } }; ColumnComponent.prototype.toggle = function(){ if(this._column.visible){ this.hide(); }else{ this.show(); } }; ColumnComponent.prototype.delete = function(){ return this._column.delete(); }; ColumnComponent.prototype.getSubColumns = function(){ var output = []; if(this._column.columns.length){ this._column.columns.forEach(function(column){ output.push(column.getComponent()); }); } return output; }; ColumnComponent.prototype.getParentColumn = function(){ return this._column.parent instanceof Column ? this._column.parent.getComponent() : false; }; ColumnComponent.prototype._getSelf = function(){ return this._column; }; ColumnComponent.prototype.scrollTo = function(){ return this._column.table.columnManager.scrollToColumn(this._column); }; ColumnComponent.prototype.getTable = function(){ return this._column.table; }; ColumnComponent.prototype.headerFilterFocus = function(){ if(this._column.table.modExists("filter", true)){ this._column.table.modules.filter.setHeaderFilterFocus(this._column); } }; ColumnComponent.prototype.reloadHeaderFilter = function(){ if(this._column.table.modExists("filter", true)){ this._column.table.modules.filter.reloadHeaderFilter(this._column); } }; ColumnComponent.prototype.getHeaderFilterValue = function(){ if(this._column.table.modExists("filter", true)){ return this._column.table.modules.filter.getHeaderFilterValue(this._column); } }; ColumnComponent.prototype.setHeaderFilterValue = function(value){ if(this._column.table.modExists("filter", true)){ this._column.table.modules.filter.setHeaderFilterValue(this._column, value); } }; ColumnComponent.prototype.move = function(to, after){ var toColumn = this._column.table.columnManager.findColumn(to); if(toColumn){ this._column.table.columnManager.moveColumn(this._column, toColumn, after) }else{ console.warn("Move Error - No matching column found:", toColumn); } }; ColumnComponent.prototype.getNextColumn = function(){ var nextCol = this._column.nextColumn(); return nextCol ? nextCol.getComponent() : false; }; ColumnComponent.prototype.getPrevColumn = function(){ var prevCol = this._column.prevColumn(); return prevCol ? prevCol.getComponent() : false; }; ColumnComponent.prototype.updateDefinition = function(updates){ return this._column.updateDefinition(updates); }; ColumnComponent.prototype.getWidth = function(){ return this._column.getWidth(); }; ColumnComponent.prototype.setWidth = function(width){ var result; if(width === true){ result = this._column.reinitializeWidth(true); }else{ result = this._column.setWidth(width); } if(this._column.table.options.virtualDomHoz){ this._column.table.vdomHoz.reinitialize(true); } return result; }; ColumnComponent.prototype.validate = function(){ return this._column.validate(); }; var Column = function(def, parent){ var self = this; this.table = parent.table; this.definition = def; //column definition this.parent = parent; //hold parent object this.type = "column"; //type of element this.columns = []; //child columns this.cells = []; //cells bound to this column this.element = this.createElement(); //column header element this.contentElement = false; this.titleHolderElement = false; this.titleElement = false; this.groupElement = this.createGroupElement(); //column group holder element this.isGroup = false; this.tooltip = false; //hold column tooltip this.hozAlign = ""; //horizontal text alignment this.vertAlign = ""; //vert text alignment //multi dimensional filed handling this.field =""; this.fieldStructure = ""; this.getFieldValue = ""; this.setFieldValue = ""; this.titleFormatterRendered = false; this.setField(this.definition.field); if(this.table.options.invalidOptionWarnings){ this.checkDefinition(); } this.modules = {}; //hold module variables; this.cellEvents = { cellClick:false, cellDblClick:false, cellContext:false, cellTap:false, cellDblTap:false, cellTapHold:false, cellMouseEnter:false, cellMouseLeave:false, cellMouseOver:false, cellMouseOut:false, cellMouseMove:false, }; this.width = null; //column width this.widthStyled = ""; //column width prestyled to improve render efficiency this.maxWidth = null; //column maximum width this.maxWidthStyled = ""; //column maximum prestyled to improve render efficiency this.minWidth = null; //column minimum width this.minWidthStyled = ""; //column minimum prestyled to improve render efficiency this.widthFixed = false; //user has specified a width for this column this.visible = true; //default visible state this.component = null; this._mapDepricatedFunctionality(); //initialize column if(def.columns){ this.isGroup = true; def.columns.forEach(function(def, i){ var newCol = new Column(def, self); self.attachColumn(newCol); }); self.checkColumnVisibility(); }else{ parent.registerColumnField(this); } if(def.rowHandle && this.table.options.movableRows !== false && this.table.modExists("moveRow")){ this.table.modules.moveRow.setHandle(true); } this._buildHeader(); this.bindModuleColumns(); }; Column.prototype.createElement = function (){ var el = document.createElement("div"); el.classList.add("tabulator-col"); el.setAttribute("role", "columnheader"); el.setAttribute("aria-sort", "none"); return el; }; Column.prototype.createGroupElement = function (){ var el = document.createElement("div"); el.classList.add("tabulator-col-group-cols"); return el; }; Column.prototype.checkDefinition = function(){ Object.keys(this.definition).forEach((key) => { if(this.defaultOptionList.indexOf(key) === -1){ console.warn("Invalid column definition option in '" + (this.field || this.definition.title) + "' column:", key) } }); }; Column.prototype.setField = function(field){ this.field = field; this.fieldStructure = field ? (this.table.options.nestedFieldSeparator ? field.split(this.table.options.nestedFieldSeparator) : [field]) : []; this.getFieldValue = this.fieldStructure.length > 1 ? this._getNestedData : this._getFlatData; this.setFieldValue = this.fieldStructure.length > 1 ? this._setNestedData : this._setFlatData; }; //register column position with column manager Column.prototype.registerColumnPosition = function(column){ this.parent.registerColumnPosition(column); }; //register column position with column manager Column.prototype.registerColumnField = function(column){ this.parent.registerColumnField(column); }; //trigger position registration Column.prototype.reRegisterPosition = function(){ if(this.isGroup){ this.columns.forEach(function(column){ column.reRegisterPosition(); }); }else{ this.registerColumnPosition(this); } }; Column.prototype._mapDepricatedFunctionality = function(){ if(typeof this.definition.hideInHtml !== "undefined"){ this.definition.htmlOutput = !this.definition.hideInHtml; console.warn("hideInHtml column definition property is deprecated, you should now use htmlOutput") } if(typeof this.definition.align !== "undefined"){ this.definition.hozAlign = this.definition.align; console.warn("align column definition property is deprecated, you should now use hozAlign"); } if(typeof this.definition.downloadTitle !== "undefined"){ this.definition.titleDownload = this.definition.downloadTitle; console.warn("downloadTitle definition property is deprecated, you should now use titleDownload"); } }; Column.prototype.setTooltip = function(){ var self = this, def = self.definition; //set header tooltips var tooltip = def.headerTooltip || def.tooltip === false ? def.headerTooltip : self.table.options.tooltipsHeader; if(tooltip){ if(tooltip === true){ if(def.field){ self.table.modules.localize.bind("columns|" + def.field, function(value){ self.element.setAttribute("title", value || def.title); }); }else{ self.element.setAttribute("title", def.title); } }else{ if(typeof(tooltip) == "function"){ tooltip = tooltip(self.getComponent()); if(tooltip === false){ tooltip = ""; } } self.element.setAttribute("title", tooltip); } }else{ self.element.setAttribute("title", ""); } }; //build header element Column.prototype._buildHeader = function(){ var self = this, def = self.definition; while(self.element.firstChild) self.element.removeChild(self.element.firstChild); if(def.headerVertical){ self.element.classList.add("tabulator-col-vertical"); if(def.headerVertical === "flip"){ self.element.classList.add("tabulator-col-vertical-flip"); } } self.contentElement = self._bindEvents(); self.contentElement = self._buildColumnHeaderContent(); self.element.appendChild(self.contentElement); if(self.isGroup){ self._buildGroupHeader(); }else{ self._buildColumnHeader(); } self.setTooltip(); //set resizable handles if(self.table.options.resizableColumns && self.table.modExists("resizeColumns")){ self.table.modules.resizeColumns.initializeColumn("header", self, self.element); } //set resizable handles if(def.headerFilter && self.table.modExists("filter") && self.table.modExists("edit")){ if(typeof def.headerFilterPlaceholder !== "undefined" && def.field){ self.table.modules.localize.setHeaderFilterColumnPlaceholder(def.field, def.headerFilterPlaceholder); } self.table.modules.filter.initializeColumn(self); } //set resizable handles if(self.table.modExists("frozenColumns")){ self.table.modules.frozenColumns.initializeColumn(self); } //set movable column if(self.table.options.movableColumns && !self.isGroup && self.table.modExists("moveColumn")){ self.table.modules.moveColumn.initializeColumn(self); } //set calcs column if((def.topCalc || def.bottomCalc) && self.table.modExists("columnCalcs")){ self.table.modules.columnCalcs.initializeColumn(self); } //handle persistence if(self.table.modExists("persistence") && self.table.modules.persistence.config.columns){ self.table.modules.persistence.initializeColumn(self); } //update header tooltip on mouse enter self.element.addEventListener("mouseenter", function(e){ self.setTooltip(); }); }; Column.prototype._bindEvents = function(){ var self = this, def = self.definition, dblTap, tapHold, tap; //setup header click event bindings if(typeof(def.headerClick) == "function"){ self.element.addEventListener("click", function(e){def.headerClick(e, self.getComponent());}); } if(typeof(def.headerDblClick) == "function"){ self.element.addEventListener("dblclick", function(e){def.headerDblClick(e, self.getComponent());}); } if(typeof(def.headerContext) == "function"){ self.element.addEventListener("contextmenu", function(e){def.headerContext(e, self.getComponent());}); } //setup header tap event bindings if(typeof(def.headerTap) == "function"){ tap = false; self.element.addEventListener("touchstart", function(e){ tap = true; }, {passive: true}); self.element.addEventListener("touchend", function(e){ if(tap){ def.headerTap(e, self.getComponent()); } tap = false; }); } if(typeof(def.headerDblTap) == "function"){ dblTap = null; self.element.addEventListener("touchend", function(e){ if(dblTap){ clearTimeout(dblTap); dblTap = null; def.headerDblTap(e, self.getComponent()); }else{ dblTap = setTimeout(function(){ clearTimeout(dblTap); dblTap = null; }, 300); } }); } if(typeof(def.headerTapHold) == "function"){ tapHold = null; self.element.addEventListener("touchstart", function(e){ clearTimeout(tapHold); tapHold = setTimeout(function(){ clearTimeout(tapHold); tapHold = null; tap = false; def.headerTapHold(e, self.getComponent()); }, 1000); }, {passive: true}); self.element.addEventListener("touchend", function(e){ clearTimeout(tapHold); tapHold = null; }); } //store column cell click event bindings if(typeof(def.cellClick) == "function"){ self.cellEvents.cellClick = def.cellClick; } if(typeof(def.cellDblClick) == "function"){ self.cellEvents.cellDblClick = def.cellDblClick; } if(typeof(def.cellContext) == "function"){ self.cellEvents.cellContext = def.cellContext; } //store column mouse event bindings if(typeof(def.cellMouseEnter) == "function"){ self.cellEvents.cellMouseEnter = def.cellMouseEnter; } if(typeof(def.cellMouseLeave) == "function"){ self.cellEvents.cellMouseLeave = def.cellMouseLeave; } if(typeof(def.cellMouseOver) == "function"){ self.cellEvents.cellMouseOver = def.cellMouseOver; } if(typeof(def.cellMouseOut) == "function"){ self.cellEvents.cellMouseOut = def.cellMouseOut; } if(typeof(def.cellMouseMove) == "function"){ self.cellEvents.cellMouseMove = def.cellMouseMove; } //setup column cell tap event bindings if(typeof(def.cellTap) == "function"){ self.cellEvents.cellTap = def.cellTap; } if(typeof(def.cellDblTap) == "function"){ self.cellEvents.cellDblTap = def.cellDblTap; } if(typeof(def.cellTapHold) == "function"){ self.cellEvents.cellTapHold = def.cellTapHold; } //setup column cell edit callbacks if(typeof(def.cellEdited) == "function"){ self.cellEvents.cellEdited = def.cellEdited; } if(typeof(def.cellEditing) == "function"){ self.cellEvents.cellEditing = def.cellEditing; } if(typeof(def.cellEditCancelled) == "function"){ self.cellEvents.cellEditCancelled = def.cellEditCancelled; } }; //build header element for header Column.prototype._buildColumnHeader = function(){ var def = this.definition, table = this.table, sortable; //set column sorter if(table.modExists("sort")){ table.modules.sort.initializeColumn(this, this.titleHolderElement); } //set column header context menu if((def.headerContextMenu || def.headerClickMenu || def.headerMenu) && table.modExists("menu")){ table.modules.menu.initializeColumnHeader(this); } //set column formatter if(table.modExists("format")){ table.modules.format.initializeColumn(this); } //set column editor if(typeof def.editor != "undefined" && table.modExists("edit")){ table.modules.edit.initializeColumn(this); } //set colum validator if(typeof def.validator != "undefined" && table.modExists("validate")){ table.modules.validate.initializeColumn(this); } //set column mutator if(table.modExists("mutator")){ table.modules.mutator.initializeColumn(this); } //set column accessor if(table.modExists("accessor")){ table.modules.accessor.initializeColumn(this); } //set respoviveLayout if(typeof table.options.responsiveLayout && table.modExists("responsiveLayout")){ table.modules.responsiveLayout.initializeColumn(this); } //set column visibility if(typeof def.visible != "undefined"){ if(def.visible){ this.show(true); }else{ this.hide(true); } } //asign additional css classes to column header if(def.cssClass){ var classeNames = def.cssClass.split(" "); classeNames.forEach((className) => { this.element.classList.add(className); }); } if(def.field){ this.element.setAttribute("tabulator-field", def.field); } //set min width if present this.setMinWidth(typeof def.minWidth == "undefined" ? this.table.options.columnMinWidth : parseInt(def.minWidth)); if(def.maxWidth || this.table.options.columnMaxWidth){ if(def.maxWidth !== false){ this.setMaxWidth(typeof def.maxWidth == "undefined" ? this.table.options.columnMaxWidth : parseInt(def.maxWidth)); } } this.reinitializeWidth(); //set tooltip if present this.tooltip = this.definition.tooltip || this.definition.tooltip === false ? this.definition.tooltip : this.table.options.tooltips; //set orizontal text alignment this.hozAlign = typeof(this.definition.hozAlign) == "undefined" ? this.table.options.cellHozAlign : this.definition.hozAlign; this.vertAlign = typeof(this.definition.vertAlign) == "undefined" ? this.table.options.cellVertAlign : this.definition.vertAlign; this.titleElement.style.textAlign = this.definition.headerHozAlign || this.table.options.headerHozAlign; }; Column.prototype._buildColumnHeaderContent = function(){ var def = this.definition, table = this.table; var contentElement = document.createElement("div"); contentElement.classList.add("tabulator-col-content"); this.titleHolderElement = document.createElement("div"); this.titleHolderElement.classList.add("tabulator-col-title-holder"); contentElement.appendChild(this.titleHolderElement); this.titleElement = this._buildColumnHeaderTitle(); this.titleHolderElement.appendChild(this.titleElement); return contentElement; }; //build title element of column Column.prototype._buildColumnHeaderTitle = function(){ var self = this, def = self.definition, table = self.table, title; var titleHolderElement = document.createElement("div"); titleHolderElement.classList.add("tabulator-col-title"); if(def.editableTitle){ var titleElement = document.createElement("input"); titleElement.classList.add("tabulator-title-editor"); titleElement.addEventListener("click", function(e){ e.stopPropagation(); titleElement.focus(); }); titleElement.addEventListener("change", function(){ def.title = titleElement.value; table.options.columnTitleChanged.call(self.table, self.getComponent()); }); titleHolderElement.appendChild(titleElement); if(def.field){ table.modules.localize.bind("columns|" + def.field, function(text){ titleElement.value = text || (def.title || "&nbsp;"); }); }else{ titleElement.value = def.title || "&nbsp;"; } }else{ if(def.field){ table.modules.localize.bind("columns|" + def.field, function(text){ self._formatColumnHeaderTitle(titleHolderElement, text || (def.title || "&nbsp;")); }); }else{ self._formatColumnHeaderTitle(titleHolderElement, def.title || "&nbsp;"); } } return titleHolderElement; }; Column.prototype._formatColumnHeaderTitle = function(el, title){ var formatter, contents, params, mockCell, onRendered; if(this.definition.titleFormatter && this.table.modExists("format")){ formatter = this.table.modules.format.getFormatter(this.definition.titleFormatter); onRendered = (callback) => { this.titleFormatterRendered = callback; }; mockCell = { getValue:function(){ return title; }, getElement:function(){ return el; } }; params = this.definition.titleFormatterParams || {}; params = typeof params === "function" ? params() : params; contents = formatter.call(this.table.modules.format, mockCell, params, onRendered); switch(typeof contents){ case "object": if(contents instanceof Node){ el.appendChild(contents); }else{ el.innerHTML = ""; console.warn("Format Error - Title formatter has returned a type of object, the only valid formatter object return is an instance of Node, the formatter returned:", contents); } break; case "undefined": case "null": el.innerHTML = ""; break; default: el.innerHTML = contents; } }else{ el.innerHTML = title; } }; //build header element for column group Column.prototype._buildGroupHeader = function(){ this.element.classList.add("tabulator-col-group"); this.element.setAttribute("role", "columngroup"); this.element.setAttribute("aria-title", this.definition.title); //asign additional css classes to column header if(this.definition.cssClass){ var classeNames = this.definition.cssClass.split(" "); classeNames.forEach((className) => { this.element.classList.add(className); }); } //set column header context menu if ((this.definition.headerContextMenu || this.definition.headerMenu) && this.table.modExists("menu")) { this.table.modules.menu.initializeColumnHeader(this); } this.titleElement.style.textAlign = this.definition.headerHozAlign || this.table.options.headerHozAlign; this.element.appendChild(this.groupElement); }; //flat field lookup Column.prototype._getFlatData = function(data){ return data[this.field]; }; //nested field lookup Column.prototype._getNestedData = function(data){ var dataObj = data, structure = this.fieldStructure, length = structure.length, output; for(let i = 0; i < length; i++){ dataObj = dataObj[structure[i]]; output = dataObj; if(!dataObj){ break; } } return output; }; //flat field set Column.prototype._setFlatData = function(data, value){ if(this.field){ data[this.field] = value; } }; //nested field set Column.prototype._setNestedData = function(data, value){ var dataObj = data, structure = this.fieldStructure, length = structure.length; for(let i = 0; i < length; i++){ if(i == length -1){ dataObj[structure[i]] = value; }else{ if(!dataObj[structure[i]]){ if(typeof value !== "undefined"){ dataObj[structure[i]] = {}; }else{ break; } } dataObj = dataObj[structure[i]]; } } }; //attach column to this group Column.prototype.attachColumn = function(column){ var self = this; if(self.groupElement){ self.columns.push(column); self.groupElement.appendChild(column.getElement()); }else{ console.warn("Column Warning - Column being attached to another column instead of column group"); } }; //vertically align header in column Column.prototype.verticalAlign = function(alignment, height){ //calculate height of column header and group holder element var parentHeight = this.parent.isGroup ? this.parent.getGroupElement().clientHeight : (height || this.parent.getHeadersElement().clientHeight); // var parentHeight = this.parent.isGroup ? this.parent.getGroupElement().clientHeight : this.parent.getHeadersElement().clientHeight; this.element.style.height = parentHeight + "px"; if(this.isGroup){ this.groupElement.style.minHeight = (parentHeight - this.contentElement.offsetHeight) + "px"; } //vertically align cell contents if(!this.isGroup && alignment !== "top"){ if(alignment === "bottom"){ this.element.style.paddingTop = (this.element.clientHeight - this.contentElement.offsetHeight) + "px"; }else{ this.element.style.paddingTop = ((this.element.clientHeight - this.contentElement.offsetHeight) / 2) + "px"; } } this.columns.forEach(function(column){ column.verticalAlign(alignment); }); }; //clear vertical alignmenet Column.prototype.clearVerticalAlign = function(){ this.element.style.paddingTop = ""; this.element.style.height = ""; this.element.style.minHeight = ""; this.groupElement.style.minHeight = ""; this.columns.forEach(function(column){ column.clearVerticalAlign(); }); }; Column.prototype.bindModuleColumns = function (){ //check if rownum formatter is being used on a column if(this.definition.formatter == "rownum"){ this.table.rowManager.rowNumColumn = this; } }; //// Retreive Column Information //// //return column header element Column.prototype.getElement = function(){ return this.element; }; //return colunm group element Column.prototype.getGroupElement = function(){ return this.groupElement; }; //return field name Column.prototype.getField = function(){ return this.field; }; //return the first column in a group Column.prototype.getFirstColumn = function(){ if(!this.isGroup){ return this; }else{ if(this.columns.length){ return this.columns[0].getFirstColumn(); }else{ return false; } } }; //return the last column in a group Column.prototype.getLastColumn = function(){ if(!this.isGroup){ return this; }else{ if(this.columns.length){ return this.columns[this.columns.length -1].getLastColumn(); }else{ return false; } } }; //return all columns in a group Column.prototype.getColumns = function(){ return this.columns; }; //return all columns in a group Column.prototype.getCells = function(){ return this.cells; }; //retreive the top column in a group of columns Column.prototype.getTopColumn = function(){ if(this.parent.isGroup){ return this.parent.getTopColumn(); }else{ return this; } }; //return column definition object Column.prototype.getDefinition = function(updateBranches){ var colDefs = []; if(this.isGroup && updateBranches){ this.columns.forEach(function(column){ colDefs.push(column.getDefinition(true)); }); this.definition.columns = colDefs; } return this.definition; }; //////////////////// Actions //////////////////// Column.prototype.checkColumnVisibility = function(){ var visible = false; this.columns.forEach(function(column){ if(column.visible){ visible = true; } }); if(visible){ this.show(); this.parent.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), false); }else{ this.hide(); } }; //show column Column.prototype.show = function(silent, responsiveToggle){ if(!this.visible){ this.visible = true; this.element.style.display = ""; if(this.parent.isGroup){ this.parent.checkColumnVisibility(); } this.cells.forEach(function(cell){ cell.show(); }); if(!this.isGroup && this.width === null){ this.reinitializeWidth(); } this.table.columnManager._verticalAlignHeaders(); if(this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns){ this.table.modules.persistence.save("columns"); } if(!responsiveToggle && this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)){ this.table.modules.responsiveLayout.updateColumnVisibility(this, this.visible); } if(!silent){ this.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), true); } if(this.parent.isGroup){ this.parent.matchChildWidths(); } if(!this.silent && this.table.options.virtualDomHoz){ this.table.vdomHoz.reinitialize(); } } }; //hide column Column.prototype.hide = function(silent, responsiveToggle){ if(this.visible){ this.visible = false; this.element.style.display = "none"; this.table.columnManager._verticalAlignHeaders(); if(this.parent.isGroup){ this.parent.checkColumnVisibility(); } this.cells.forEach(function(cell){ cell.hide(); }); if(this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns){ this.table.modules.persistence.save("columns"); } if(!responsiveToggle && this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)){ this.table.modules.responsiveLayout.updateColumnVisibility(this, this.visible); } if(!silent){ this.table.options.columnVisibilityChanged.call(this.table, this.getComponent(), false); } if(this.parent.isGroup){ this.parent.matchChildWidths(); } if(!this.silent && this.table.options.virtualDomHoz){ this.table.vdomHoz.reinitialize(); } } }; Column.prototype.matchChildWidths = function(){ var childWidth = 0; if(this.contentElement && this.columns.length){ this.columns.forEach(function(column){ if(column.visible){ childWidth += column.getWidth(); } }); this.contentElement.style.maxWidth = (childWidth - 1) + "px"; if(this.parent.isGroup){ this.parent.matchChildWidths(); } } }; Column.prototype.removeChild = function(child){ var index = this.columns.indexOf(child); if(index > -1){ this.columns.splice(index, 1); } if(!this.columns.length){ this.delete(); } }; Column.prototype.setWidth = function(width){ this.widthFixed = true; this.setWidthActual(width); }; Column.prototype.setWidthActual = function(width){ if(isNaN(width)){ width = Math.floor((this.table.element.clientWidth/100) * parseInt(width)); } width = Math.max(this.minWidth, width); if(this.maxWidth){ width = Math.min(this.maxWidth, width); } this.width = width; this.widthStyled = width ? width + "px" : ""; this.element.style.width = this.widthStyled; if(!this.isGroup){ this.cells.forEach(function(cell){ cell.setWidth(); }); } if(this.parent.isGroup){ this.parent.matchChildWidths(); } //set resizable handles if(this.table.modExists("frozenColumns")){ this.table.modules.frozenColumns.layout(); } }; Column.prototype.checkCellHeights = function(){ var rows = []; this.cells.forEach(function(cell){ if(cell.row.heightInitialized){ if(cell.row.getElement().offsetParent !== null){ rows.push(cell.row); cell.row.clearCellHeight(); }else{ cell.row.heightInitialized = false; } } }); rows.forEach(function(row){ row.calcHeight(); }); rows.forEach(function(row){ row.setCellHeight(); }); }; Column.prototype.getWidth = function(){ var width = 0; if(this.isGroup){ this.columns.forEach(function(column){ if(column.visible){ width += column.getWidth(); } }); }else{ width = this.width; } return width; }; Column.prototype.getHeight = function(){ return this.element.offsetHeight; }; Column.prototype.setMinWidth = function(minWidth){ this.minWidth = minWidth; this.minWidthStyled = minWidth ? minWidth + "px" : ""; this.element.style.minWidth = this.minWidthStyled; this.cells.forEach(function(cell){ cell.setMinWidth(); }); }; Column.prototype.setMaxWidth = function(maxWidth){ this.maxWidth = maxWidth; this.maxWidthStyled = maxWidth ? maxWidth + "px" : ""; this.element.style.maxWidth = this.maxWidthStyled; this.cells.forEach(function(cell){ cell.setMaxWidth(); }); }; Column.prototype.delete = function(){ return new Promise((resolve, reject) => { var index; if(this.isGroup){ this.columns.forEach(function(column){ column.delete(); }); } //cancel edit if column is currently being edited if(this.table.modExists("edit")){ if(this.table.modules.edit.currentCell.column === this){ this.table.modules.edit.cancelEdit(); } } var cellCount = this.cells.length; for(let i = 0; i < cellCount; i++){ this.cells[0].delete(); } if(this.element.parentNode){ this.element.parentNode.removeChild(this.element); } this.element = false; this.contentElement = false; this.titleElement = false; this.groupElement = false; if(this.parent.isGroup){ this.parent.removeChild(this); } this.table.columnManager.deregisterColumn(this); if(this.table.options.virtualDomHoz){ this.table.vdomHoz.reinitialize(true); } resolve(); }); }; Column.prototype.columnRendered = function(){ if(this.titleFormatterRendered){ this.titleFormatterRendered(); } }; Column.prototype.validate = function(){ var invalid = []; this.cells.forEach(function(cell){ if(!cell.validate()){ invalid.push(cell.getComponent()); } }); return invalid.length ? invalid : true; }; //////////////// Cell Management ///////////////// //generate cell for this column Column.prototype.generateCell = function(row){ var self = this; var cell = new Cell(self, row); this.cells.push(cell); return cell; }; Column.prototype.nextColumn = function(){ var index = this.table.columnManager.findColumnIndex(this); return index > -1 ? this._nextVisibleColumn(index + 1) : false; }; Column.prototype._nextVisibleColumn = function(index){ var column = this.table.columnManager.getColumnByIndex(index); return !column || column.visible ? column : this._nextVisibleColumn(index + 1); }; Column.prototype.prevColumn = function(){ var index = this.table.columnManager.findColumnIndex(this); return index > -1 ? this._prevVisibleColumn(index - 1) : false; }; Column.prototype._prevVisibleColumn = function(index){ var column = this.table.columnManager.getColumnByIndex(index); return !column || column.visible ? column : this._prevVisibleColumn(index - 1); }; Column.prototype.reinitializeWidth = function(force){ this.widthFixed = false; //set width if present if(typeof this.definition.width !== "undefined" && !force){ this.setWidth(this.definition.width); } //hide header filters to prevent them altering column width if(this.table.modExists("filter")){ this.table.modules.filter.hideHeaderFilterElements(); } this.fitToData(); //show header filters again after layout is complete if(this.table.modExists("filter")){ this.table.modules.filter.showHeaderFilterElements(); } }; //set column width to maximum cell width Column.prototype.fitToData = function(){ var self = this; if(!this.widthFixed){ this.element.style.width = ""; self.cells.forEach(function(cell){ cell.clearWidth(); }); } var maxWidth = this.element.offsetWidth; if(!self.width || !this.widthFixed){ self.cells.forEach(function(cell){ var width = cell.getWidth(); if(width > maxWidth){ maxWidth = width; } }); if(maxWidth){ self.setWidthActual(maxWidth + 1); } } }; Column.prototype.updateDefinition = function(updates){ return new Promise((resolve, reject) => { var definition; if(!this.isGroup){ if(!this.parent.isGroup){ definition = Object.assign({}, this.getDefinition()); definition = Object.assign(definition, updates); this.table.columnManager.addColumn(definition, false, this) .then((column) => { if(definition.field == this.field){ this.field = false; //cleair field name to prevent deletion of duplicate column from arrays } this.delete() .then(() => { resolve(column.getComponent()); }).catch((err) => { reject(err); }); }).catch((err) => { reject(err); }); }else{ console.warn("Column Update Error - The updateDefinition function is only available on ungrouped columns"); reject("Column Update Error - The updateDefinition function is only available on columns, not column groups"); } }else{ console.warn("Column Update Error - The updateDefinition function is only available on ungrouped columns"); reject("Column Update Error - The updateDefinition function is only available on columns, not column groups"); } }); }; Column.prototype.deleteCell = function(cell){ var index = this.cells.indexOf(cell); if(index > -1){ this.cells.splice(index, 1); } }; Column.prototype.defaultOptionList = [ "title", "field", "columns", "visible", "align", "hozAlign", "vertAlign", "width", "minWidth", "maxWidth", "widthGrow", "widthShrink", "resizable", "frozen", "responsive", "tooltip", "cssClass", "rowHandle", "hideInHtml", "print", "htmlOutput", "sorter", "sorterParams", "formatter", "formatterParams", "variableHeight", "editable", "editor", "editorParams", "validator", "mutator", "mutatorParams", "mutatorData", "mutatorDataParams", "mutatorEdit", "mutatorEditParams", "mutatorClipboard", "mutatorClipboardParams", "accessor", "accessorParams", "accessorData", "accessorDataParams", "accessorDownload", "accessorDownloadParams", "accessorClipboard", "accessorClipboardParams", "accessorPrint", "accessorPrintParams", "accessorHtmlOutput", "accessorHtmlOutputParams", "clipboard", "download", "downloadTitle", "topCalc", "topCalcParams", "topCalcFormatter", "topCalcFormatterParams", "bottomCalc", "bottomCalcParams", "bottomCalcFormatter", "bottomCalcFormatterParams", "cellClick", "cellDblClick", "cellContext", "cellTap", "cellDblTap", "cellTapHold", "cellMouseEnter", "cellMouseLeave", "cellMouseOver", "cellMouseOut", "cellMouseMove", "cellEditing", "cellEdited", "cellEditCancelled", "headerSort", "headerSortStartingDir", "headerSortTristate", "headerClick", "headerDblClick", "headerContext", "headerTap", "headerDblTap", "headerTapHold", "headerTooltip", "headerVertical", "headerHozAlign", "editableTitle", "titleFormatter", "titleFormatterParams", "headerFilter", "headerFilterPlaceholder", "headerFilterParams", "headerFilterEmptyCheck", "headerFilterFunc", "headerFilterFuncParams", "headerFilterLiveFilter", "print", "headerContextMenu", "headerMenu", "contextMenu", // "headerClickMenu", "clickMenu", "formatterPrint", "formatterPrintParams", "formatterClipboard", "formatterClipboardParams", "formatterHtmlOutput", "formatterHtmlOutputParams", "titlePrint", "titleClipboard", "titleHtmlOutput", "titleDownload", ]; //////////////// Event Bindings ///////////////// //////////////// Object Generation ///////////////// Column.prototype.getComponent = function(){ if(!this.component){ this.component = new ColumnComponent(this); } return this.component; };