DataTable Control: Inline Cell Editing

このExampleは、触っていて面白い。
「テーブルのセルをブラウザー上で編集しましょう」という例なのだが、こういうのを触っていると、Ajaxだなぁ、という気になる。

編集方法もいろいろ。
以下は、デイト・ピッカー(Date Picker; Calendar)を表示した画面。日付を選んで、セーブすると画面の日付が変わる(画面はyyyy/mm/ddの形式に変更してある)

以下は、読み込んだJSONデータから表示するリスト・ボックス。
この場合は、選択=更新(Save)となる。

あとは、ソースコードをみた方が早いが、validatorやらなんやらまで組み込んでいる。

YUIのExampleだと画面を変更してもアクションが起きないので、サンプリングでは、セルの更新をハンドリングして以下のようなアラートをあげるようにした。
これで、実データをSaveするときは、これにならえばよい。

以下にJavaScriptを含むHTMLの全文を示す。このような画面が、とても簡単に作れることがわかる。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title>Ajax Sample</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/calendar/assets/skins/sam/calendar.css" /> 
<link rel="stylesheet" type="text/css" href="scripts/yui/datatable/assets/skins/sam/datatable.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/element/element-beta-min.js"></script> 
<script type="text/javascript" src="scripts/yui/datasource/datasource-min.js"></script> 
<script type="text/javascript" src="scripts/yui/datatable/datatable-min.js"></script> 

<style type="text/css" id="defaultstyle">
#main {
	margin: 2px;
	padding: 3px;
}
/* custom styles for this example */
.yui-skin-sam .yui-dt-col-address pre { font-family:arial;font-size:100%; } 
/* Use PRE in first col to preserve linebreaks*/
</style>

<script type="text/javascript" src="scripts/yui/datatable/assets/js/data.js"></script> 
<script type="text/javascript"> 
YAHOO.util.Event.addListener(window, "load", function() {
	
	YAHOO.example.InlineCellEditing = function() {
        // Custom formatter for "address" column to preserve line breaks
        var formatAddress = function(elCell, oRecord, oColumn, oData) {
            elCell.innerHTML = "<pre class=\"address\">" + oData + "</pre>";
        };

        var myColumnDefs = [
                {key:"uneditable",label:"編集不可"},
                {key:"address", 
                    formatter:formatAddress, 
                    // Resizableな編集フィールドがでる。
                    editor: new YAHOO.widget.TextareaCellEditor()},
                {key:"city", 
                    // Resizableでもなく、ボタンもない編集フィールドがでる。
                    editor: new YAHOO.widget.TextboxCellEditor(
                            {	disableBtns:true}
                    )},
                {key:"state", 
                    editor: new YAHOO.widget.DropdownCellEditor(
					// リストボックス(ボタンなし)
                    		{dropdownOptions:YAHOO.example.Data.stateAbbrs,
                                disableBtns:true}
                   )},
                {key:"amount", 
                    editor: new YAHOO.widget.TextboxCellEditor(
  					// リストボックス(数字以外は入らない)
                            {validator:YAHOO.widget.DataTable.validateNumber}
                   )},
                {key:"active", 
                    editor: new YAHOO.widget.RadioCellEditor(
  					// ラジオボタン
                            {radioOptions:["yes","no","maybe"],
                                disableBtns:true}
                  )},
                {key:"colors", 
                   editor: new YAHOO.widget.CheckboxCellEditor(
   					// チェックボタン
                           {checkboxOptions:["red","yellow","blue"]}
                  )},
                {key:"last_login", 
                   		  formatter:YAHOO.widget.DataTable.formatDate, 
  					// Dateピッカー
                        editor: new YAHOO.widget.DateCellEditor()}
       	];

        var myDataSource = new YAHOO.util.DataSource(YAHOO.example.Data.addresses);
        myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
        myDataSource.responseSchema = {
            fields: ["address","city","state","amount","active","colors",{key:"last_login",parser:"date"}]
        };
 
        var myDataTable = new YAHOO.widget.DataTable("cellediting", 
                myColumnDefs, 
                myDataSource, 
                {dateOptions:{format:"%Y/%m/%d", locale:"ja"}}
        );

        // Set up editing flow
        var highlightEditableCell = function(oArgs) {
            var elCell = oArgs.target;
            if(YAHOO.util.Dom.hasClass(elCell, "yui-dt-editable")) {
                this.highlightCell(elCell);
            }
        };
        myDataTable.subscribe("cellMouseoverEvent", 
                highlightEditableCell);
        myDataTable.subscribe("cellMouseoutEvent", 
                myDataTable.onEventUnhighlightCell);
        // クリックすると編集モードとなる。
        myDataTable.subscribe("cellClickEvent", 
                myDataTable.onEventShowCellEditor);

		// Cell更新時のハンドラー
        var hdlUpdateCell = function(oArgs) {
            var upRecord = oArgs.record;
            var upColumn = oArgs.column;
            var upOldData = oArgs.oldData;
            var upKey = upColumn.key;
			var colNum = upRecord._nCount+1;
			var oldData = upOldData[upKey];
			var newData = upRecord.getData(upKey);
			// DatePickerでは、oldDataがnullオブジェクト={}となってしまう。
			alert(colNum+"行目の"+upKey+"が"+oldData+
					"から"+newData+"に変更されました");
        };
		// Cell更新時のイベントとハンドラ定義
        myDataTable.subscribe("cellUpdateEvent", 
        		hdlUpdateCell);
        
        return {
            oDS: myDataSource,
            oDT: myDataTable
       };
    }();
});
</script>
</head> 
 
<body class=" yui-skin-sam">
<div id="main">
<p>クリックをするとセルが編集モードになります</p>
<div id="cellediting"></div></div>
</body> 
</html>