bbtreeview/src/bbtreeviewnode.js

416 lines
7.8 KiB
JavaScript

class BBTreeviewNode {
constructor(treeview) {
this.Treeview = treeview;
this.ID = null;
this.Node = null;
this.Container = null;
this.Label = null;
this.Value = null;
this.Name = "";
this.Hint = "";
this.ParentID = null;
this.IsChecked = false;
this.Highlighted = false;
this.Tag = null;
this.initialiseComponents();
}
initialiseComponents() {
const a = this;
}
get IsChecked() {
const a = this;
if (!a.Treeview.Options.ShowCheckbox) {
return false;
}
return a.Node.classList.contains("x");
}
set IsChecked(value) {
const a = this;
a.setCheckbox(a.Node, value);
// Update children
a.Node.querySelectorAll("li").forEach(function(e) {
a.setCheckbox(e, value);
});
// Update parent state
let parentNode = a.ParentNode;
if (parentNode == null) {
return;
}
// Handle pull-ups
if (a.Treeview.Options.EnablePullUp) {
while (true) {
const parentChecked = (parentNode.querySelectorAll("li.x").length > 0);
a.setCheckbox(parentNode, parentChecked);
parentNode = a.Treeview.getNode(parentNode);
parentNode = parentNode.ParentNode;
if (parentNode == null) {
break;
}
}
} else {
let uncheckedCount = 0;
parentNode.querySelectorAll("li").forEach(function(e) {
if (e.classList.contains("x")) {
return;
}
uncheckedCount++;
});
a.setCheckbox(parentNode, (uncheckedCount <= 0));
}
}
get IsExpanded() {
const a = this;
if (a.Node.classList.contains("e")) {
return true;
}
if (a.Node.classList.contains("c")) {
return false;
}
return null;
}
get IsHighlighted() {
const a = this;
return (a.Container.classList.contains("highlighted"));
}
get Tag() {
const a = this;
let tag = a.Node.getAttribute("data-bbtv-tag");
if (a.Treeview.isNullOrWhitespace(tag)) {
return null;
}
return JSON.parse(decodeURIComponent(tag));
}
get ParentNodeID() {
const a = this;
const parentNode = a.ParentNode;
if (parentNode == null) {
return null;
}
return parentNode.getAttribute("data-bbtv-id");
}
get ParentNode() {
const a = this;
return a.parentsUntilTagName(a.Node, "li");
}
Load(node) {
const a = this;
a.ID = node.getAttribute("data-bbtv-id");
a.Node = node;
a.Container = node.querySelectorAll("div.li")[0];
a.Label = node.querySelectorAll("span")[0];
a.Value = node.getAttribute("data-bbtv-value");
a.Name = a.Label.textContent;
a.Hint = a.Label.getAttribute("title");
a.ParentID = a.ParentNodeID;
a.IsChecked = a.IsChecked;
a.Highlighted = a.IsHighlighted;
a.Tag = a.Tag;
a.initialiseComponents_Events();
}
Collapse() {
const a = this;
if (a.Node.classList.contains("e")) {
a.Node.classList.remove("e");
a.Node.classList.add("c");
}
a.GetChildNodes().forEach(function(e) {
e.classList.add("hidden");
});
}
Expand() {
const a = this;
if (a.Node.classList.contains("c")) {
a.Node.classList.remove("c");
a.Node.classList.add("e");
}
a.GetChildNodes().forEach(function(e) {
e.classList.remove("hidden");
});
}
GetCheckbox() {
const a = this;
if (!a.Treeview.Options.ShowCheckbox) {
return null;
}
const checkboxes = a.Node.querySelectorAll("div.icon.checkbox");
if (typeof(checkboxes) == "undefined") {
return null;
}
return checkboxes[0];
}
GetChildNode() {
const a = this;
let result = a.Node.querySelectorAll("ul");
if (result.length <= 0) {
return null;
}
return result[0];
}
GetChildNodes() {
const a = this;
const childNode = a.GetChildNode();
if (childNode == null) {
return [];
}
let nodes = childNode.querySelectorAll("li");
if (nodes.length <= 0) {
return [];
}
let result = [];
nodes.forEach(function(e) {
if (typeof(e.parentNode) == "undefined") {
return;
}
if (e.parentNode != childNode) {
return;
}
result.push(e);
});
return result;
}
Remove() {
const a = this;
if (a.ParentNode != null) {
if (a.ParentNode.classList.contains("e")) {
a.ParentNode.classList.remove("e");
}
if (a.ParentNode.classList.contains("c")) {
a.ParentNode.classList.remove("c");
}
}
a.Node.parentNode.removeChild(a.Node);
}
Toggle() {
const a = this;
switch (a.IsExpanded) {
case true:
a.Collapse();
break;
case false:
a.Expand();
break;
default: break;
}
}
initialiseComponents_Events() {
const a = this;
// collapsible icon behaviour
a.Node.addEventListener("click", function(e){
e.stopPropagation();
e.preventDefault();
if (!a.isTag(e.target, "li")) {
return;
}
if ((e.offsetX < 0) || (e.offsetX > 16) || (e.offsetY < 0) || (e.offsetY > 16)) {
return;
}
const myNode = a.Treeview.getNode(e.target);
if (myNode == null) {
return;
}
myNode.Toggle();
});
// collapsible label behaviour
a.Container.addEventListener("dblclick", function(e){
e.stopPropagation();
e.preventDefault();
const myNode = a.Treeview.getNode(e.target);
if (myNode == null) {
return;
}
myNode.Toggle();
});
// checkbox behaviour
if (a.Treeview.Options.ShowCheckbox) {
a.GetCheckbox().addEventListener("mousedown", function(e){
e.stopPropagation();
e.preventDefault();
a.IsChecked = !a.IsChecked;
});
a.GetCheckbox().addEventListener("click", function(e){
e.stopPropagation();
e.preventDefault();
// do nothing
});
a.GetCheckbox().addEventListener("dblclick", function(e){
e.stopPropagation();
e.preventDefault();
// do nothing
});
}
// highlighting
a.Container.addEventListener("mousedown", function(e){
e.stopPropagation();
e.preventDefault();
const myNode = a.Treeview.getNode(e.target);
if (myNode == null) {
return;
}
a.Treeview.Container.querySelectorAll("div.highlighted").forEach(function(e) {
e.classList.remove("highlighted");
});
// Don't show selection
if (!a.Treeview.Options.ShowSelection) {
return;
}
myNode.Container.classList.add("highlighted");
});
a.invalidateCollapsible();
}
invalidateCollapsible() {
const a = this;
// Invalidate state
if (a.ParentNode == null) {
return;
}
if (a.ParentNode.classList.contains("c")) {
a.Node.classList.add("hidden");
} else if (a.ParentNode.classList.contains("e")) {
a.Node.classList.remove("hidden");
} else {
a.ParentNode.classList.add("e");
a.Node.classList.remove("hidden");
}
}
isTag(el, tagName) {
return (el.tagName.toLowerCase() == tagName);
}
parentsUntilTagName(el, tagName) {
const a = this;
let node = el;
while (true) {
if (typeof(node.parentNode) == "undefined") {
break;
}
node = node.parentNode;
if (typeof(node) == "undefined") {
break;
}
if (a.isTag(node, "ul")) {
if (node.classList.contains("bbtreeview")) {
return null;
}
}
if (a.isTag(node, tagName)) {
break;
}
}
return node;
}
setCheckbox(el, value) {
if (value) {
if (!el.classList.contains("x")) {
el.classList.add("x");
}
} else {
if (el.classList.contains("x")) {
el.classList.remove("x");
}
}
}
}