I'm using jsTree to show a tree with checkboxes. Each level of nodes is loaded on-demand using the json_data
plugin.
If a node's descendent is checked, then that node should be in an "undetermined state" (like ACME and USA).
The problem is, the tree starts out collapsed. ACME looks unchecked
but should be undetermined
. When I finally expand to a checked node, jsTree realizes the ancestors should be undetermined
.
So I need to be able to put a checkbox in the undetermined
state without loading its children.
With jsTree
you can pre-check a box by adding the jstree-checked
class to the <li>
. I tried adding the jstree-undetermined
class, but it doesn't work. It just puts them in a checked state.
Here's my code:
$("#tree").jstree({
plugins: ["json_data", "checkbox"],
json_data: {
ajax: {
url: '/api/group/node',
success: function (groups) {
var nodes = [];
for (var i=0; i<groups.length; i++) {
var group = groups[i];
var cssClass = "";
if(group.isSelected)
cssClass = "jstree-checked";
else if(group.isDecendantSelected)
cssClass = "jstree-undetermined";
nodes.push({
data: group.name,
attr: { 'class': cssClass }
});
}
return nodes;
}
}
}
})
My Question
How do I set a node to the undetermined
state?
I'm using jsTree to show a tree with checkboxes. Each level of nodes is loaded on-demand using the json_data
plugin.
If a node's descendent is checked, then that node should be in an "undetermined state" (like ACME and USA).
The problem is, the tree starts out collapsed. ACME looks unchecked
but should be undetermined
. When I finally expand to a checked node, jsTree realizes the ancestors should be undetermined
.
So I need to be able to put a checkbox in the undetermined
state without loading its children.
With jsTree
you can pre-check a box by adding the jstree-checked
class to the <li>
. I tried adding the jstree-undetermined
class, but it doesn't work. It just puts them in a checked state.
Here's my code:
$("#tree").jstree({
plugins: ["json_data", "checkbox"],
json_data: {
ajax: {
url: '/api/group/node',
success: function (groups) {
var nodes = [];
for (var i=0; i<groups.length; i++) {
var group = groups[i];
var cssClass = "";
if(group.isSelected)
cssClass = "jstree-checked";
else if(group.isDecendantSelected)
cssClass = "jstree-undetermined";
nodes.push({
data: group.name,
attr: { 'class': cssClass }
});
}
return nodes;
}
}
}
})
My Question
How do I set a node to the undetermined
state?
3 Answers
Reset to default 4I had the same problem and the solution I found was this one:
var tree = $("#tree").jstree({
plugins: ["json_data", "checkbox"],
json_data: {
ajax: {
url: '/api/group/node',
success: function(groups) {
var nodes = [];
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
var checkedState = "false";
if (group.isSelected)
checkedState = "true";
else if (group.isDecendantSelected)
checkedState = "undetermined";
nodes.push({
data: group.name,
attr: { 'checkedNode': checkedState }
});
}
return nodes;
},
plete: function () {
$('li[checkedNode="undetermined"]', tree).each(function () {
$(this).removeClass('jstree-unchecked').removeClass('jstree-checked').addClass('jstree-undetermined');
});
$('li[checkedNode="true"]', tree).each(function () {
$(this).removeClass('jstree-unchecked').removeClass('jstree-undetermined').addClass('jstree-checked');
});
$('li[checkedNode="false"]', tree).each(function () {
$(this).removeClass('jstree-checked').removeClass('jstree-undetermined').addClass('jstree-unchecked');
});
}
}
}
});
Hope it helps you!
Maybe this changed in the meanwhile...
But now (version 3.0.0) the really simple solution works:
{
id : "string" // will be autogenerated if omitted
text : "string" // node text
icon : "string" // string for custom
state : {
opened : boolean // is the node open
disabled : boolean // is the node disabled
selected : boolean // is the node selected
undetermined : boolean // is the node undetermined <<==== HERE: JUST SET THIS
},
children : [] // array of strings or objects
li_attr : {} // attributes for the generated LI node
a_attr : {} // attributes for the generated A node
}
Learned directly from the source code at: https://github./vakata/jstree/blob/6507d5d71272bc754eb1d198e4a0317725d771af/src/jstree.checkbox.js#L318
Thank you guys, and I found an additional trick which makes life a little better, but it requires a code change in jstree.js. Looks like an oversight:
Look at the get_undetermined function, and scan for the keyword break. That break should be a continue.
If you make that one change, then all you need to do is provide the state (for the main object and its children), and jstree will automatically take care of cascading upwards for undetermined state. It was bailing out early from the scripting and failing to catch all the undetermined nodes properly, requiring the above ugly workarounds for styling and such.
Here's my config (no special attrs or plete() function required) using AJAX:
var tree = $('#jstree').jstree({
"core": {
"themes": {
"variant": "large"
},
'data': {
'url': function (node) {
return "{{API}}/" + node.id + "?product_id={{Product.ID}}"
},
'dataType': 'json',
'type': 'GET',
'success': function (data) {
if (data.length == 0) {
data = rootStub
}
return {
'id': data.id,
'text': data.text,
'children': data.children,
'state': data.state,
}
}
}
},
"checkbox": {
// "keep_selected_style": false,
"three_state": false,
"cascade": "undetermined"
},
"plugins": ["wholerow", "checkbox"],
});