web-dev-qa-db-ja.com

jsTree全体を無効にする

私はjsTreeを使用しており、編集/保存できる選択したノードに基づいて、その右側にフォームがあります。目標は、ユーザーがフォームの編集中にツリーの他の場所をクリックしないようにすることです。

ツリーを視覚的に利用可能な状態に保ちながら、ツリー機能を一時的に無効/有効にする方法はありますか?

disable_node(obj)メソッドを使用してツリーのルートに適用しようとしましたが、解決策ではないようです。

助言がありますか?または、これはjsTree libで可能な機能ではありませんか?

ありがとう

9

選択したノードを無効にするには、次のようにします。

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

すべてのノードを無効にするには、次を使用します。

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

更新しました

無効化されたノードが開かないようにする方法が見つからなかったため、閉じられたノードのすべての子も無効にします。

デモを参照してください: フィドル

10
Nikolay Ermakov

編集 @charlesで指摘されているように、ノードを無効にしても、メニュープラグイン(少なくともカスタムメニューの場合)は無効にならず、ドラッグアンドドロップ-これを処理するためにポイント4を追加しました

ツリー全体を無効にするには

  1. レンダリングされたすべてのノードを無効にする-IDで各ノードを無効にするまたはIDの配列を取得して、「disable_node」を1回呼び出します
  2. 新しいノードを開くことを禁止する-開くアイコンのクリックイベントを傍受してブロックする
  3. ダブルクリックで新しいノードを開くことを禁止する-現在のツリー設定を変更する
  4. ツリーが何らかの方法でユーザーが変更できる場合は、すべての変更設定を一時的に無効にします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>
3
edc65

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
}

もう1つの方法は、何かを使用することです jQuery BlockUIプラグイン jsTreeの外部で一般的なブロッキングを実行します。

1
Charles

これはどう?

// 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 }));
0
wonsuc