YUI2.7.0のEditable Table(編集可能な表)で1クリックで行を削除する
YUI2.7.0のEditable Table(編集可能な表)について、バリデーションのコードを書いてきた。
バリデーションは、データの登録・更新に伴う処理。
今回は、
のような表を用意して、都道府県名の脇のマークをクリックしたら、行が削除される仕組みを作ってみる。このアイコンは、iconPodというありがたいサイトのものを使わせてもらった(Thank you so much)。サイトのトップに書かれているように、クレジットもバックリンクも不要、商用利用も可能でたくさんのアイコンが提供されている。
行の削除方法は、YUIのOfficial Examplesに紹介されていて、以前のログで取り上げた(これ)。
ポイントは以下。
- マークは、formatterとして都道府県名の脇に設定する。
- 行のクリックイベントが発生したら、その発生源(YUIではEventのTargetといわれる模様)がこのイメージであるか特定する。
- マークがクリックされていれば、行を削除する。
セルエディタ(Cell Editor)による更新と同様に、削除はYUI.widget.DataTableオブジェクト内で行われて永続化はされない。したがって、データベースやフラットファイルに永続化したい場合には、そのための実装が必要である。
また、行を削除するときに、確認用にコンファームすることがあるが、この例では行わない。以下が、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>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; } .actdel img { /* 都道府県に付ける「×(行削除)」イメージのスタイル */ border:0; margin-bottom: -3px; } </style> <script type="text/javascript" src="data.js"></script> <script type="text/javascript"> EzTable = function() { var myDataSource; var myDataTable; var Dom = YAHOO.util.Dom; var Event = YAHOO.util.Event; // MyValidatorオブジェクト var valObj; // 選択された行を保管 var wData; // 削除された行と行数を保管 var delRow; var delNum; /* * 都道府県に「×(行削除)」のマークを付ける * (注)カラム定義より前のこと */ var ezInitFormatter = function(elCell, oRecord, oColumn, oData) { elCell.innerHTML = oData + ' ' + ' ' + '<a class="actdel" href="#">' + '<img class="actdel" src="../images/action_delete.png">' + '</a>'; }; /* * メモ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; // 行データを退避 wData = Array(); for(var i in _rowData){ wData[i]=_rowData[i]; } // 選ばれた行の取得 var _rowIdx = this._oAnchorRecord._nCount; // 行を削除する関数 // (注) 削除するとmyDataTable.deleteRow()のインデックスがずれるので補正する。 var _corr = 0; for(var i=0; i<delRow.length; i++){ if(delRow[i]<_rowIdx) _corr++; } var _wk = _rowIdx-_corr; if(onClickDelete(oArgs, _wk)){ // 削除した行の保管 delRow[delNum++] = _rowIdx; } return; }; /* * クリック時に、選択された行を削除する */ var onClickDelete = function(oArgs, _rowIdx){ // イベントの発生が画面のクリックか判定する。 var _target = Event.getTarget(oArgs.event); var _targetClassName = getClassName(_target); var _idx = _targetClassName.indexOf('actdel',0) if(_idx != -1){ Event.preventDefault(oArgs.event); // oArgsから行を取り出して削除する。 myDataTable.deleteRow(_rowIdx); return true; } return false; }; /* * ダブルクリックイベントでエラーメッセージを消す */ var clearErrorMsg = function(){ Dom.get('ez_error_res').innerHTML = ''; return; }; /***************************************************** * 汎用関数 *****************************************************/ /** * クラス名の取得 */ var getClassName = function(_obj){ if(document.all){ //for IE var _keys = _obj.getAttribute('className'); }else{ // for FF, Chrome, Safari var _keys = _obj.getAttribute('class'); } return _keys; }; return { /** * 初期処理 */ init: function() { // DataTable用:列定義 var myColumnDefs = [ { key:"areacode", label:"コード", width:50, resizeable:true, sortable:true}, { key:"state", label:"都道府県", width:150, formatter:ezInitFormatter, // 上で定義したフォーマッターを適用する 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(); /* * 変数の初期化 */ delRow = new Array(); delNum = 0; }, // initの終わり oDS: myDataSource, oDT: myDataTable }; }(); </script> </head> <body class=" yui-skin-sam" onload="EzTable.init()"> test_datatable_validate5 <br> <div id="main"> <p>いくつかのオプションを加えたサンプルです。<br/> メモ1とメモ2はダブルクリックで変更できます。「メモ1<メモ2」という相関チェックを行います。<br> 都道府県名の右の<img src="../images/action_delete.png" style="margin-bottom:-3px;">をクリックすると、行を削除します。</p> <div id="ez_error_res" class="ez_error"></div> <div id="table1"></div> <div id="result"></div> </div> </body> </html>