JSONデータを使って動的にツリーを作成する

概要

YUI 2 — Yahoo! User Interface Library」を使います。
YUI2のIndex of Official Examplesに掲載されている「TreeView Control: Dynamically Loading Node Data」を編集して使います。

ライブラリを読み込む

HEADタグの中に貼り付ける。

<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/treeview/assets/skins/sam/treeview.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>

<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/connection/connection-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/treeview/treeview-min.js"></script>

とりあえず動かす

動作例のページ(Dynamically Loading Node Data)のソースを見て、[<!--BEGIN ]と[<!--END]で囲われている箇所をコピーペーストする。

カスタマイズ:自分で作ったデータを表示する

例のスクリプトが読み込んでいるJSON形式と同じ形式のJSONを作成する。

例のスクリプト内で使っているPHPに適当な値を渡して形式を確認すると次の通り。

#http://developer.yahoo.com/yui/examples/treeview/assets/ysuggest_proxy.php?query=example

{"ResultSet":
  {"Result":
    ["resume example","cover letter example","annotated bibliography example","mla format bibliography example","swot analysis example","letter of recommendation example","example mission statement","free example resumes online","resignation letter example","persuasive essay example"]
  }
}

カスタマイズ:複数のデータを渡す

受け取る側
if((oResults.ResultSet.Result) && (oResults.ResultSet.Result.length)) {
    //Result is an array if more than one result, string otherwise
    if(YAHOO.lang.isArray(oResults.ResultSet.Result)) {
        for (var i=0, j=oResults.ResultSet.Result.length; i<j; i++) {
            // edit this line.
            var tempNode = new YAHOO.widget.TextNode({label:oResults.ResultSet.Result[i][2],title:oResults.ResultSet.Result[i][1]},node, false);
            tempNode.isLeaf = true;
        }
    } else {
        //there is only one result; comes as string:
        var tempNode = new YAHOO.widget.TextNode(oResults.ResultSet.Result, node, false)
    }
}

ResultSet.Result[i][2]を編集する。

送る側

Pythonの例

class ListHandler(tornado.web.RequestHandler):
    def get(self,name):
        import json # import JSON module.
        tbl = name +'.tbl'
        list = db.select(tbl,['recno'],['*'])
        #list is dic object
        ret = {'Result':list}
        data = {'ResultSet':ret}
        self.write(json.JSONEncoder().encode(data))

カスタマイズ:ボタンでデータを更新する

例として使っているスクリプトは「+」ボタンが押されたらJSONデータを読みに行ってツリーを構築するように作成されている。
そこで、監視する先を追加してそのボタンが押されたときも更新するようにする。

return {
    init: function() {
        YAHOO.util.Event.on(["mode0", "mode1"], "click", changeIconMode);

        //add this line
        YAHOO.util.Event.on(["reload_button"], "click", changeIconMode);

        var el = document.getElementById("mode1");
        if (el && el.checked) {
            currentIconMode = parseInt(el.value);
        } else {
            currentIconMode = 0;
        }
        buildTree();
    }
<input type="submit" id="reload_button">

reload_buttonというidのボタンを作って、上記のようにコードを追加する。

カスタマイズ:階層を1階層に固定する

if((oResults.ResultSet.Result) && (oResults.ResultSet.Result.length)) {
    //Result is an array if more than one result, string otherwise
    if(YAHOO.lang.isArray(oResults.ResultSet.Result)) {
        for (var i=0, j=oResults.ResultSet.Result.length; i<j; i++) {
            var tempNode = new YAHOO.widget.TextNode({label:oResults.ResultSet.Result[i][2],title:oResults.ResultSet.Result[i][1]},node, false);
	    //all node is Leaf
            tempNode.isLeaf = true;
        }
    } else {
        //there is only one result; comes as string:
        var tempNode = new YAHOO.widget.TextNode(oResults.ResultSet.Result, node, false)
    }
}

カスタマイズ:ラベルをクリックしたときの動作を指定する

//render tree with these toplevel nodes; all descendants of these nodes
//will be generated as needed by the dynamic loader.
tree.draw();

//add this line.
tree.subscribe('labelClick',function(node){javascript:alert(node);});

こんな感じ。