Not having found any way to do that in the Tabulator documentation/examples, I have searched for a while how to do this very basic thing.
I have seen this answer but it relies on JQuery that I don't know and I cannot use in my limited environment (plus, it does not seem to be resolving the misplaced TREE branches and [+]/[-] TREE buttons).
Below is my (malfunctioning) pure-JS code that I would like to see performing correctly: it just prunes a "NEW" item when you click an existing TREE item (but the TREE attachments, indentation and [+]/[-] buttons go nuts).
As far as I can tell, the result displayed by alert()
is correct.
Could that be a Tabulator library bug?
<!DOCTYPE html>
<html lang="en">
<head><title>Tree</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://unpkg.com/[email protected]/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/[email protected]/dist/js/tabulator.min.js"></script>
<style>
body{margin:1.5%}
#treediv{width:300px;height:250px;font-size:1.6em;background:#777};
</style>
<script type="text/javascript">
function $def(variable) {return(typeof variable !== 'undefined')}
var count = 0; // item #
window.onload=function()
{
var treedata =
[ {name:"Bob"}, {name:"Tom"},
{name:"Jane", _children:[{name:"Eric"}]},
{name:"John", _children:[{name:"Lin", _children:[{name:"Eva"}]}]}
];
var tree = new Tabulator("#tree",
{ height:"250px", layout:"fitColumns", headerVisible:false,
data:treedata, dataTree:true, dataTreeChildIndent:25,
dataTreeStartExpanded:true, selectable:1,
columns: [ {field:'name'} ],
rowClick:function(e, row)
{
var children = row.getData()["_children"];
var nbr = $def(children) ? children.length : 0;
count++;
row.select();
var selectedRows = tree.getSelectedRows();
var root = selectedRows[0].getTreeParent();
if(root)
{ var r = root; parents = 1;
while(r){r = r.getTreeParent(); if(r){root = r}}
} else root = selectedRows[0];
if(!nbr) // easy case, define _children[]
{
row.update({_children:[{name:"pNEW" + count}]});
alert(JSON.stringify(root.getData()));
}
else // _children[] already exists, add NEW ITEM
{
children.push({name:"cNEW" + count});
row.update({_children:children});
alert(JSON.stringify(root.getData()));
}
},
});
}
</script>
</head><body>
<div id="treediv"> <div id="tree"></div> </div>
</body></html>
Since the JSON array is correctly updated - but badly rendered, the (uggly) workaround is just to add the following line of code at the end of rowClick:function(e, row){}
:
rowClick:function(e, row){
...
tree.setData(tree.getData()); // make tree use new JSON array
}
Someone has then suggested a (potentially) better API call:
rowClick:function(e, row){
...
tree.redraw(true); // make tree use new JSON array
}
Yet, it does not resolve the problem at all: tree.redraw()
is buggy and might be the source of the problem in the first place.
With my workaround, the Tabulator library is correctly rendering the TREE (proof that our point-and-click code was working and that this is a Tabulator bug).
This can safely be used as a FUTURE-SAFE WORKAROUND (that is, if your TREE is not too large and slowing-down the forced refresh...) until the Tabulator library is fixed.