42

I have a jstree. I want to select the node which is bound to the object which has a location with id of 158. This works but seems stupid. What's the more idiomatic way of doing this?

var $tree = $('.jstree', myContext),
    node = $tree.find('li').filter(function() { 
        return ( $(this).data().location || {}).id === 158;
    });
$tree.jstree('select_node', n)
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
George Mauer
  • 117,483
  • 131
  • 382
  • 612
  • 1
    The above code doesn't work for you? Could you provide jsfidlle sample? – Radek Dec 12 '11 at 00:54
  • 1
    @Radek - it works, but it seems like there has got to be a better way of doing this than 'grab all li and test their data'. It feels like I can't find the front door and am using a side one. This for example could break if there are changes to the tree structure while it is filtering or if list items are added/removed manually. – George Mauer Dec 12 '11 at 02:57
  • I have the same problem, but every solution I find out there assumes that I have some mysterious "ID" to select. But I don't. I just have a recursive JSON dict/array and no IDs. Is there no way to select a node just by path, such as /path/to/some/file? – Teekin Aug 13 '17 at 13:24

9 Answers9

46

Just wanted to chime in here as none of the answers worked for me. What finally DID work was very simple:

$('#someTree').jstree('select_node', 'someNodeId');

Note that I didn't initialize someNodeId as a jQuery object. It's just a plain string.

I did this right after a tree was loaded without putting it into a "ready" bind event as it seems to not be necessary.

Hope it saves some one from a few frustrating hours. . .

To hook into the tree after it has been loaded:

.on('loaded.jstree', function() {
    // Do something here...
  });
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Matt Cashatt
  • 23,490
  • 28
  • 78
  • 111
  • 1
    The loaded.jstree part helped me. – nima Jan 25 '15 at 14:44
  • It works, but I'm not a fan of string based method invocation. I prefer $("#someTree").jstree().select_node(["nodeId1", "nodeId2"]) syntax. – Tikall Jul 19 '16 at 07:18
  • @shantaram--Great, glad it helped you. Gotta love stackoverflow! – Matt Cashatt Dec 14 '16 at 15:44
  • @MattCashatt I have a question, how can i create an object of `someNodeId` in $('#someTree').jstree('select_node', 'someNodeId');. [here](https://stackoverflow.com/questions/51666785/jstree-how-to-send-array-to-select-node-method) i post a question about it. – topcool Aug 03 '18 at 07:29
23

Based on jsTree groups you can try

jQuery("#getStartedTree").jstree("select_node", "#test2"); 

if the data looks like

The JSON in the TextFile.txt - borrowed from your simple example
 [
     {
     "data" : "A node",
     "children" : [ "Child 1", "Child 2" ]
     },
     {
     "attr" : { "id" : "test1" },
         "data" : {
             "title" : "Long format demo",
             "attr" : { "id" : "test2", "href" : "#" }
         }
     }
 ] 

and jsTree set up

My tree container is <div id="getStartedTree">

My jsTree code
 $("#getStartedTree").jstree({
            "themes": {
                "theme": "default",
                "url": "../App_Css/Themes/Default/style.css",
                "dots": true,
                "icons": true
            },
            "json_data": {
                "ajax": {
                    "url": "../SiteMaps/TextFile.txt",
                    "dataType": "json",
                    "data": function(n) {
                        return { id: n.attr ? n.attr("id") : 0 };
                    }
                }
            },
            "plugins": ["themes", "json_data", "ui"]
        }); 

Is that what you are after?

Radek
  • 13,813
  • 52
  • 161
  • 255
  • 1
    But here you have to assign ids to nodes as you create them and somehow figure out the correlating id. I don't know how they implemented it but the API I'm looking for would be something like get_node_bound_to. `var treeData = $jstree.jstree('data'), nodeData = findCorrectNodeIn(data); node = $jstree.jstree('get_node_bound_to', nodeData); $jstree.jstree('select_node', node);` – George Mauer Dec 12 '11 at 04:37
  • 2
    When do you assign id to your node? And how? – Radek Dec 12 '11 at 04:44
  • 1
    I would be really really shocked if they didn't provide a way to do this. The li technique doesn't really work that great. For example I need to select a node for data matching certain criteria when the dialog containing the jstree opens. Using this li hack I have to listen to the loaded event and only then do the selection. – George Mauer Dec 12 '11 at 04:48
  • 1
    Currently, this is all based on dynamic data and the control was written by another developer who did not generate ids. But there really seems to be no reason to use them. I know the criteria for the data node I want and those data nodes are the jstree's model. Indeed, if I pulled up multiple side-by-side copies of the same jstree, using ids would explicitly fail. – George Mauer Dec 12 '11 at 04:53
  • 1
    If you don't have id's you have to do some kind of search, do you. – Radek Dec 12 '11 at 06:10
  • 1
    Yes, I do a search through the data model - see the filter block in my original question or the findCorreectNodeIn function above. This returns the node in the data model that the node in the UI that I want is bound to. I mean this _has_ to be a very common operation. Creating a button to expand all nodes containing a certain text for example. – George Mauer Dec 12 '11 at 15:05
  • 1
    But in your search above you use some kind of id (.id === 158;) – Radek Dec 13 '11 at 00:11
  • 1
    That is a coincidence. The javascript object that is being bound (it is apparently stored in data-location for each li) has an id property. The DOM elements themselves have no ids – George Mauer Dec 13 '11 at 19:00
  • 1
    So hoe do you know then what to select? – Radek Dec 13 '11 at 21:10
  • 1
    Well look at my "working but shitty" code - it works by looking through the data that jstree attaches to each list item. That is another thing I'm worrid about - that's not a guaranteed interface. – George Mauer Dec 14 '11 at 15:53
  • 1
    If the id is a coincidence how else do you want to to the search? – Radek Dec 15 '11 at 04:36
  • 1
    I'm not sure what the confusion can be. jstree seems to use a standard view-model pattern. The vm in this case is the hierarchy of data-bound object nodes. If I can identify a node then there is a jstree node that correlates to it. The filter function above simply identifies a node. This has nothing to do with the HTML id attribute. – George Mauer Dec 16 '11 at 20:05
  • 1
    I don't understand. How come it has nothing to do with id if you use a `condition === 158` ? – Radek Dec 18 '11 at 22:54
  • 1
    Radek, the id in `
    ` is an xml attribute named id. The id property of an object `{id: 123}` is just a property on an object that happens to be named 'id'. They are not at all the same thing.
    – George Mauer Dec 19 '11 at 01:55
  • 1
    Can you add id to nodes when creating data? – Radek Dec 19 '11 at 01:59
  • 1
    Not easily, but adding id nodes at the time I create the data will be almost as fragile as my current approach. My question is what is the "correct" way of handling this requirement. Lots of people use jstree and this is not such a crazy thing that I'm trying to do so I would imagine there is something less hacky that I just don't know about. – George Mauer Dec 19 '11 at 02:04
  • 1
    I am still lost :-) Why is that fragile? If you want to select a node you have to identify the node. Somehow. Why not by using id? – Radek Dec 19 '11 at 02:18
  • 1
    1) Because ids are supposed to be unique to the page - so what if you want 2 copies of the same tree, 2) because you have to invent an algorithm for generating ids, 3) because someone might add a node to the jstree without knowing that they're supposed to assign an id to it 4) because between the time when you create an id and when you try to find by it, the data that UI node is bound to might have changed. Basically I want to go from data bound object directly to the bound node. Introducing an id is introducing yet another concept and another possible point of failure. – George Mauer Dec 19 '11 at 02:21
  • 1
    The ONLY reason why DOM ids are not exactly as fragile as the approach I outlined is because it does not depend on the undocumented presence of the viewmodel node in the UI node's data() object – George Mauer Dec 19 '11 at 02:23
6

I did it with:

$('.jstree').jstree(true).select_node('element id');

this code:

jQuery.each(produto.categorias, function(i, categoria) {
    $('#lista-categorias').jstree(true).select_node(categoria.dadoCategoria.id);
});
Alberto Cerqueira
  • 1,339
  • 14
  • 18
  • This worked for me, but I had to deselect first. I did it with $('#f_tree').jstree(true).deselect_all(true); – cwhisperer Jun 15 '21 at 05:44
5

I was able to simulate a click on a jstree node as an alternative way to select a node. The following code is what was used :

$(treeIdHandle + " li[id=" + nodeId + "] a").click();
Suketu Bhuta
  • 1,871
  • 1
  • 18
  • 26
  • 2
    This would require each node to have an id attribute which is one of the things that is not available by default (and would be terrible for performance if it was). However, in your case where the id exists, it should be possible to simplify to `$('a', '#'+nodeId).click()` – George Mauer Jul 03 '13 at 02:19
  • 1
    Yes, it would require each node to have an id attribute or even any other attribute which can uniquely identify a node in a tree. – Suketu Bhuta Jul 09 '13 at 16:00
3

If you're populating the tree using HTML instead of JSON data and wondering how to set the node_id, you just need to set the id attribute of the <li> element!

<div class="tree-menu">
    <ul class="menu">
        <li id="node_1">
            Node 1 - Level 1
           <ul class="menu">
               <li id="node_3">
                   Node 3 - Level 2
               </li>
           </ul>
        </li>
        <li id="node_2">
            Node 2 - Level 1
        </li>
    </ul>
</div>

Then

$('.tree-menu')
    .jstree(true)
    .select_node("node_3");

will select the Node 3 - Level 2 node.

For those getting javascript errors, remember to use Full version of jQuery, not the slim version!

For all down voters, here is the demo to prove it's working: https://jsfiddle.net/davidliang2008/75v3fLbs/7/

enter image description here

David Liang
  • 20,385
  • 6
  • 44
  • 70
2

i use jstree 3.0.8. don't use 'state'

'plugins' : ['dnd','sort','types','contextmenu','wholerow','ui']

and server offer the json, the selected node has

"state":{"selected":true,"opened":true}
Echilon
  • 10,064
  • 33
  • 131
  • 217
weijia
  • 21
  • 1
  • 2
    This sounds promising but can you please provide a better example or some documentation? This is not enough for someone starting out with jstree to figure it out. – George Mauer Jul 20 '15 at 16:35
1

This solution Works for me

// after the tree is loaded
$(".jstree").on("loaded.jstree", function(){
    // don't use "#" for ID
    $('.jstree').jstree(true).select_node('ElementId');
});

and even in a php loop (dynamically) :

$(".jstree").on("loaded.jstree", function(){
    <?php foreach($tree as $node): ?>
        $('.jstree').jstree(true).select_node('<?=$node?>');
    <?php endforeach;?>
});

Hope this works for you.

Mahmoud Abdelsattar
  • 1,299
  • 1
  • 15
  • 31
  • This doesn't answer the question. It is asking how to select a node that is bound to a given object - NOT the dom element. If you read the comments on the top answer, this is discussed. – George Mauer Nov 19 '16 at 01:47
0

i think u should write code to select node after jstree initialized, therefore use this code

 $('#jstree')
    .on('ready.jstree', function (e, data) {
       // do function after jstree initialized
      $('#jstree')
        .jstree(true)
        .select_node('nodeid');
    });

hope its work :)

sep7696
  • 494
  • 2
  • 16
  • Welcome to StackOverflow. This isn't really an answer to the question. The question is not about using nodeid, its about how to select by an arbitrary property of the object that the node was generated from. – George Mauer Jun 02 '20 at 19:13
-1

trigger click on first anchor

$("#jstree .jstree-anchor:first").click(); 

or by node id 158

$("#jstree #158").find(".jstree-anchor:first").click(); 

$('#' + 158).find(".jstree-anchor:first").click(); 
Paully
  • 582
  • 5
  • 12