I've seen an example somewhere online showing how to customise the appearance of jstree's right-click context menu (using contextmenu plugin).
For example, allow my users to delete "documents" but not "folders" (by hiding the "delete" option from the context menu for folders).
Now I can't find that example. Can anyone point me in the right direction? The official documentation didn't really help.
Edit:
Since I want the default context menu with only one or two minor changes, I'd prefer to not recreate the whole menu (though of course I will if it's the only way). What I'd like to do is something like this:
"contextmenu" : {
items: {
"ccp" : false,
"create" : {
// The item label
"label" : "Create",
// The function to execute upon a click
"action": function (obj) { this.create(obj); },
"_disabled": function (obj) {
alert("obj=" + obj);
return "default" != obj.attr('rel');
}
}
}
}
but it doesn't work – the create item is just always disabled (the alert never appears).
Best Answer
The
contextmenu
plugin already has support for this. From the documentation you linked to:So rather than give
contextmenu
a hard-coded object to work with, you can supply the following function. It checks the element that was clicked for a class named "folder", and removes the "delete" menu item by deleting it from the object:Note that the above will hide the delete option completely, but the plugin also allows you to show an item while disabling its behaviour, by adding
_disabled: true
to the relevant item. In this case you can useitems.deleteItem._disabled = true
within theif
statement instead.Should be obvious, but remember to initialise the plugin with the
customMenu
function instead of what you had previously:Edit: If you don't want the menu to be recreated on every right-click, you can put the logic in the action handler for the delete menu item itself.
Edit again: After looking at the jsTree source code, it looks like the contextmenu is being re-created every time it is shown anyway (see the
show()
andparse()
functions), so I don't see a problem with my first solution.However, I do like the notation you are suggesting, with a function as the value for
_disabled
. A potential path to explore is to wrap theirparse()
function with your own one that evaluates the function atdisabled: function () {...}
and stores the result in_disabled
, before calling the originalparse()
.It won't be difficult either to modify their source code directly. Line 2867 of version 1.0-rc1 is the relevant one:
You can simply add a line before this one that checks
$.isFunction(val._disabled)
, and if so,val._disabled = val._disabled()
. Then submit it to the creators as a patch :)