I've seen an example somewhere online showing how to customise the appearance of jstree's right-click context menu (using contextmenu plugin).

例如,允许我的用户删除"文档",但不能删除"文件夹"(通过隐藏文件夹上下文菜单中的"删除"选项).

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'); 
            }
        }
    }
}

但它不起作用——创建项总是被禁用(alert 永远不会出现).

推荐答案

The contextmenu plugin already has support for this. From the documentation you linked to:

items: Expects an object or a function, which should return an object. If a function is used it fired in the tree's context and receives one argument - the node that was right clicked.

因此,您可以提供以下函数,而不是让contextmenu使用硬编码对象.它判断在名为"Folder"的类中单击的元素,并通过从对象中删除"delete"菜单项来删除该菜单项:

function customMenu(node) {
    // The default set of all items
    var items = {
        renameItem: { // The "rename" menu item
            label: "Rename",
            action: function () {...}
        },
        deleteItem: { // The "delete" menu item
            label: "Delete",
            action: function () {...}
        }
    };

    if ($(node).hasClass("folder")) {
        // Delete the "delete" menu item
        delete items.deleteItem;
    }

    return items;
}

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 use items.deleteItem._disabled = true within the if statement instead.

应该是显而易见的,但记住使用customMenu函数初始化插件,而不是使用之前的函数:

$("#tree").jstree({plugins: ["contextmenu"], contextmenu: {items: customMenu}});
//                                                                    ^
// ___________________________________________________________________|

Edit:如果您不想在每次右键单击时重新创建菜单,可以将逻辑放入"删除"菜单项本身的操作处理程序中.

"label": "Delete",
"action": function (obj) {
    if ($(this._get_node(obj)).hasClass("folder") return; // cancel action
}

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() and parse() 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 their parse() function with your own one that evaluates the function at disabled: function () {...} and stores the result in _disabled, before calling the original parse().

It won't be difficult either to modify their source code directly. Line 2867 of version 1.0-rc1 is the relevant one:

str += "<li class='" + (val._class || "") + (val._disabled ? " jstree-contextmenu-disabled " : "") + "'><ins ";

你可以简单地在这一行前面加一行,判断$.isFunction(val._disabled),如果是的话,判断val._disabled = val._disabled().然后将其作为补丁提交给创建者:)

Jquery相关问答推荐

ASP.NET Core 8 MVC:从jQuery发布控制器中的所有值为空

JQuery日期 Select 器未设置从jQuery中 Select 的月份起90天或3个月

当一个很长的活动增加标题时,满历js每周都会出现.这是一种让标题只出现一次的方法吗?

如果在视窗中有相同的数据属性值,则jQuery/添加类

多个 AJAX 调用;获取所有失败的呼叫

可以推迟 jQuery 的加载吗?

jQuery:在mousemove事件期间检测按下的鼠标按钮

jQuery / Ajax - $.ajax() 将参数传递给回调 - 使用好的模式?

jQuery绑定到粘贴事件,如何获取粘贴的内容

jQuery UI 滑块(以编程方式设置)

如何获取 onclick 调用对象?

获取跨域 iframe 的 DOM 内容

使用 JQuery 获取触发事件的元素的类

如何检测 window.print() 完成

测试两个元素是否相同

$(document).on("click"... 不工作?

更改 Eclipse 设置以忽略特定文件上的错误

带有函数的 JavaScript 三元运算符示例

Bootstrap datepicker Select 后隐藏

如何判断值是否为 JSON 对象?