Search code examples
jstreeaddeventlisteneronkeypress

jsTree: bind keypress event on a newly created node


I am trying to bind keypress event on a newly created node from context menu of jsTree. It seems adding listener for each and every node is not so good idea..Edited as per suggestion based on comments provided below

$(function () {
        $('#demo').jstree({
             ...
              "contextmenu":{         
                    "items": function($node) {
                        var tree = $("#demo").jstree(true);
                        return {
                            "Create": {
                                "separator_before": false,
                                "separator_after": false,
                                "label": "Create",
                                "action": function (obj) { 
                                    var newNode = createNode($node,tree);
                                    //tree.edit(newNode);

                        tree.edit(newNode, null, function (the_node, rename_status) {

                            console.log("status:"+rename_status);
                        });
                                   }
                            }
                            }
                        };
                    }
                }

            })
    });




function createNode($node,tree)
   {
      $newNode = tree.create_node($node); //create new node
      return $newNode;
   }

Solution

  • The jstree create_node functions does not return a DOM node, it returns an ID string, as stated here: http://www.jstree.com/api/#/?q=create_node&f=create_node%28[obj,%20node,%20pos,%20callback,%20is_loaded]%29

    In order to be able to attach any event you need the DOM node, so rewrite your createNode function to this:

    function createNode($node,tree) {
        $newNode = tree.create_node($node); //create new node
        return tree.get_node($newNode, true);
    }
    

    Also keep in mind if you attach a handler like this, it will be lost if the parent of this node is closed and then opened, as jstree keeps only visible nodes in the DOM. If that is not OK for you - use event delegation, for example by attaching the event to the tree container.


    As per the comments below, a better solution would be to use the edit callback (provided you are using jstree v.3.1.1 or later):

    tree.edit(newNode, null, function (the_node, rename_status) {
      // any custom logic you need
    })
    

    Here is the final demo using the edit callback and v.3.1.1: http://jsfiddle.net/DGAF4/498/

    If using an earlier version OR you do not care about catching calls to rename_node - listen for the rename_node.jstree event - this is the preferred method to react to name changes.