tabulator-tables
Version:
Interactive table generation JavaScript library
2,253 lines (1,514 loc) • 602 kB
JavaScript
/* 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 || " ";
});
} else {
titleElement.value = def.title || " ";
}
} else {
if (def.field) {
table.modules.localize.bind("columns|" + def.field, function (text) {
self._formatColumnHeaderTitle(titleHolderElement, text || def.title || " ");
});
} else {
self._formatColumnHeaderTitle(titleHolderElement, def.title || " ");
}
}
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) {