1. ホーム
  2. jquery

[解決済み] jstree の右クリックコンテキストメニューを異なるノードタイプに設定する

2023-04-16 12:10:25

質問

jstree の右クリックコンテキストメニューの外観をカスタマイズする方法(contextmenu プラグインを使用)を示す例を、ネット上のどこかで見たことがあります。

たとえば、ユーザーが "documents" は削除できるが、"folder" は削除できないようにします (フォルダーのコンテキスト メニューから "delete" オプションを非表示にして)。

今、その例を見つけることができません。どなたか正しい方向を示していただけませんか? 公式の ドキュメント は本当に役に立ちませんでした。

編集してください。

私は、1 つか 2 つの小さな変更を加えたデフォルトのコンテキスト メニューが欲しいので、メニュー全体を再作成しないことを希望します (もちろん、それが唯一の方法である場合はそうしますが)。私が行いたいことは、次のようなものです。

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

しかし、これはうまくいきません。作成項目は常に無効になっているだけです(アラートは決して表示されません)。

どのように解決するのですか?

この contextmenu プラグインはすでにこれをサポートしています。リンク先のドキュメントから。

items : オブジェクトを期待するか オブジェクトを返すべき関数 . 関数が使用された場合、ツリーのコンテキストで起動され、1つの引数 - 右クリックされたノード - を受け取ります。

ですから 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;
}

上記は削除オプションを完全に隠してしまいますが、このプラグインでは、項目を表示しながらその動作を無効にすることも可能です。 _disabled: true を追加することで表示させることもできます。この場合 items.deleteItem._disabled = true の中で if 文の中に記述します。

当然といえば当然ですが、プラグインを初期化する際には customMenu 関数でプラグインを初期化することを忘れないでください。

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


編集してください。 右クリックのたびにメニューを再作成させたくない場合は、削除メニュー項目自体のアクションハンドラにロジックを入れることができます。

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


もう一度編集してください。 jsTreeのソースコードを見てみると、どうやらcontextmenuが表示されるたびに再作成されているようです( show()parse() 関数を使用することができます)。したがって、私の最初の解決策に問題はありません。

しかし、私はあなたが提案している記法が好きで、関数を _disabled . 探索する潜在的な道は、彼らの parse() にある関数を評価する独自の関数でラップすることです。 disabled: function () {...} で評価し、その結果を _disabled に格納し、その後に元の parse() .

それらのソースコードを直接修正することも難しくありません。バージョン 1.0-rc1 の 2867 行が関連するものです。

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

この前に単純に、チェックする行を追加することができます。 $.isFunction(val._disabled) をチェックし、もしそうなら val._disabled = val._disabled() . そして、それをパッチとしてクリエイターに提出します :)