YUI2.7.0のEditable Table(編集可能な表)でのバリデーション(その3:相関チェックをする)
先のログで、DataTableのセルエディタ(Cell Editor)についてバリデータを自作してみた。ここで一点気になるのが、表の同一行内の値との「相関チェック」をどうするか?ということ。先のログのバリデーションでは、「そのセルの値」のみがチェックの対象。これでは不十分だ。
ということで、相関チェックを実装してみた。
戦略は以下。
- (セルエディタを開くための)ダブルクリックに先んじて、クリックイベントで選択された行の(表内に保管されている)データを保管する。
- セルエディタのバリデーション内で、保管した「行データ」を相関チェックを行う。
したがって、セルエディタのバリデーションロジックの中には、
- そのセルの入力値の(簡単な)妥当性検証
- そのセルの入力値と、同一行内にあるデータとの相関チェック
が入る(必要であれば、サーバーサイドでの非同期でのチェックも入る)。
前者には、以前に作成したMyValidatorが使えるので、それを使うことにしよう。
まず、これまでのサンプルを変更して、以下のように編集可能な列を2つにする。これらに以下のような制約をつけてみる。
- 2列ともに、数値(int,float)のみ入力
- メモ2の入力値 > メモ1の入力値
単純化のため、メモ1の入力値には、defaultValue:0と、validator:YAHOO.widget.DataTable.validateNumberを設定し、メモ2の入力値のバリデーションを自作した。以下の2つは、メモ2に「数値以外」を入力したときのスナップショットである。
「ああああ」を入力すると、
以下のようにバリデーションがかかって、セルエディタが再度の入力を要求する。
以下のスナップショットは、メモ1の値(10)に対して、メモ2に"5"を入力した際のスナップショットである。同様にバリデーションがかかって、セルエディタが再度の入力を促す。
以下にHTMLの全文を示す。validateNotes2()が、メモ2の相関チェックをしている関数である。
<!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>DataTable Validate</title> <style type="text/css"> </style> <link rel="stylesheet" type="text/css" href="../scripts/lib/yui/build/fonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="../scripts/lib/yui/build/paginator/assets/skins/sam/paginator.css" /> <link rel="stylesheet" type="text/css" href="../scripts/lib/yui/build/datatable/assets/skins/sam/datatable.css" /> <script type="text/javascript" src="../scripts/lib/yui/build/yahoo-dom-event/yahoo-dom-event.js"></script> <script type="text/javascript" src="../scripts/lib/yui/build/animation/animation.js"></script> <script type="text/javascript" src="../scripts/lib/yui/build/element/element.js"></script> <script type="text/javascript" src="../scripts/lib/yui/build/paginator/paginator-min.js"></script> <script type="text/javascript" src="../scripts/lib/yui/build/datasource/datasource-min.js"></script> <script type="text/javascript" src="../scripts/lib/yui/build/datatable/datatable-min.js"></script> <!--// MyValidatorの読み込み --> <script type="text/javascript" src="../scripts/myznala.js"> </script> <style type="text/css" id="defaultstyle"> #main { margin: 2px; padding: 3px; } .ez_error { /* red(エラー用) */ color:#ff0000; } </style> <script type="text/javascript" src="data.js"></script> <script type="text/javascript"> EzTable = function() { var myDataSource; var myDataTable; var Dom = YAHOO.util.Dom; // MyValidatorオブジェクト var valObj; // 選択された行を保管 var wData; /* * メモ2のバリデーション */ var validateNotes2 = function(oData){ // エラーメッセージのクリア clearErrorMsg(); // MyValidatorをつかって数値チェックをする。 var _ret = valObj.validate('ja','isNum',oData); if(_ret['isNum']!=null &&_ret['isNum'].length > 0){ Dom.get('ez_error_res').innerHTML = _ret['isNum']; return undefined; } /* * 以下、相関チェック */ // 数値化 var _numData = 1 * oData; if("notes1" in wData){ var _savData = 1 * wData["notes1"]; }else{ var _savData = 0; } // 相関チェック if(_savData >= _numData){ // エラーの場合、undefindを返せばいい。 Dom.get('ez_error_res').innerHTML = 'メモ2>メモ1でなければなりません。'; return undefined; } return oData; }; /* * クリックイベントで行データを退避する */ var onRowClick = function(oArgs){ // 選ばれた行のデータ var _rowData = this._oAnchorRecord._oData; // 以下の方法でRowのデータが取り出せる。 wData = Array(); for(var i in _rowData){ wData[i]=_rowData[i]; } return; }; /* * ダブルクリックイベントでエラーメッセージを消す */ var clearErrorMsg = function(){ Dom.get('ez_error_res').innerHTML = ''; return; }; return { /** * 初期処理 */ init: function() { // DataTable用:列定義 var myColumnDefs = [ { key:"areacode", label:"コード", width:50, resizeable:true, sortable:true}, { key:"state", label:"都道府県", width:150, resizeable:true, sortable:true}, { key:"notes1", label:"メモ1 (編集可:数値)", editor:new YAHOO.widget.TextboxCellEditor( { validator:YAHOO.widget.DataTable.validateNumber, defaultValue:0 } ), resizeable:true, sortable:true}, { key:"notes2", label:"メモ 2(編集可:数値)", editor:new YAHOO.widget.TextboxCellEditor( { validator:validateNotes2, defaultValue:0 } ), resizeable:true, sortable:true} ]; // DataTable用:コンフィグ属性 var myConfigs = { sortedBy:{key:"areacode",dir:"asc"}, paginator: new YAHOO.widget.Paginator({ rowsPerPage: 10, template: YAHOO.widget.Paginator.TEMPLATE_ROWS_PER_PAGE, rowsPerPageOptions: [10,25,50,100], pageLinks: 5 }), caption:"都道府県" }; // DataSourceのインスタンス化 myDataSource = new YAHOO.util.DataSource(Data.areacodes); myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; myDataSource.responseSchema = { fields: ["areacode","state"] }; // DataTableのインスタンス化 myDataTable = new YAHOO.widget.DataTable("table1", myColumnDefs, myDataSource, myConfigs); /* * 行の選択補助。 */ // クリックでハイライトするようにハンドラを設定 myDataTable.subscribe("rowClickEvent", myDataTable.onEventSelectRow); myDataTable.subscribe("rowMouseoverEvent", myDataTable.onEventHighlightRow); myDataTable.subscribe("rowMouseoutEvent", myDataTable.onEventUnhighlightRow); // クリック時にデータを退避する。 myDataTable.subscribe("rowClickEvent", onRowClick); /* * セルの処理 */ // ダブルクリックでエラーメッセージを消す。 myDataTable.subscribe("cellDblclickEvent", clearErrorMsg); // ダブルクリックでセルのエディターを呼ぶ。 myDataTable.subscribe("cellDblclickEvent", myDataTable.onEventShowCellEditor); /* * MyValidatorの初期化 */ valObj = new MyValidator(); }, // initの終わり oDS: myDataSource, oDT: myDataTable }; }(); </script> </head> <body class=" yui-skin-sam" onload="EzTable.init()"> test_datatable_validate4 <br> <div id="main"> <p>いくつかのオプションを加えたサンプルです。<br/> メモ1とメモ2はダブルクリックで変更できます。「メモ1<メモ2」という相関チェックを行います。</p> <div id="ez_error_res" class="ez_error"></div> <div id="table1"></div> <div id="result"></div> </div> </body> </html>