禁用整个 jsTree

Disable the whole jsTree

我正在使用 jsTree,它的右侧有一个基于所选节点的表单,可以是 edited/saved。目标是防止用户在编辑表单时单击树上的任何其他位置。

有什么方法可以临时 disable/enable 树的功能,同时仍然保持树的可见性?

我尝试使用 disable_node(obj) 方法并将其应用于树的根,但似乎不是解决方案。

有什么建议吗?或者这不是 jsTree 库的可能功能?

谢谢

要禁用选定的节点,请按以下方式执行:

var node = $("#tree").jstree().get_selected();
$("#tree").jstree().disable_node(node);

要禁用所有节点,请使用:

$('#tree li').each( function() {
    $("#tree").jstree().disable_node(this.id);
})

已更新

我没有找到阻止打开已禁用节点的方法,所以我也只是禁用已关闭节点的所有子节点。

查看演示:Fiddle

Edit 正如@charles 所指出的 禁用节点不会禁用菜单插件(至少使用自定义菜单)或拖动'n' drop - 添加了第 4 点来解决这个问题

禁用整个树

  1. 禁用所有呈现的节点 - 通过 id 禁用每个节点获取一个 id 数组以对 "disable_node"
  2. 进行一次调用
  3. 禁止打开新节点-拦截并阻止打开图标上的点击事件
  4. 禁止双击打开新节点-修改当前树设置
  5. 如果用户可以以任何方式修改树,则暂时禁用所有修改设置 core.check_callback = false

注意 第 2 点基于未记录的功能,并且(考虑到 jstree 插件的历史)可能不适用于未来的版本

查看演示片段

var data1 = [{
  "id": "W",
  "text": "World",
  "state": { "opened": true },
  "children": [{"text": "Asia"}, 
               {"text": "Africa"}, 
               {"text": "Europe",
                "state": { "opened": false },
                "children": [ "France","Germany","UK" ]
  }]
}];

$('#Tree').jstree({ 
    core: {data: data1, 
    check_callback: true
  }, 
  plugins: ['dnd','contextmenu','checkbox']
})

function DisableFlawed() {
  // this is not enough 
  $('#Tree li.jstree-node').each(function() {
    $('#Tree').jstree("disable_node", this.id)
  })
}  
function Disable() {
  // disable visible nodes
  $('#Tree li.jstree-node').each(function() {
    $('#Tree').jstree("disable_node", this.id)
  })
  // block open new nodes
  $('#Tree i.jstree-ocl')
  .off('click.block')
  .on('click.block', function() {
    return false;
    });
  // eventually... dbl click
  $('#Tree').jstree().settings.core.dblclick_toggle = false;
  // eventually... block all edits
  $('#Tree').jstree().settings.core.check_callback = false;
}  
function Enable() {
  // enable again visible nodes
  $('#Tree li.jstree-node').each(function() {
    $('#Tree').jstree("enable_node", this.id)
  });
  // ublock open new nodes
  $('#Tree i.jstree-ocl')
  //
  .off('click.block');
  // eventually... dbl click
  $('#Tree').jstree().settings.core.dblclick_toggle = true;
  // eventually... unblock all edits
  // set to true OR reset to whatever user defined function you are using
  $('#Tree').jstree().settings.core.check_callback = true;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" type="text/css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<button onclick="DisableFlawed()">Disable (bad)</button>
<button onclick="Disable()">Disable (ok)</button>
<button onclick="Enable()">Enable</button>
<div id="Tree"></div>

除了 Nikolay Ermakov 的回答之外,禁用节点不会禁用菜单插件(至少使用自定义菜单)或拖放。如果你想这样做,你需要在这些功能中添加一个额外的检查(使用JsTree 3.2.1测试)

$('#tree').jstree({
    // ...
    contextmenu: {
        items: customMenu
    },
    dnd: {
        is_draggable: function (node) {
            return !node[0].state.disabled;
        }
    },
});

function customMenu(node)
{
    if (node.state.disabled)
        return false;

    // usual menu generation code
}

另一种方法是使用一些东西 jQuery BlockUI plugin 在 jsTree 之外做一些一般的阻塞。

这个怎么样?

// get an instance of jstree.
var tree = $.jstree.create('#tree', { ... });

// disable all nodes with one line.
tree.disable_node(tree.get_json(null, { flat: true }));