Reputation: 1
I am using this plugin for showing a tree.
Does it have any functionality which will check all child nodes when parent node is checked?
Currently I can't find any way to do this.
To achieve this functionality I have written recursive function to find each node under root and check using checkNode
function.
I see a performance issue when depth of the tree is more than 3 for around 150 nodes. On investigation I found checkNode
function in bootstrap-treeview.js
uses render
each time node is checked, can anyone tell me the use of this render
function?
Can we remove use of render
?
Upvotes: 0
Views: 1313
Reputation: 637
Try this.
Edit bootstrap treeview js files.
find toggleCheckedState function and replace with below
Tree.prototype.toggleCheckedState = function (node, options) {
if (!node) return;
this.setCheckedState(node, !node.state.checked, options);
if (node.nodes && !options.ignoreChildren) {
$.each(node.nodes, $.proxy(function (index, node1) {
this.toggleCheckedState(node1,_default.options);
}, this));
}
};
Upvotes: 0
Reputation: 1
I was struggling with performance using a recursive solution as well, but I found a more efficient alternative. The call to checkAll
is fast, even with large trees, because it only makes a single call to render
, while a recursive implementation of this checking using checkNode
will call render
many times unnecessarily, as you pointed out.
I couldn't find this in the documentation, but I noticed that checkNode
calls forEachIdentifier
in its implementation, the same as checkAll
, so you can actually pass in an array of nodes or nodeIds, instead of just a single nodeId, and it will only call render
only once, after all the nodes are checked. The only difference for checkAll
is that it specifically passes in all the nodeIds in the tree.
So you can just add some code in your event handler to generate the list of nodeIds for all nodes underneath the parent, by looking at the id of the last child node and building a range, then call checkNode
once.
function onNodeChecked(event, node_data) {
var first_index, last_index, last_node, nodes, range, i;
nodes = node_data.nodes;
if (nodes != null) {
first_index = node_data.nodeId;
last_node = nodes[nodes.length - 1];
while (last_node.nodes != null) {
nodes = last_node.nodes;
last_node = nodes[nodes.length - 1];
}
last_index = last_node.nodeId;
range = [];
for (i = first_index; i <= last_index ; i++) {
range.push(i);
}
return $('#tree').treeview('checkNode', [range, {silent: true}]);
}
}
Edit: revised code to properly handle the case where the last child has children.
Upvotes: 0