DGis
DGis

Reputation: 31

jsTree Context Menu selected item?

We're working with jsTree (revision 236 from 09/02/2011).

Does anyone know if there is any way to access the menu item name selected in the function associated with the "action"?

I want to automate the definition of menu items, so that the functionality of the "action" for each are set based on the identifier of the item in the contextual menu.

For example, for a context menu with three actions ("A", "B" or "C")

...
var items = {};             
for(var i=0; i < preconfiguredItemsData.length; i++) 
{ 
    var item = preconfiguredItemsData[i]; 

    items[item.name] = {
        "label": item.title,
        "action": function (liNode) {
            control = eval("new " + **SELECTED ITEM IDENTIFIER ?** + "()"); 
                    // **new A(), new B() or new C()** depending on the selected
                    // item on the context menu.
                    // I have the identifier of the jsTree node but ... how
                    // can I get the item id ("A", "B" or "C")?
            control.execute(); 
        },              
        "_class": "class",  
        "separator_before": false,
        "separator_after": true,
        "icon": false,
        "submenu": {}
    };
    ...
} //for

items.create = false; 
items.rename = false; 
items.remove = false,
items.edit = false;
items.ccp = false;

...

I hope to have described my problem clearly.

Thanks in advance.

Upvotes: 3

Views: 5529

Answers (3)

iled
iled

Reputation: 2170

There is much simpler solution, that requires no modification in jstree's source code. I tested this approach with jstree 3.3.1.

From the docs (emphasis mine):

Once a menu item is activated the action function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu.

The item property is the complete definition of your context menu item. This means that you can attach whatever property to that object, and retrieve its value later. In the question example, that could be the _class property. It is not clear whether the OP tried this approach or not.

var items = {
  item1: {
    label: 'a label',
    icon: 'fa fa-font-awesome',
    separator_after: true,
    disabled: false,
    action: lang.hitch(this, 'doSomething'),
    _name: 'item1'
  }
}

Then, _name will be passed in the item property.

doSomething: function (obj) {
  console.log(obj.item._name)
}

Upvotes: 1

Mike Gledhill
Mike Gledhill

Reputation: 29161

I'm using jsTree 3.0.2, and this fix didn't work for me.

The "i" parameter is already included in the results sent to the "action" function, but it just contains details about the Context Menu which was clicked on, rather than the JSON item which was binded to that jsTree branch.

enter image description here

To get the id of the item which was right-clicked on, here's what I did.

Some of the branches in my tree are folders, and some are reports (which the user can run), so I needed to be able to adapt my jsTree context menu, depending on which type of node the user right-clicked on, and for reports, I needed to fetch the ID of the record which was selected.

enter image description here

First, I wrote a small getCustomMenu function to fetch the context menu items for a particular jsTree branch, so, I defined my jstree as below.

$('#divReportsTree').jstree({
   "core": {
       'data': JSON.Results.core.data
   },
   "plugins": ["contextmenu"],
   "contextmenu" : {
       //  Call a function, to fetch the CustomMenu for this particular jsTree branch
       items: getCustomMenu    
   }, 
})

And my getCustomMenu function looked like this:

function getCustomMenu(node) {

    var thisReportID = node.li_attr.ReportID;

    var items = {
      Run: {
        "separator_before": false,
        "separator_after": true,
        "label": "Run this report",
        "icon": "/Images/Icons/Go.png",
        "action": function (node, reportID) {
             //  Call a function to run a report, with a particular Report ID 
             RunReport(node, thisReportID);
        }
      },
      Refresh: {
        "separator_before": false,
        "separator_after": false,
        "label": "Refresh",
        "icon": "/Images/Icons/Refresh.png",
        "action": function (node, reportID) {
             //  Call a refresh function, with a particular Report ID 
             RefreshReport(node, thisReportID);
        }
    };

    //  If this is a jsTree node for a Folder (rather than a Report) then 
    //  just show the "Refresh" ContextMenu item
    if (node.li_attr.ReportID == null)
    {
        delete items.Run;
    }

    return items;
}

When the user right-clicks on a Report in my jstree, the getCustomMenu function will call my RunReport function with the ID of the selected report.

enter image description here

The key to this is that the JSON data which populates this tree specifically adds a ReportID attribute in to the jsTree's li_attr attribute.

enter image description here

Because our getCustomMenu calls the action function ("RunReport", in this example), we can adapt it to pass extra parameters to this function.

Phew.

Hope all this helps (and makes sense !)

Upvotes: 3

DGis
DGis

Reputation: 1

Solved by adding function name as parameter in this function call of the original jquery.jstree.js.

(function ($) {
    $.vakata.context = {
            .....
            exec : function (i) {
                ....
                if($.isFunction($.vakata.context.func[i])) {
                    ....
                    $.vakata.context.func[i].call($.vakata.context.data, $.vakata.context.par, i);    //Param 'i' added        
                    ....
                }
                ....
            }
            ....
        }

Thanks!

Upvotes: 0

Related Questions