TreeView Control: Folder-Style TreeView Design

先の「Default TreeView」のところに書いたように、TreeViewは

  • treeview.css
  • treeview.js(もしくは、これを圧縮したtreeview-min.js)

を利用するのが、デフォルトの設定である。

この「Folder-Style TreeView Design」では、Default TreeviewのサンプルのCSSを変えて、エクスプローラ風のフォルダーアイコンで、Treeを表現している。

スクリプトの方は、Default TreeViewとほぼ同じであるが、Treeの枝(branch)を「全て開く(expand all)」、「全て閉じる(collapse all)」というアクションが紹介されている。これらは、TreeViewオブジェクトの持つメソッド

全て開く(expand all) expandAll()
全て閉じる(collapse all) collapseAll()

で簡単に行える。
TreeViewのAPIドキュメントはこちらを参照)

サンプリングは、「日本語化」と「logの書き出しをやめた」程度とした。
ノードを開くときと、閉じるときに発火する、expandイベントとcollapseイベントに、alertを上げるハンドラを、トップレベルの最初のノードにのみ設定した。この部分は、このサンプルには本質的ではないので、削除してもいいだろう。

まず、初期画面は以下のようになる。Exampleの通り、トップレベルのノードは、3個から7個の間で乱数で決定する。

ノードの階層は2階層で、2階層目は10個のノードを生成する。上で述べたように、トップレベルの最初のノードに下のようなalertを上げるハンドラを仕掛ける。

以下に、Javascriptを含むHTMLの全文を示す。Exampleのコードは、無名関数での処理となっているが、HTML内でのscriptの位置を変えるにあたって、module patternで書き直した。
また、ソース内に書いているが、ここで使うCSSとフォルダーアイコンは、YUIのダウンロードファイルのbuild下に無いので、ダウンロードファイルのexamples/treeview/assetsからcssとimgの2つのディレクトリをコピーしてくる必要がある。

<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" />

<!-- ダウンロードファイルのbuild下にはないので、examples/treeview/assets
             から cssフォルダーとimgフォルダーをとってくる。-->
<link rel="stylesheet" type="text/css" href="scripts/yui/treeview/assets/css/folders/tree.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">
//モジュールパターンで実装する。
YAHOO.namespace("EGP");

YAHOO.EGP.FolderTree = 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++) {
            // 子ノードの追加
            var tmpNode = 
                new YAHOO.widget.TextNode("label-" + i, tree.getRoot(), false);
			// tempNodeに10個の子要素をつける。
            buildLargeBranch(tmpNode);
        }

	// expandイベントは、テキストノードクリック時、ノード展開時に発火する。
	tree.subscribe("expand", function(node) {
	    if(node.index==1){
		alert("[index: "+node.index + ", label: " + node.label + 
       	   		"] was expanded");
	    }
       });

	// collapseイベントは、ノードを閉じた時に発火する。
        tree.subscribe("collapse", function(node) {
		if(node.index==1){
	       		alert("[index: "+node.index + ", label: " + node.label + 
                   	"] was collapsed");
			}
		});

        tree.draw();
    };

    // 引数のノードに10個の子ノードをつける。
    var buildLargeBranch = function (node) {
        if (node.depth < 10) {
            for ( var i = 0; i < 10; i++ ) {
                new YAHOO.widget.TextNode(node.label + 
                        				"-" + i, node, false);
            }
        }
    };
	
    return{
    	init: function() {
                // Treeの作成
        	buildRandomTextNodeTree();

        	//「全て開く」用のハンドラ設定
    		YAHOO.util.Event.on("expand", "click", function(e) {
			// aタグのデフォルトの動きを抑止して、全展開する。
    			YAHOO.util.Event.preventDefault(e);
				tree.expandAll();
    		});
    		
        	//「全て閉じる」用のハンドラ設定
    		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.FolderTree.init,
	//ハンドラに渡すオブジェクト(関数)
	YAHOO.EGP.FolderTree,
	//ハンドラは、上記のオブジェクトのスコープをもつ。   
	true
);
</script>
</HEAD>

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