jsTree のプラグイン contextmenu は、デフォルトのままではフォルダとファイルのように、
ある種類のノードの配下にノードを作成することができない
=ファイルの下に、フォルダ/ファイルは作れてはいけないはずだ。。
つまり、ツリー構造を作成できるのは、フォルダのみでファイルではない。
・・・当たり前の規則だが。。。
jsTree デフォルトの contextmenu をそのまま使うと全てに対して、
配下にノードを作成ができてしまう。
だから、フォルダとファイルのようなツリーでコンテキストメニューを用意する場合
、自分でカスタマイズして書いてあげないとならない。
contextmenu 書込みの準備、 "plugins":[ "contextmenu" ], を書いて、
次にコンテキストメニューの設定を書く。
フォルダとファイルの区別は、icon 属性で区別する制御にする。
ノードに任意属性種別を作っても、コピー操作の処理は、
jsTree のコア内部処理でとてもオーバーライドできるような代物ではなく、
任意属性の新しい規則を作ってコピー時にきちんとコピーされるように
するのは非常に厳しい。
→ よって、icon 属性でフォルダとファイルの区別制御をする。
初期データにも↓のとおり、"icon" を書く
$('#treediv').jstree({ 'core':{ 'data':[ { "id":1, "icon":"jstree-folder", "text":"Root", "children":[ { "id":2, "icon":"jstree-file", "text":"AAA" } ] } ], "check_callback" : true }, "plugins":[ "contextmenu" ], // ここに、contextmenu のカスタマイズを書き込む } });
"plugins":[ "contextmenu" ], の次に書くもの。
"contextmenu":{ "items":function($node){ return { "createFolder":{ "separator_before": false, "separator_after": false, "label": "新規フォルダ作成", "_disabled": function(data){ return $.jstree.reference(data.reference) .get_node(data.reference).icon != "jstree-folder"; }, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.create_node(obj, { text:'New Folder', 'icon':'jstree-folder' } , "last", function(new_node){ try{ inst.edit(new_node); }catch(ex){ setTimeout(function(){ inst.edit(new_node); },0); } }); } }, "createFile":{ "separator_before": false, "separator_after": false, "label": "新規ファイル作成", "_disabled": function(data){ return $.jstree.reference(data.reference) .get_node(data.reference).icon != "jstree-folder"; }, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.create_node(obj, { text:'New File', 'icon':'jstree-file' } , "last", function(new_node){ try{ inst.edit(new_node); }catch(ex){ setTimeout(function(){ inst.edit(new_node); },0); } }); } }, "rename":{ "separator_before": true, "separator_after": false, "label": "名称の変更", "_disabled": false, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.edit(obj); } }, "remove":{ "separator_before": false, "separator_after": false, "label": "削除", "_disabled": function(data){ return $.jstree.reference(data.reference) .get_node(data.reference).parent == "#"; }, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if (inst.is_selected(obj)){ inst.delete_node(inst.get_selected()); }else{ inst.delete_node(obj); } } }, "cut":{ "separator_before": true, "separator_after": false, "label": "切り取り", "_disabled": function(data){ return $.jstree.reference(data.reference) .get_node(data.reference).parent == "#"; }, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if (inst.is_selected(obj)){ inst.cut(inst.get_top_selected()); }else{ inst.cut(obj); } } }, "copy":{ "separator_before": false, "icon": false, "separator_after": false, "label": "コピー", "_disabled": function(data){ return $.jstree.reference(data.reference) .get_node(data.reference).parent == "#"; }, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if (inst.is_selected(obj)){ inst.copy(inst.get_top_selected()); }else{ inst.copy(obj); } } }, "paste":{ "separator_before": false, "separator_after": false, "label": "貼り付け", "icon": false, "_disabled": function(data){ if ($.jstree.reference(data.reference) .get_node(data.reference).icon != "jstree-folder") return true; return !$.jstree.reference(data.reference).can_paste(); }, "action": function(data){ var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.paste(obj); console.log( obj ); } } }; } }