UNPKG

tabulator-tables

Version:

Interactive table generation JavaScript library

2,253 lines (1,514 loc) 602 kB
/* Tabulator v4.9.3 (c) Oliver Folkerd */ 'use strict'; // https://tc39.github.io/ecma262/#sec-array.prototype.findIndex var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; if (!Array.prototype.findIndex) { Object.defineProperty(Array.prototype, 'findIndex', { value: function value(predicate) { // 1. Let O be ? ToObject(this value). if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception. if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. var thisArg = arguments[1]; // 5. Let k be 0. var k = 0; // 6. Repeat, while k < len while (k < len) { // a. Let Pk be ! ToString(k). // b. Let kValue be ? Get(O, Pk). // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). // d. If testResult is true, return k. var kValue = o[k]; if (predicate.call(thisArg, kValue, k, o)) { return k; } // e. Increase k by 1. k++; } // 7. Return -1. return -1; } }); } // https://tc39.github.io/ecma262/#sec-array.prototype.find if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', { value: function value(predicate) { // 1. Let O be ? ToObject(this value). if (this == null) { throw new TypeError('"this" is null or not defined'); } var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception. if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. var thisArg = arguments[1]; // 5. Let k be 0. var k = 0; // 6. Repeat, while k < len while (k < len) { // a. Let Pk be ! ToString(k). // b. Let kValue be ? Get(O, Pk). // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). // d. If testResult is true, return kValue. var kValue = o[k]; if (predicate.call(thisArg, kValue, k, o)) { return kValue; } // e. Increase k by 1. k++; } // 7. Return undefined. return undefined; } }); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill if (!String.prototype.includes) { String.prototype.includes = function (search, start) { 'use strict'; if (search instanceof RegExp) { throw TypeError('first argument must not be a RegExp'); } if (start === undefined) { start = 0; } return this.indexOf(search, start) !== -1; }; } // https://tc39.github.io/ecma262/#sec-array.prototype.includes if (!Array.prototype.includes) { Object.defineProperty(Array.prototype, 'includes', { value: function value(searchElement, fromIndex) { if (this == null) { throw new TypeError('"this" is null or not defined'); } // 1. Let O be ? ToObject(this value). var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). var len = o.length >>> 0; // 3. If len is 0, return false. if (len === 0) { return false; } // 4. Let n be ? ToInteger(fromIndex). // (If fromIndex is undefined, this step produces the value 0.) var n = fromIndex | 0; // 5. If n ≥ 0, then // a. Let k be n. // 6. Else n < 0, // a. Let k be len + n. // b. If k < 0, let k be 0. var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); function sameValueZero(x, y) { return x === y || typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y); } // 7. Repeat, while k < len while (k < len) { // a. Let elementK be the result of ? Get(O, ! ToString(k)). // b. If SameValueZero(searchElement, elementK) is true, return true. if (sameValueZero(o[k], searchElement)) { return true; } // c. Increase k by 1. k++; } // 8. Return false return false; } }); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill if (typeof Object.assign !== 'function') { // Must be writable: true, enumerable: false, configurable: true Object.defineProperty(Object, "assign", { value: function assign(target, varArgs) { // .length of function is 2 'use strict'; if (target === null || target === undefined) { throw new TypeError('Cannot convert undefined or null to object'); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource !== null && nextSource !== undefined) { for (var nextKey in nextSource) { // Avoid bugs when hasOwnProperty is shadowed if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, writable: true, configurable: true }); } var ColumnManager = function ColumnManager(table) { this.table = table; //hold parent table this.blockHozScrollEvent = false; this.headersElement = this.createHeadersElement(); this.element = this.createHeaderElement(); //containing element this.rowManager = null; //hold row manager object this.columns = []; // column definition object this.columnsByIndex = []; //columns by index this.columnsByField = {}; //columns by field this.scrollLeft = 0; this.element.insertBefore(this.headersElement, this.element.firstChild); }; ////////////// Setup Functions ///////////////// ColumnManager.prototype.createHeadersElement = function () { var el = document.createElement("div"); el.classList.add("tabulator-headers"); return el; }; ColumnManager.prototype.createHeaderElement = function () { var el = document.createElement("div"); el.classList.add("tabulator-header"); if (!this.table.options.headerVisible) { el.classList.add("tabulator-header-hidden"); } return el; }; ColumnManager.prototype.initialize = function () { var self = this; //scroll body along with header // self.element.addEventListener("scroll", function(e){ // if(!self.blockHozScrollEvent){ // self.table.rowManager.scrollHorizontal(self.element.scrollLeft); // } // }); }; //link to row manager ColumnManager.prototype.setRowManager = function (manager) { this.rowManager = manager; }; //return containing element ColumnManager.prototype.getElement = function () { return this.element; }; //return header containing element ColumnManager.prototype.getHeadersElement = function () { return this.headersElement; }; // ColumnManager.prototype.tempScrollBlock = function(){ // clearTimeout(this.blockHozScrollEvent); // this.blockHozScrollEvent = setTimeout(() => {this.blockHozScrollEvent = false;}, 50); // } //scroll horizontally to match table body ColumnManager.prototype.scrollHorizontal = function (left) { var hozAdjust = 0, scrollWidth = this.element.scrollWidth - this.table.element.clientWidth; // this.tempScrollBlock(); this.element.scrollLeft = left; //adjust for vertical scrollbar moving table when present if (left > scrollWidth) { hozAdjust = left - scrollWidth; this.element.style.marginLeft = -hozAdjust + "px"; } else { this.element.style.marginLeft = 0; } //keep frozen columns fixed in position //this._calcFrozenColumnsPos(hozAdjust + 3); this.scrollLeft = left; if (this.table.modExists("frozenColumns")) { this.table.modules.frozenColumns.scrollHorizontal(); } }; ///////////// Column Setup Functions ///////////// ColumnManager.prototype.generateColumnsFromRowData = function (data) { var cols = [], definitions = this.table.options.autoColumnsDefinitions, row, sorter; if (data && data.length) { row = data[0]; for (var key in row) { var col = { field: key, title: key }; var value = row[key]; switch (typeof value === 'undefined' ? 'undefined' : _typeof(value)) { case "undefined": sorter = "string"; break; case "boolean": sorter = "boolean"; break; case "object": if (Array.isArray(value)) { sorter = "array"; } else { sorter = "string"; } break; default: if (!isNaN(value) && value !== "") { sorter = "number"; } else { if (value.match(/((^[0-9]+[a-z]+)|(^[a-z]+[0-9]+))+$/i)) { sorter = "alphanum"; } else { sorter = "string"; } } break; } col.sorter = sorter; cols.push(col); } if (definitions) { switch (typeof definitions === 'undefined' ? 'undefined' : _typeof(definitions)) { case "function": this.table.options.columns = definitions.call(this.table, cols); break; case "object": if (Array.isArray(definitions)) { cols.forEach(function (col) { var match = definitions.find(function (def) { return def.field === col.field; }); if (match) { Object.assign(col, match); } }); } else { cols.forEach(function (col) { if (definitions[col.field]) { Object.assign(col, definitions[col.field]); } }); } this.table.options.columns = cols; break; } } else { this.table.options.columns = cols; } this.setColumns(this.table.options.columns); } }; ColumnManager.prototype.setColumns = function (cols, row) { var self = this; while (self.headersElement.firstChild) { self.headersElement.removeChild(self.headersElement.firstChild); }self.columns = []; self.columnsByIndex = []; self.columnsByField = {}; //reset frozen columns if (self.table.modExists("frozenColumns")) { self.table.modules.frozenColumns.reset(); } cols.forEach(function (def, i) { self._addColumn(def); }); self._reIndexColumns(); if (self.table.options.responsiveLayout && self.table.modExists("responsiveLayout", true)) { self.table.modules.responsiveLayout.initialize(); } if (this.table.options.virtualDomHoz) { this.table.vdomHoz.reinitialize(false, true); } self.redraw(true); }; ColumnManager.prototype._addColumn = function (definition, before, nextToColumn) { var column = new Column(definition, this), colEl = column.getElement(), index = nextToColumn ? this.findColumnIndex(nextToColumn) : nextToColumn; if (nextToColumn && index > -1) { var parentIndex = this.columns.indexOf(nextToColumn.getTopColumn()); var nextEl = nextToColumn.getElement(); if (before) { this.columns.splice(parentIndex, 0, column); nextEl.parentNode.insertBefore(colEl, nextEl); } else { this.columns.splice(parentIndex + 1, 0, column); nextEl.parentNode.insertBefore(colEl, nextEl.nextSibling); } } else { if (before) { this.columns.unshift(column); this.headersElement.insertBefore(column.getElement(), this.headersElement.firstChild); } else { this.columns.push(column); this.headersElement.appendChild(column.getElement()); } column.columnRendered(); } return column; }; ColumnManager.prototype.registerColumnField = function (col) { if (col.definition.field) { this.columnsByField[col.definition.field] = col; } }; ColumnManager.prototype.registerColumnPosition = function (col) { this.columnsByIndex.push(col); }; ColumnManager.prototype._reIndexColumns = function () { this.columnsByIndex = []; this.columns.forEach(function (column) { column.reRegisterPosition(); }); }; //ensure column headers take up the correct amount of space in column groups ColumnManager.prototype._verticalAlignHeaders = function () { var self = this, minHeight = 0; self.columns.forEach(function (column) { var height; column.clearVerticalAlign(); height = column.getHeight(); if (height > minHeight) { minHeight = height; } }); self.columns.forEach(function (column) { column.verticalAlign(self.table.options.columnHeaderVertAlign, minHeight); }); self.rowManager.adjustTableSize(); }; //////////////// Column Details ///////////////// ColumnManager.prototype.findColumn = function (subject) { var self = this; if ((typeof subject === 'undefined' ? 'undefined' : _typeof(subject)) == "object") { if (subject instanceof Column) { //subject is column element return subject; } else if (subject instanceof ColumnComponent) { //subject is public column component return subject._getSelf() || false; } else if (typeof HTMLElement !== "undefined" && subject instanceof HTMLElement) { //subject is a HTML element of the column header var match = self.columns.find(function (column) { return column.element === subject; }); return match || false; } } else { //subject should be treated as the field name of the column return this.columnsByField[subject] || false; } //catch all for any other type of input return false; }; ColumnManager.prototype.getColumnByField = function (field) { return this.columnsByField[field]; }; ColumnManager.prototype.getColumnsByFieldRoot = function (root) { var _this = this; var matches = []; Object.keys(this.columnsByField).forEach(function (field) { var fieldRoot = field.split(".")[0]; if (fieldRoot === root) { matches.push(_this.columnsByField[field]); } }); return matches; }; ColumnManager.prototype.getColumnByIndex = function (index) { return this.columnsByIndex[index]; }; ColumnManager.prototype.getFirstVisibileColumn = function (index) { var index = this.columnsByIndex.findIndex(function (col) { return col.visible; }); return index > -1 ? this.columnsByIndex[index] : false; }; ColumnManager.prototype.getColumns = function () { return this.columns; }; ColumnManager.prototype.findColumnIndex = function (column) { return this.columnsByIndex.findIndex(function (col) { return column === col; }); }; //return all columns that are not groups ColumnManager.prototype.getRealColumns = function () { return this.columnsByIndex; }; //travers across columns and call action ColumnManager.prototype.traverse = function (callback) { var self = this; self.columnsByIndex.forEach(function (column, i) { callback(column, i); }); }; //get defintions of actual columns ColumnManager.prototype.getDefinitions = function (active) { var self = this, output = []; self.columnsByIndex.forEach(function (column) { if (!active || active && column.visible) { output.push(column.getDefinition()); } }); return output; }; //get full nested definition tree ColumnManager.prototype.getDefinitionTree = function () { var self = this, output = []; self.columns.forEach(function (column) { output.push(column.getDefinition(true)); }); return output; }; ColumnManager.prototype.getComponents = function (structured) { var self = this, output = [], columns = structured ? self.columns : self.columnsByIndex; columns.forEach(function (column) { output.push(column.getComponent()); }); return output; }; ColumnManager.prototype.getWidth = function () { var width = 0; this.columnsByIndex.forEach(function (column) { if (column.visible) { width += column.getWidth(); } }); return width; }; ColumnManager.prototype.moveColumn = function (from, to, after) { this.moveColumnActual(from, to, after); if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { this.table.modules.responsiveLayout.initialize(); } if (this.table.modExists("columnCalcs")) { this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows); } to.element.parentNode.insertBefore(from.element, to.element); if (after) { to.element.parentNode.insertBefore(to.element, from.element); } this._verticalAlignHeaders(); this.table.rowManager.reinitialize(); }; ColumnManager.prototype.moveColumnActual = function (from, to, after) { if (from.parent.isGroup) { this._moveColumnInArray(from.parent.columns, from, to, after); } else { this._moveColumnInArray(this.columns, from, to, after); } this._moveColumnInArray(this.columnsByIndex, from, to, after, true); if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { this.table.modules.responsiveLayout.initialize(); } if (this.table.options.virtualDomHoz) { this.table.vdomHoz.reinitialize(true); } if (this.table.options.columnMoved) { this.table.options.columnMoved.call(this.table, from.getComponent(), this.table.columnManager.getComponents()); } if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) { this.table.modules.persistence.save("columns"); } }; ColumnManager.prototype._moveColumnInArray = function (columns, from, to, after, updateRows) { var _this2 = this; var fromIndex = columns.indexOf(from), toIndex, rows = []; if (fromIndex > -1) { columns.splice(fromIndex, 1); toIndex = columns.indexOf(to); if (toIndex > -1) { if (after) { toIndex = toIndex + 1; } } else { toIndex = fromIndex; } columns.splice(toIndex, 0, from); if (updateRows) { if (this.table.options.dataTree && this.table.modExists("dataTree", true)) { this.table.rowManager.rows.forEach(function (row) { rows = rows.concat(_this2.table.modules.dataTree.getTreeChildren(row, false, true)); }); } rows = rows.concat(this.table.rowManager.rows); rows.forEach(function (row) { if (row.cells.length) { var cell = row.cells.splice(fromIndex, 1)[0]; row.cells.splice(toIndex, 0, cell); } }); } } }; ColumnManager.prototype.scrollToColumn = function (column, position, ifVisible) { var _this3 = this; var left = 0, offset = 0, adjust = 0, colEl = column.getElement(); return new Promise(function (resolve, reject) { if (typeof position === "undefined") { position = _this3.table.options.scrollToColumnPosition; } if (typeof ifVisible === "undefined") { ifVisible = _this3.table.options.scrollToColumnIfVisible; } if (column.visible) { //align to correct position switch (position) { case "middle": case "center": adjust = -_this3.element.clientWidth / 2; break; case "right": adjust = colEl.clientWidth - _this3.headersElement.clientWidth; break; } //check column visibility if (!ifVisible) { offset = colEl.offsetLeft; if (offset > 0 && offset + colEl.offsetWidth < _this3.element.clientWidth) { return false; } } //calculate scroll position left = colEl.offsetLeft + adjust; left = Math.max(Math.min(left, _this3.table.rowManager.element.scrollWidth - _this3.table.rowManager.element.clientWidth), 0); _this3.table.rowManager.scrollHorizontal(left); _this3.scrollHorizontal(left); resolve(); } else { console.warn("Scroll Error - Column not visible"); reject("Scroll Error - Column not visible"); } }); }; //////////////// Cell Management ///////////////// ColumnManager.prototype.generateCells = function (row) { var self = this; var cells = []; self.columnsByIndex.forEach(function (column) { cells.push(column.generateCell(row)); }); return cells; }; //////////////// Column Management ///////////////// ColumnManager.prototype.getFlexBaseWidth = function () { var self = this, totalWidth = self.table.element.clientWidth, //table element width fixedWidth = 0; //adjust for vertical scrollbar if present if (self.rowManager.element.scrollHeight > self.rowManager.element.clientHeight) { totalWidth -= self.rowManager.element.offsetWidth - self.rowManager.element.clientWidth; } this.columnsByIndex.forEach(function (column) { var width, minWidth, colWidth; if (column.visible) { width = column.definition.width || 0; minWidth = typeof column.minWidth == "undefined" ? self.table.options.columnMinWidth : parseInt(column.minWidth); if (typeof width == "string") { if (width.indexOf("%") > -1) { colWidth = totalWidth / 100 * parseInt(width); } else { colWidth = parseInt(width); } } else { colWidth = width; } fixedWidth += colWidth > minWidth ? colWidth : minWidth; } }); return fixedWidth; }; ColumnManager.prototype.addColumn = function (definition, before, nextToColumn) { var _this4 = this; return new Promise(function (resolve, reject) { var column = _this4._addColumn(definition, before, nextToColumn); _this4._reIndexColumns(); if (_this4.table.options.responsiveLayout && _this4.table.modExists("responsiveLayout", true)) { _this4.table.modules.responsiveLayout.initialize(); } if (_this4.table.modExists("columnCalcs")) { _this4.table.modules.columnCalcs.recalc(_this4.table.rowManager.activeRows); } _this4.redraw(true); if (_this4.table.modules.layout.getMode() != "fitColumns") { column.reinitializeWidth(); } _this4._verticalAlignHeaders(); _this4.table.rowManager.reinitialize(); if (_this4.table.options.virtualDomHoz) { _this4.table.vdomHoz.reinitialize(); } resolve(column); }); }; //remove column from system ColumnManager.prototype.deregisterColumn = function (column) { var field = column.getField(), index; //remove from field list if (field) { delete this.columnsByField[field]; } //remove from index list index = this.columnsByIndex.indexOf(column); if (index > -1) { this.columnsByIndex.splice(index, 1); } //remove from column list index = this.columns.indexOf(column); if (index > -1) { this.columns.splice(index, 1); } if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { this.table.modules.responsiveLayout.initialize(); } this._verticalAlignHeaders(); this.redraw(); }; //redraw columns ColumnManager.prototype.redraw = function (force) { if (force) { if (Tabulator.prototype.helpers.elVisible(this.element)) { this._verticalAlignHeaders(); } this.table.rowManager.resetScroll(); this.table.rowManager.reinitialize(); } if (["fitColumns", "fitDataStretch"].indexOf(this.table.modules.layout.getMode()) > -1) { this.table.modules.layout.layout(); } else { if (force) { this.table.modules.layout.layout(); } else { if (this.table.options.responsiveLayout && this.table.modExists("responsiveLayout", true)) { this.table.modules.responsiveLayout.update(); } } } if (this.table.modExists("frozenColumns")) { this.table.modules.frozenColumns.layout(); } if (this.table.modExists("columnCalcs")) { this.table.modules.columnCalcs.recalc(this.table.rowManager.activeRows); } if (force) { if (this.table.options.persistence && this.table.modExists("persistence", true) && this.table.modules.persistence.config.columns) { this.table.modules.persistence.save("columns"); } if (this.table.modExists("columnCalcs")) { this.table.modules.columnCalcs.redraw(); } } this.table.footerManager.redraw(); }; //public column object var ColumnComponent = function ColumnComponent(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 Column(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 () { var _this5 = this; Object.keys(this.definition).forEach(function (key) { if (_this5.defaultOptionList.indexOf(key) === -1) { console.warn("Invalid column definition option in '" + (_this5.field || _this5.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 _this6 = this; 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(function (className) { _this6.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 _this7 = this; var formatter, contents, params, mockCell, onRendered; if (this.definition.titleFormatter && this.table.modExists("format")) { formatter = this.table.modules.format.getFormatter(this.definition.titleFormatter); onRendered = function onRendered(callback) { _this7.titleFormatterRendered = callback; }; mockCell = { getValue: function getValue() { return title; }, getElement: function getElement() { 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 === 'undefined' ? 'undefined' : _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 () { var _this8 = this; 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(function (className) { _this8.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 (var _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 (var _i2 = 0; _i2 < length; _i2++) { if (_i2 == length - 1) { dataObj[structure[_i2]] = value; } else { if (!dataObj[structure[_i2]]) { if (typeof value !== "undefined") { dataObj[structure[_i2]] = {}; } else { break; } } dataObj = dataObj[structure[_i2]]; } } }; //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) {