vakata / jstree

jquery tree plugin
http://jstree.com
MIT License
5.15k stars 1.38k forks source link

get_checked returns a list of nodes that contains a false node #2544

Closed andrew-schweyen closed 1 year ago

andrew-schweyen commented 3 years ago

I'm running into an issue where get_checked returns a list of nodes where the list contains a node that is false. This is an issue when calling get_top_checked as it calls tmp[i].children_d.length;, but when tmp[i] = false this results in an error. Get_checked only returns an array containing false when there is a single parent node selected and all of its child nodes don't have any children. A sample scenario can be seen in the tree below:

image

The code to initialize the tree can be seen below: $(function () { $(treeName).jstree({ "checkbox": { "keep_selected_style": false, "whole_node": true, "tie_selection": false }, "core": { "check_callback": true, }, "plugins": ["types", "checkbox"], types: { "root": { "icon": "glyphicon glyphicon-plus" }, "child": { "icon": "glyphicon glyphicon-leaf" }, "default": { "icon": "wwwroot/css/Employee Icon.png" } } }); });

vakata commented 3 years ago

This is odd - I can easily fix the error, but it would be better if you provide some information on how this is happening? It seems that a selected node disappears from the internal structure, which is very odd. Usually the selected array is kept in sync. Do you modify the internal collections yourself (core._model, core.selected, etc)?

andrew-schweyen commented 3 years ago

I do not modify the internal collections myself. I'm dynamically adding child nodes to the tree as users interact with it.

Below is where I add nodes to the tree. return $(treeName).jstree().create_node(parentNode, { "id": id, "text": text, "a_attr": { "href": ""}, "data": { "hasChildren": hasChildren, "isPopulated": isPopulated, "isDummy": isDummy } }, "last", function () { });

I also delete nodes on the fly as well. I add a dummy child to all nodes that have children. When a node is expanded for the first time, the dummy node is deleted and new nodes are added.

// We need to delete the dummy node we inserted // This is done after the API has returned otherwise the node appears to go from having children // to not having children to having children again. This is less noticable UI-wise var currentNodeDOM = $(treeName).jstree('get_children_dom', data.node); $(treeName).jstree('delete_node', currentNodeDOM[0].id);

vakata commented 2 years ago

I will try to track the issue further, but in the mean time - you can use the loaded and children properties of the node - set to false and true and jstree will show the node as having children and trigger the load function when the user tries to open the node.