jsTree
ひさびさにツリーメニューを実装しようと思って
Treeview を設置してみたけど、動かない。。。
更新も止まっているようだし、他のプラグインを探してみたら良さそうなのがあった。 😯
採用するかどうかはわからないけど、使い方をメモ。
コード中に出てくる vakata って何かと思ってたけど
作者の HN でした。
GitHub:vakata
jsTree:3.2.1
jQuery:1.11.3
公式 の Download ボタンより DL。
2015-10-28 現在
vakata-jstree-3.2.1-0-g8ea6ce7.zip
- DL したファイルを解凍
- 中身の dist ディレクトリを js ディレクトリへ配置
- 配置した dist ディレクトリを jstree にリネーム
中には CSS ファイルや画像ファイルもあるので、本来なら分けるべきかもしれないけど、ここで完結させる。
なぜなら、テーマ名を設定するだけで、テーマの変更をできるようになっているから。
でも、その割には CSS ファイルへの参照はちゃんと記述しないとダメ。。。
- <link rel="stylesheet" type="text/css" href="./css/jstree.min.css">
- <script type="text/javascript" src="./js/jquery-1.11.3.min.js"></script>
- <script type="text/javascript" src="./js/jstree.min.js"></script>
- <script>
- $(document).ready(function(){
- $('#tree').jstree();
- });
- </script>
- <div id="tree">
- <ul>
- <li>階層1
- <ul>
- <li>階層2</li>
- </ul>
- </li>
- </ul>
- </div>
注意
階層リストの場合、書式に注意。
下記タイプA、タイプB、どちらでもリスト表示をできるけど
jsTree は、タイプB で記述しないと認識しない。
- // タイプA
- <ul>
- <li>階層1</li>
- <ul>
- <li>階層2</li>
- </ul>
- </ul>
- // タイプB
- <ul>
- <li>階層1
- <ul>
- <li>階層2</li>
- </ul>
- </li>
- </ul>
私は今までタイプAで書くのが普通だったんだけど
もしかして、正式はタイプBなのかしら。。。汗
ツリー項目に a タグを付けてリンクを貼ろうとしたけど
どうも表示が変になる。
- <li>Content <a href="#">Edit</a></li>
としても、Edit だけが表示される。
dnd の研究にノードオブジェクトの中身を覗いてみたけど
jsTree が表示用に a タグを利用しているようで
リンクを貼りたければ、click イベントで制御するしかなさそう。
プラグインも含めた設定の例。
- $(document).ready(function(){
- $('#jstree').jstree({
- // 基本設定
- 'core' : {
- 'themes' : {
- 'variant' : 'large'
- }
- },
- // プラグイン毎の設定
- 'checkbox' : {
- 'keep_selected_style' : false
- },
- // 利用するプラグインを列挙?
- 'plugins' : [ 'wholerow', 'checkbox' ]
- });
- });
- </script>
こんな感じ。
他のプラグインと同じ~。 😯
‘plugins’ で、On にしたいプラグインを列挙し
プラグイン毎の設定で、各プラグインの設定変更をする。
設定変更がなければ、プラグイン各個の設定は記述しなくて良い。
- $(document).ready(function(){
- $('#jstree').jstree({
- "core" : {
- 'themes' : {
- // 独自テーマを利用したい場合は、当該ディレクトリ名文字列を指定?
- 'name' : false,
- // 独自テーマを利用したくて、.js ファイルと別階層に置きたい場合に true を指定?
- 'url' : false,
- // url を true にしたときだけ有効。テーマの場所を記述?
- 'dir' : false,
- // ツリー罫線を表示するか否か
- 'dots' : true,
- // ノード(フォルダ)アイコンを表示するか否か
- 'icons' : true,
- // 1行おきに背景色を付けて縞々にするか否か
- 'stripes' : false,
- // CSS クラス('large', 'small', 'responsive')があるっぽい
- // false でデフォルトなんだろうけど、どれかわからない
- 'variant' : false,
- // 小さい画面の時は ture って書いてある気がするけど、true にしてみても、違いがわからない
- 'responsive' : false,
- }
- }
- });
- });
ユーザーによるツリーの変更を許可するか否か。
デフォルトは false。
- $(document).ready(function(){
- $('#jstree').jstree({
- "core" : {
- 'check_callback' : false,
- }
- });
- });
true か false か、状況によって変化させるために
関数を指定することができる。
- $(document).ready(function(){
- $('#jstree').jstree({
- "core" : {
- 'check_callback' : function (operation, node, node_parent, node_position, more) {
- if ((operation === 'move_node' || operation === 'copy_node') && (node_parent.id === '#')) return false;
- },
- }
- });
- });
- * __Examples__
- *
- * $('#tree').jstree({
- * 'core' : {
- * 'check_callback' : function (operation, node, node_parent, node_position, more) {
- * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node'
- * // in case of 'rename_node' node_position is filled with the new node name
- * return operation === 'rename_node' ? true : false;
- * }
- * }
- * });
- * @name check(chk, obj, par, pos)
- * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node"
- * @param {mixed} obj the node
- * @param {mixed} par the parent
- * @param {mixed} pos the position to insert at, or if "rename_node" - the new name
- * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node
- * @return {Boolean}
- 引数
- operation(String)
- ソース説明の通り。5種
- node(Object)
- オブジェクト
- node_parent(Object)
- 移動先の親オブジェクト
- node_position(integer)
- more(Object)
- core
- is_foreign
- is_multi
- origin(Object)
- 恐らく移動前のツリー全体の情報が格納されている
- 参考記事の more.ref.data.type の使い方不明
stackoverflow:JsTree v3.0 drag and drop plugin. Reference target node upon dropping
こちらに書かれている下記コードにおける
more.ref.data.type
が、何をどう辿っているのか不明。
- if (more.ref.data.type === "folder") {
- return true;
- }
- console.log(more.ref.data.type);
チェックは常に行っているらしく
上記のように指定することで、ドラッグ中に
root 直下へは、移動先候補 ▶ のマークが出なくなった。
こちらを設定しておくことで、ページ読み込み時に
そちらを読みにいく。
- $(document).ready(function(){
- $('#jstree').jstree({
- "core" : {
- 'data' : {
- 'url' : function (node){
- if (node.id === '#') {
- return "http://localhost:9000/getCourses/" ;
- }
- else
- return "http://localhost:9000/getCourses/" + node.id;
- }
- },
- 'data' : function (node) {
- return { 'id' : node.id };
- }
- }
- }
- });
- });
こちらは下記サイトのコードをいただいてきたが
あちこちでこのような書き方がされている。
answer uxu:jstree html and json
どうもデフォルトでは、node.id がルートの # になっていて
ルートの情報を取得して表示。
後はノードを選択する度に、そのノードの ID を送り、その配下の情報を取得し表示。
という仕様になっているっぽい。
変更の通信ではない?
jsTree という名前の jQuery プラグインに実装されている
プラグイン(追加機能)。
公式:Plugins?
- 'plugins' : [
- 'checkbox',
- 'contextmenu',
- 'dnd',
- 'massload',
- 'search',
- 'sort',
- 'state',
- 'types',
- 'unique',
- 'wholerow',
- 'changed',
- 'conditionalselect'
- ]
- $(document).ready(function(){
- $('#jstree').jstree({
- 'checkbox' : {
- // 選択された行に背景色をつけるか否か
- 'keep_selected_style' : true
- }
- 'plugins' : [ 'checkbox' ]
- });
- });
dnd(Drag and Drop)
JSFIDDLE:http://jsfiddle.net/53cvtbv9/1/
- $(document).ready(function(){
- $('#jstree').jstree({
- 'plugins' : [ 'search' ]
- });
- });
- <div><?php echo __('Search : '); ?><input type="text" class="search-input" /></div>
- <script>
- $(document).ready(function() {
- $(".search-input").keyup(function() {
- var searchString = $(this).val();
- $(selectorTree).jstree('search', searchString);
- });
- });
- <script>
単一ノード直下の重複チェック。
- $(document).ready(function(){
- $('#jstree').jstree({
- 'unique' : {
- // 大文字小文字の区別をするか否か
- 'case_sensitive' : false,
- // 重複した場合の名称を hoge -> hoge (2) のように変更する
- 'duplicate' : false,
- }
- 'plugins' : [ 'unique' ]
- });
- });
複数あるっぽい。
- $('#jstree').jstree('select_all'); // うまくいった
- $('#jstree').select_all(true); // 未試行
- // 選択系
- $('#jstree').jstree('select_all'); // 全選択
- $('#jstree').jstree('check_all'); // 全選択
- $('#jstree').jstree('deselect_all'); // 全選択解除
- $('#jstree').jstree('select_node', node.id); // 個別選択
- $('#jstree').jstree('deselect_node', node.id); // 個別選択解除
- // オープン系
- $('#jstree').jstree('open_all'); // 全開く
- $('#jstree').jstree('close_all'); // 全閉じる
- // 後はパターンで考えてましょう。。。
全部でないかもしれないけど、本体コード中に現れる this は
カスタマイズの際には $(selectorTree).jstree(true) に読みかえればよいかも?
本体の Ajax 通信を利用せずに、独自の通信ロジックにしたら
Loading 表示のやり方がわからなかった。
どこの例を見ても、’data’ : のところが、{ “id” : node.id } となっていて、それ以外のデータの渡し方がわからなかったから
当該ノードだけを更新するわけでなくて、ツリー全体を更新しているから
うまい例を見つけられなかったので、本体を見てみた。
- refresh : function (skip_loading, forget_state) {
- __snip__
- if(!skip_loading) {
- this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='treeitem' id='j"+this._id+"_loading'><i class='jstree-icon jstree-ocl'></i><"+"a class='jstree-anchor' href='#'><i class='jstree-icon jstree-themeicon-hidden'></i>" + this.get_string("Loading ...") + "</a></li></ul>");
- this.element.attr('aria-activedescendant','j'+this._id+'_loading');
- }
- __snip__
- }
どうやら、ここで表示しているらしい。
本体の HTML を一旦 Loading 用に書き換えちゃってるのね~。
それで、いくつか refresh メソッドを試してみたけど表示されなかった。
- $(selectorTree).jstree(true).trigger('refresh');
- // create で試したけど、当該ノードが消えただけ
- // refresh をかけたわけだから、create に前に戻るので当たり前
- $(selectorTree).jstree(true).refresh();
上記の HTML の内、わからないところとか、不必要と思われる箇所を少しだけ除いて
無理くり下記のようにしてみたら、ツリー全体を Loading 画像で置き換えることができた。
- var htmlLoading = '<ul class="jstree-container-ul jstree-children" role="group">'
- + '<li class="jstree-initial-node jstree-loading jstree-leaf jstree-last" role="tree-item">'
- + '<i class="jstree-icon jstree-ocl"></i>'
- + '<a class="jstree-anchor" href="#">'
- + '<i class="jstree-icon jstree-themeicon-hidden"></i>Loading ...'
- + '</a>'
- + '</li>'
- + '</ul>';
- $('#jstree').jstree(true).element.html(htmlLoading);
そのまんま。
読み込んだときの状態に戻す。
- $(selectorTree).jstree(true).refresh();
- $(selectorTree).jstree(true).refresh(false, false);
第1引数:skip_loading。Loading 表示をスキップするか否か
第2引数:forget_state。現状を記憶するか否か
株式会社アンフィニ 技術ブログ:【javascript】jQueryプラグイン jsTreeの紹介
海外製ライブラリ・Web API ドキュメントの翻訳ページ:jsTreeドキュメント日本語訳