tabulator-tables
Version:
Interactive table generation JavaScript library
515 lines (398 loc) • 13.7 kB
JavaScript
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; };
/* Tabulator v4.9.3 (c) Oliver Folkerd */
var DataTree = function DataTree(table) {
this.table = table;
this.indent = 10;
this.field = "";
this.collapseEl = null;
this.expandEl = null;
this.branchEl = null;
this.elementField = false;
this.startOpen = function () {};
this.displayIndex = 0;
};
DataTree.prototype.initialize = function () {
var dummyEl = null,
firstCol = this.table.columnManager.getFirstVisibileColumn(),
options = this.table.options;
this.field = options.dataTreeChildField;
this.indent = options.dataTreeChildIndent;
this.elementField = options.dataTreeElementColumn || (firstCol ? firstCol.field : false);
if (options.dataTreeBranchElement) {
if (options.dataTreeBranchElement === true) {
this.branchEl = document.createElement("div");
this.branchEl.classList.add("tabulator-data-tree-branch");
} else {
if (typeof options.dataTreeBranchElement === "string") {
dummyEl = document.createElement("div");
dummyEl.innerHTML = options.dataTreeBranchElement;
this.branchEl = dummyEl.firstChild;
} else {
this.branchEl = options.dataTreeBranchElement;
}
}
}
if (options.dataTreeCollapseElement) {
if (typeof options.dataTreeCollapseElement === "string") {
dummyEl = document.createElement("div");
dummyEl.innerHTML = options.dataTreeCollapseElement;
this.collapseEl = dummyEl.firstChild;
} else {
this.collapseEl = options.dataTreeCollapseElement;
}
} else {
this.collapseEl = document.createElement("div");
this.collapseEl.classList.add("tabulator-data-tree-control");
this.collapseEl.tabIndex = 0;
this.collapseEl.innerHTML = "<div class='tabulator-data-tree-control-collapse'></div>";
}
if (options.dataTreeExpandElement) {
if (typeof options.dataTreeExpandElement === "string") {
dummyEl = document.createElement("div");
dummyEl.innerHTML = options.dataTreeExpandElement;
this.expandEl = dummyEl.firstChild;
} else {
this.expandEl = options.dataTreeExpandElement;
}
} else {
this.expandEl = document.createElement("div");
this.expandEl.classList.add("tabulator-data-tree-control");
this.expandEl.tabIndex = 0;
this.expandEl.innerHTML = "<div class='tabulator-data-tree-control-expand'></div>";
}
switch (_typeof(options.dataTreeStartExpanded)) {
case "boolean":
this.startOpen = function (row, index) {
return options.dataTreeStartExpanded;
};
break;
case "function":
this.startOpen = options.dataTreeStartExpanded;
break;
default:
this.startOpen = function (row, index) {
return options.dataTreeStartExpanded[index];
};
break;
}
};
DataTree.prototype.initializeRow = function (row) {
var childArray = row.getData()[this.field];
var isArray = Array.isArray(childArray);
var children = isArray || !isArray && (typeof childArray === "undefined" ? "undefined" : _typeof(childArray)) === "object" && childArray !== null;
if (!children && row.modules.dataTree && row.modules.dataTree.branchEl) {
row.modules.dataTree.branchEl.parentNode.removeChild(row.modules.dataTree.branchEl);
}
if (!children && row.modules.dataTree && row.modules.dataTree.controlEl) {
row.modules.dataTree.controlEl.parentNode.removeChild(row.modules.dataTree.controlEl);
}
row.modules.dataTree = {
index: row.modules.dataTree ? row.modules.dataTree.index : 0,
open: children ? row.modules.dataTree ? row.modules.dataTree.open : this.startOpen(row.getComponent(), 0) : false,
controlEl: row.modules.dataTree && children ? row.modules.dataTree.controlEl : false,
branchEl: row.modules.dataTree && children ? row.modules.dataTree.branchEl : false,
parent: row.modules.dataTree ? row.modules.dataTree.parent : false,
children: children
};
};
DataTree.prototype.layoutRow = function (row) {
var cell = this.elementField ? row.getCell(this.elementField) : row.getCells()[0],
el = cell.getElement(),
config = row.modules.dataTree;
if (config.branchEl) {
if (config.branchEl.parentNode) {
config.branchEl.parentNode.removeChild(config.branchEl);
}
config.branchEl = false;
}
if (config.controlEl) {
if (config.controlEl.parentNode) {
config.controlEl.parentNode.removeChild(config.controlEl);
}
config.controlEl = false;
}
this.generateControlElement(row, el);
row.getElement().classList.add("tabulator-tree-level-" + config.index);
if (config.index) {
if (this.branchEl) {
config.branchEl = this.branchEl.cloneNode(true);
el.insertBefore(config.branchEl, el.firstChild);
if (this.table.rtl) {
config.branchEl.style.marginRight = (config.branchEl.offsetWidth + config.branchEl.style.marginLeft) * (config.index - 1) + config.index * this.indent + "px";
} else {
config.branchEl.style.marginLeft = (config.branchEl.offsetWidth + config.branchEl.style.marginRight) * (config.index - 1) + config.index * this.indent + "px";
}
} else {
if (this.table.rtl) {
el.style.paddingRight = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-right')) + config.index * this.indent + "px";
} else {
el.style.paddingLeft = parseInt(window.getComputedStyle(el, null).getPropertyValue('padding-left')) + config.index * this.indent + "px";
}
}
}
};
DataTree.prototype.generateControlElement = function (row, el) {
var _this = this;
var config = row.modules.dataTree,
el = el || row.getCells()[0].getElement(),
oldControl = config.controlEl;
if (config.children !== false) {
if (config.open) {
config.controlEl = this.collapseEl.cloneNode(true);
config.controlEl.addEventListener("click", function (e) {
e.stopPropagation();
_this.collapseRow(row);
});
} else {
config.controlEl = this.expandEl.cloneNode(true);
config.controlEl.addEventListener("click", function (e) {
e.stopPropagation();
_this.expandRow(row);
});
}
config.controlEl.addEventListener("mousedown", function (e) {
e.stopPropagation();
});
if (oldControl && oldControl.parentNode === el) {
oldControl.parentNode.replaceChild(config.controlEl, oldControl);
} else {
el.insertBefore(config.controlEl, el.firstChild);
}
}
};
DataTree.prototype.setDisplayIndex = function (index) {
this.displayIndex = index;
};
DataTree.prototype.getDisplayIndex = function () {
return this.displayIndex;
};
DataTree.prototype.getRows = function (rows) {
var _this2 = this;
var output = [];
rows.forEach(function (row, i) {
var config, children;
output.push(row);
if (row instanceof Row) {
row.create();
config = row.modules.dataTree.children;
if (!config.index && config.children !== false) {
children = _this2.getChildren(row);
children.forEach(function (child) {
child.create();
output.push(child);
});
}
}
});
return output;
};
DataTree.prototype.getChildren = function (row, allChildren) {
var _this3 = this;
var config = row.modules.dataTree,
children = [],
output = [];
if (config.children !== false && (config.open || allChildren)) {
if (!Array.isArray(config.children)) {
config.children = this.generateChildren(row);
}
if (this.table.modExists("filter") && this.table.options.dataTreeFilter) {
children = this.table.modules.filter.filter(config.children);
} else {
children = config.children;
}
if (this.table.modExists("sort") && this.table.options.dataTreeSort) {
this.table.modules.sort.sort(children);
}
children.forEach(function (child) {
output.push(child);
var subChildren = _this3.getChildren(child);
subChildren.forEach(function (sub) {
output.push(sub);
});
});
}
return output;
};
DataTree.prototype.generateChildren = function (row) {
var _this4 = this;
var children = [];
var childArray = row.getData()[this.field];
if (!Array.isArray(childArray)) {
childArray = [childArray];
}
childArray.forEach(function (childData) {
var childRow = new Row(childData || {}, _this4.table.rowManager);
childRow.create();
childRow.modules.dataTree.index = row.modules.dataTree.index + 1;
childRow.modules.dataTree.parent = row;
if (childRow.modules.dataTree.children) {
childRow.modules.dataTree.open = _this4.startOpen(childRow.getComponent(), childRow.modules.dataTree.index);
}
children.push(childRow);
});
return children;
};
DataTree.prototype.expandRow = function (row, silent) {
var config = row.modules.dataTree;
if (config.children !== false) {
config.open = true;
row.reinitialize();
this.table.rowManager.refreshActiveData("tree", false, true);
this.table.options.dataTreeRowExpanded(row.getComponent(), row.modules.dataTree.index);
}
};
DataTree.prototype.collapseRow = function (row) {
var config = row.modules.dataTree;
if (config.children !== false) {
config.open = false;
row.reinitialize();
this.table.rowManager.refreshActiveData("tree", false, true);
this.table.options.dataTreeRowCollapsed(row.getComponent(), row.modules.dataTree.index);
}
};
DataTree.prototype.toggleRow = function (row) {
var config = row.modules.dataTree;
if (config.children !== false) {
if (config.open) {
this.collapseRow(row);
} else {
this.expandRow(row);
}
}
};
DataTree.prototype.getTreeParent = function (row) {
return row.modules.dataTree.parent ? row.modules.dataTree.parent.getComponent() : false;
};
DataTree.prototype.getFilteredTreeChildren = function (row) {
var config = row.modules.dataTree,
output = [],
children;
if (config.children) {
if (!Array.isArray(config.children)) {
config.children = this.generateChildren(row);
}
if (this.table.modExists("filter") && this.table.options.dataTreeFilter) {
children = this.table.modules.filter.filter(config.children);
} else {
children = config.children;
}
children.forEach(function (childRow) {
if (childRow instanceof Row) {
output.push(childRow);
}
});
}
return output;
};
DataTree.prototype.rowDelete = function (row) {
var parent = row.modules.dataTree.parent,
childIndex;
if (parent) {
childIndex = this.findChildIndex(row, parent);
if (childIndex !== false) {
parent.data[this.field].splice(childIndex, 1);
}
if (!parent.data[this.field].length) {
delete parent.data[this.field];
}
this.initializeRow(parent);
this.layoutRow(parent);
}
this.table.rowManager.refreshActiveData("tree", false, true);
};
DataTree.prototype.addTreeChildRow = function (row, data, top, index) {
var childIndex = false;
if (typeof data === "string") {
data = JSON.parse(data);
}
if (!Array.isArray(row.data[this.field])) {
row.data[this.field] = [];
row.modules.dataTree.open = this.startOpen(row.getComponent(), row.modules.dataTree.index);
}
if (typeof index !== "undefined") {
childIndex = this.findChildIndex(index, row);
if (childIndex !== false) {
row.data[this.field].splice(top ? childIndex : childIndex + 1, 0, data);
}
}
if (childIndex === false) {
if (top) {
row.data[this.field].unshift(data);
} else {
row.data[this.field].push(data);
}
}
this.initializeRow(row);
this.layoutRow(row);
this.table.rowManager.refreshActiveData("tree", false, true);
};
DataTree.prototype.findChildIndex = function (subject, parent) {
var _this5 = this;
var match = false;
if ((typeof subject === "undefined" ? "undefined" : _typeof(subject)) == "object") {
if (subject instanceof Row) {
//subject is row element
match = subject.data;
} else if (subject instanceof RowComponent) {
//subject is public row component
match = subject._getSelf().data;
} else if (typeof HTMLElement !== "undefined" && subject instanceof HTMLElement) {
if (parent.modules.dataTree) {
match = parent.modules.dataTree.children.find(function (childRow) {
return childRow instanceof Row ? childRow.element === subject : false;
});
if (match) {
match = match.data;
}
}
}
} else if (typeof subject == "undefined" || subject === null) {
match = false;
} else {
//subject should be treated as the index of the row
match = parent.data[this.field].find(function (row) {
return row.data[_this5.table.options.index] == subject;
});
}
if (match) {
if (Array.isArray(parent.data[this.field])) {
match = parent.data[this.field].indexOf(match);
}
if (match == -1) {
match = false;
}
}
//catch all for any other type of input
return match;
};
DataTree.prototype.getTreeChildren = function (row, component, recurse) {
var _this6 = this;
var config = row.modules.dataTree,
output = [];
if (config.children) {
if (!Array.isArray(config.children)) {
config.children = this.generateChildren(row);
}
config.children.forEach(function (childRow) {
if (childRow instanceof Row) {
output.push(component ? childRow.getComponent() : childRow);
if (recurse) {
output = output.concat(_this6.getTreeChildren(childRow, component, recurse));
}
}
});
}
return output;
};
DataTree.prototype.checkForRestyle = function (cell) {
if (!cell.row.cells.indexOf(cell)) {
cell.row.reinitialize();
}
};
DataTree.prototype.getChildField = function () {
return this.field;
};
DataTree.prototype.redrawNeeded = function (data) {
return (this.field ? typeof data[this.field] !== "undefined" : false) || (this.elementField ? typeof data[this.elementField] !== "undefined" : false);
};
Tabulator.prototype.registerModule("dataTree", DataTree);