TreeView Control: Menu-Style TreeView Design

これまでの例では、テキストノード(YAHOO.widget.TextNode)だけを使っていたが、この「Menu-Style TreeView Design」はメニューノード(YAHOO.widget.MenuNode)を使うサンプルである。(YAHOO.widget.MenuNodeのAPIドキュメントはこちらを参照)

メニューノードとテキストノードの違いは、「ひとつの枝(Branch)を開くと、他の枝が閉じること(※)」である。このアクションは、YAHOO.widget.MenuNodeをつかって、Treeを生成した際に自動的に付与される。

Exapleのページに書かれているように、この性質でtreeのheightを特定の大きさに制限することが可能になるだろう。

したがって、scriptのコーディングは、テキストノードの際と変わらず行うことができる。

サンプルは、先の「Folder-Style TreeView Design」と殆どかわらないが、上の※の性質から、おのずと「全て開く」というアクションは存在せず、「全て閉じる」だけの実装となっている。
また、branchの生成を行う関数(buildRandomTextBranch)が再帰呼び出しを行うようにコードされており、最大で6階層までのメニューを乱数にしたがって生成する。

サンプリングしたコードの初期画面は以下。

下は、これを展開したときの画面である。

以下に、Javascriptを含むHTMLの全文を示す。Exampleのコードは、無名関数での処理となっているが、HTML内でのscriptの位置を変えるにあたって、module patternで書き直した。

<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Ajax_Sampling</TITLE>
<style type="text/css">
body {
	margin:0;
	padding:0;
}
</style>
<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/treeview/assets/skins/sam/treeview.css" />

<link rel="stylesheet" type="text/css" href="scripts/yui/treeview/assets/treeview-menu.css" />

<style type="text/css" id="defaultstyle">
#container {
	margin: 2px;
	padding: 3px;
	width: 300px;
	height: auto;
	border:1px dashed #999999;
}

#expandcontractdiv {
	border:1px dotted #dedede; 
	background-color:#EBE4F2; 
	margin:0 0 .5em 0; 
	padding:0.4em;
}

#treeDiv1 { 
	background: #fff; 
	padding:1em; 
	margin-top:1em; 
}
</style>

<!-- 読み込むjs --> 
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js" ></script> 
<script type="text/javascript" src="scripts/yui/treeview/treeview-min.js" ></script>

<script type="text/javascript">
//alert("init");
//モジュールパターンで実装する。
YAHOO.namespace("EGP");

YAHOO.EGP.MenuTree = function() {
	var tree;

        var buildRandomTextNodeTree = function() {
	
	//treeのインスタンス化
        tree = new YAHOO.widget.TreeView("treeDiv1");

	// Math.floor((Math.random()*4) + 3)
	// [0,1]の乱数×4+3=[0,3.9999]+3=[3,6.9999]
	// [3,6.99999]の切捨て=[3,6]の整数
	// 1から7子の子ノードをrootに追加する。
        for (var i = 0; i < Math.floor((Math.random()*4) + 3); i++) {
            // 子ノードの追加(TextNodeからMenuNodeに変えるだけ)
            var tmpNode = 
                new YAHOO.widget.MenuNode("label-" + i, tree.getRoot(), false);
	    // tempNodeに10個の子要素をつける。
            buildRandomTextBranch(tmpNode);
        }

        tree.draw();
    };

    // 6階層までメニューを作る(再帰呼び出し)。
    // 各階層は0個から5個の間でランダムに生成する。
    function buildRandomTextBranch(node) {
    if (node.depth < 6) {
	  YAHOO.log("buildRandomTextBranch: " + node.index);
		for ( var i = 0; i < Math.floor(Math.random() * 4) ; i++ ) {
			var tmpNode 
                                = new YAHOO.widget.MenuNode(node.label + 
                                                    "-" + i, node, false);
			buildRandomTextBranch(tmpNode);
		}
	}
    }
	
    return{
    	init: function() {
       	     buildRandomTextNodeTree();

	    //「全て閉じる」のイベントと、ハンドラ定義。
    	    YAHOO.util.Event.on("collapse", "click", function(e) {
	        // aタグのデフォルトの動きを抑止して、全て閉じる。
    	        YAHOO.util.Event.preventDefault(e);
    	       tree.collapseAll();
    	    });
        }
    };
}();

//DOMが完全にloadされたら、サンプルを初期化する。
YAHOO.util.Event.onDOMReady(
	 //DomReadyイベントで発火するハンドラ
	YAHOO.EGP.MenuTree.init,
	//ハンドラに渡すオブジェクト(関数)
	YAHOO.EGP.MenuTree,
	//ハンドラは、上記のオブジェクトのスコープをもつ。   
	true
);
</script>
</HEAD>

<!-- class=" yui-skin-sam"の指定が必要 -->
<BODY class=" yui-skin-sam">
<div id="container">
<div id="expandcontractdiv">
	<a id="collapse" href="#">全て閉じる</a>
</div>
<p>
親ノードは、乱数で3から7個生成しています。<br/>
子ノードも乱数により、0個から5個まで生成しています。<br/>
ラベルをクリックすると、viewが開閉します。また、「全て閉じる」で全てのノードが閉じます。
</p>
	<div id="treeDiv1"></div>
</div>
</BODY>
</HTML>