jsTree配布デモを見ても、ツリー全体JSONをAJAXで読み込む方法はあるが、
静的に書いたJSON から下の階層を開く時や、AJAX読込み後さらに下の階層を読み込む方法が、
なかなか解らなかった。massload とかプラグインあるみたいだが、どうもできない。。。
クリックしたら
読込み終わったら自動的に、、
ということがしたい。巨大なツリーやあるノードにぶら下がる下が大量に子が存在すると、
これができない場合、ツリーデータ全てを読込みサーバから送信が終わるまで表示できないなんて
とてもつらいだろう。。
でもなんとか、AJAX読込み後さらに下の階層を読み込む方法が判った。
後から読み込ませるノードの id に任意のキーを設定し、初期状態を "state": "closed"
子ノードがあることだけを示すように、"children":[ ] を書かないで、"children": true を書く。
AJAX読込みの url は、url : function(node){ } を書いて、対象ノードIDで JSON取得先を変えて
ツリー全体か、設定した任意のキーに沿った JSON を取得するようなURL、
どちらかを返すようにする。
上の画像のサンプル
ツリー全体のJSONデータ (root.json )
[ { "id":1, "icon":"jstree-folder", "text":"Root 1", "title":"This is Root 1", "children":[{ "id":2, "icon":"jstree-file", "text":"Child 2", "title":"This is Child 2" }] },{ "id" : "submore", "icon": "jstree-folder", "text": "Root 2", "title":"open more ...", "state": "closed", "children": true } ]
↑"id" : "submore" のノードを開いた時の JSONデータ(sub.json)
[{ "id":21, "icon":"jstree-file", "text":"A001", "title":"This is A001" },{ "id":22, "icon":"jstree-file", "text":"A002", "title":"This is A002" },{ "id":23, "icon":"jstree-file", "text":"A003", "title":"This is A003" },{ "id":24, "icon":"jstree-file", "text":"A004", "title":"This is A004" }]
ブラウザで表示させる jQuery
$.jstree.defaults.core.themes.variant = "large"; $.jstree.defaults.core.themes.responsive = true; $('#tree').jstree({ "core": { "multiple": false, "data": { "url" : function(node){ var url = "/mycontext/treeview?req=#"; if (node.id === "submore") url = "/mycontext/treeview?req=sub"; return url; }, "dataType" : "json" } } }).on("hover_node.jstree", function(e, data){ $("#"+data.node.id).prop('title', data.node.original.title); });
サーバ側、別に Wicket でなくても要求に従って上のJSONを送るのが振り分けさえ
できてればよいのですが、参考として。。
Wicket での例です。
URLと WebPage クラスの紐付け、WebApplication の init でマウント
mountPage("/treeview", TreeAjaxJsonRes.class);
WebPage (TreeAjaxJsonRes) で
getRequestCycle().getRequest().getQueryParameters().getParameterValue("req").toString();
でパラメータ受け取り
File file = // URLパラメータ"req" の結果で、root.json か sub.json のどちらかを読み込むファイル getRequestCycle().scheduleRequestHandlerAfterCurrent( cycle->{ try(InputStream in = new FileInputStream(file); ByteArrayOutputStream out = new ByteArrayOutputStream()){ in.transferTo(out); text = out.toString(); cycle.getResponse().getOutputStream().write(text.getBytes()); }catch(IOException ex){ logger.error(ex.getMessage(), ex); } } );