TreeView Control: Inline Editing of TreeView Node Labels

このExample(ページへのリンクはこちら)は、タイトルにあるとおり、TreeViewのラベルを書き換えることのExampleだが、他に

  1. 特定ノードへフォーカスを当てる。
  2. EnterKeyのpress、マウスクリック、マウスダブルクリックのイベントハンドリング
  3. 「+」キーでの全展開、「-」キーでの全て閉じる

の例ともなっている。
Treeのラベルの書き換えは、ラベルのダブルクリックで行うようにされており、DateNode(初めて登場した)の場合には、カレンダーから日付をピックアップすることができる。

1は、初期画面時に上から2つ目のノードにフォーカスがあたるようにコードされている。

ラベルの編集は、ノードのeditable属性をtrueとするだけで可能となる。
このノードがTextノードの場合には、下のような編集画面が出てきて、更新後にチェック(保存)するか、「×」を押すことで、編集モードから戻ることができる。

ノードがDateNodeの場合には、下のようにDateピッカーが現れて、カレンダー上で日付を指定すれば、
それがラベルに編集される。カレンダーの書式(yyyy/mm/ddなど)は、コンフィグできる。
更新後にチェック(保存)するか、「×」を押すことで、編集モードから戻ることができるのは、テキストノードと同じ動きである。

2は、Keyのpressと、マウスのクリック・ダブルクリックのイベントハンドラを用意することで実現されているが、例では、その結果(xxxxがクリックされました、のようなメッセージがでる)が画面下部に出力されるようになっている。

3のキーバインドは特別な記述なしに利用可能であるようだ。

以下に、ソースコードの全文を示す。この例でも、scriptはmodule patternに書き直している。
また、カレンダーの形式は、日本式にyyyy/mm/ddとした。

<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>
<!-- この位置でないと、編集時のCalendarが出てこない -->
<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/calendar/assets/skins/sam/calendar.css" />
<link rel="stylesheet" type="text/css" href="scripts/yui/treeview/assets/skins/sam/treeview.css" />
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="scripts/yui/calendar/calendar-min.js"></script>
<script type="text/javascript" src="scripts/yui/treeview/treeview-min.js"></script>
 
<style type="text/css" id="defaultstyle">
#container {
	margin: 2px;
	padding: 3px;
	width: 300px;
	height: auto;
	border:1px dashed #999999;
}
#treeDiv1 {
	background: #fff; 
	padding:1em;
}
</style>

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

YAHOO.EGP.EditableTree = function() {
	var tree;
	var objlit=
		[
			'Label 0',
			{type:'Text', label:'Label 1', editable:true},
			{type:'Text', label:'Branch 2', editable:true, expanded:true, children:
      		[
      			{type:'Text', label:'Branch 2-0', editable:true, children: 
          		[
             		'Label 2-0-0',
             		'Label 2-0-1'
             	]},
         		{type:'Text', label:'Branch 2-1', editable:true, children: 
             	[
             		'Label 2-1-0',
             		'Label 2-1-1'
             	]},
              ]},
  			{type:'Text',label:'YAHOO', href:'http://www.yahoo.com', 
					target:'_self'},
	 		{type:'DateNode',label:'2008/11/8',editable:true, 
				 	calendarConfig: {
						DATE_FIELD_DELIMITER:"/",
						MDY_DAY_POSITION:3,
						MDY_MONTH_POSITION:2,
						MDY_YEAR_POSITION:1
	 		}},
  			{type:'Text',label:'Branch 3', editable:true, expanded:false, children:
      		[
       			'Label 3-0',
       			'Label 3-1'
      		]}
	];


    var buildTextNodeTree = function() {
	
		//treeのインスタンス化
		tree = new YAHOO.widget.TreeView("treeView", objlit);
		
		tree.draw();

		// ダブルクリックでノードが編集可能になる。
   		tree.subscribe('dblClickEvent',tree.onEventEditNode);

   		// トップレベルの2番目のノードにフォーカスを当てる。
   		tree.root.children[1].focus();
		                                  		
                // ノードEnter時のハンドラ。
  		tree.subscribe('enterKeyPressed',function(node) 
  		  		{
      			    YAHOO.util.Dom.get('msg').innerHTML 
      	     		    = 'Enter keyが' + node.label + 'で押されました。 ';
		        }
               );
               // ノードクリック時のハンドラ。
		tree.subscribe('clickEvent',function(oArgs) 
				{
		        	YAHOO.util.Dom.get('msg').innerHTML 
		        	    = oArgs.node.label +' がクリックされました。';
		        }
                );
               // ノードダブルクリック時のハンドラ。
		tree.subscribe('dblClickEvent',function(oArgs) 
				{
		        	YAHOO.util.Dom.get('msg').innerHTML 
		        	    = oArgs.node.label + 'がダブルクリックされました。'
		        }
               );
         };
	
         return{
              init: function() {
               buildTextNodeTree();
         }
    };
}();

//DOMが完全にloadされたら、サンプルを初期化する。
YAHOO.util.Event.onDOMReady(
		 //DomReadyイベントで発火するハンドラ
		YAHOO.EGP.EditableTree.init
);
</script>
</HEAD>

<!-- class=" yui-skin-sam"の指定が必要 -->
<BODY class=" yui-skin-sam">
<div id="container">
<p>
ラベルが編集できるTreeです。
</p>
<div id="treeView" style="background-color:white"></div>
<div id="msg">&nbsp;</div>
</div>
</BODY>
</HTML>