DataTable Control: Adding and Deleting Rows
このExampleでは、ボタンのクリックでテーブルの行を増減させる方法が示されている。
初期画面は以下。
YUIのExampleでは、テーブルの行が0の時(テーブルが空の時)、「No records found.」と表示されるが、これを「データがありません」という日本語に変えてみた。これは、DataTableのコンフィグ属性のMSG_EMPTYを設定すればよい(詳しくは、添付のソースコードと、YAHOO.widget.DataTableのAPIドキュメントのConfiguration Attributesを参照)。
以下が、20行を追加し、最初の1行を削除した時の画面である。
データを追加するときに注意すべき点は、DataTableの属性SortedByを無効化することである。
DataTableは「画面に表示されている値を元にソートを行っているわけではない」らしく、これを無効化しておかないと、降順にソートされた状態でデータを追加すると、その順番が固定されてしまう(たとえば、rowが1-20の20のデータを降順に20-1と並べた状態でデータを1つ追加すると、20-1,21というテーブルができる。これを、昇順にしたときに21,1-20となってしまう)。
この例では、降順にソートされている場合だけ、ソートの無効化を行っているが、データを追加するときの定石と考えておいた方がよさそうだ(データを追加するときにはソートは無効にする)。
以下に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/button/assets/skins/sam/button.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/element/element-beta-min.js"></script> <script type="text/javascript" src="scripts/yui/button/button-min.js"></script> <script type="text/javascript" src="scripts/yui/dragdrop/dragdrop-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; } #buttons { margin-bottom: 1em; } </style> <script type="text/javascript"> YAHOO.util.Event.addListener(window, "load", function() { YAHOO.example.ADD_DELETE_ROW = function() { var data = {one:"one",two:"two",three:"three"}; var myColumnDefs = [ {key:"row",resizeable:true,sortable:true}, {key:"one",resizeable:true}, {key:"two",resizeable:true}, {key:"three",resizeable:true} ]; var myDataSource = new YAHOO.util.DataSource([]); myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; myDataSource.responseSchema = { fields: ["one","two","three"] }; var myDataTable = new YAHOO.widget.DataTable("basic", myColumnDefs, myDataSource, {MSG_EMPTY:"データがありません"}); // iで行を保管する。 var i=1, bReverseSorted = false; // Track when Column is reverse-sorted, since new data will come in out of order // sorrableは"row"カラムにしか設定していない。 // columnSortEventにハンドラを仕掛けて、rowの降順にソートされたら、bReverseSortedにtrueを設定する。 var trackReverseSorts = function(oArg) { bReverseSorted = (oArg.dir === YAHOO.widget.DataTable.CLASS_DESC); }; myDataTable.subscribe("columnSortEvent", trackReverseSorts); // 1行追加ボタンの生成と、クリックイベントハンドラの定義 var btnAddRow = new YAHOO.widget.Button("addrow"); btnAddRow.on("click", function() { // Clear sort when necessary // 降順にソートされていたら、いったんソートを無効にする。 // 無効にしないと、追加された行が、「次に昇順にしたときに」先頭に来てしまう。 if(bReverseSorted) { myDataTable.set("sortedBy", null); } // データ配列からレコードオブジェクトを作成し、総行数(i)をインクリメントして、rowフィールドにセット後 // DataTableに追加する。 var record = YAHOO.widget.DataTable._cloneObject(data); record.row = i++; myDataTable.addRow(record); },this,true); // 20行追加ボタンの生成と、クリックイベントハンドラの定義 var btnAddRows = new YAHOO.widget.Button("addrows"); btnAddRows.on("click", function(e) { // Clear sort when necessary // 降順にソートされていたら、いったんソートを無効にする。 // 無効にしないと、追加された行が、「次に昇順にしたときに」先頭に来てしまう。 if(bReverseSorted) { myDataTable.set("sortedBy", null); } // データ配列からレコードオブジェクトを作成し、総行数(i)をインクリメントして、rowフィールドにセット後 // 配列に追加するという作業を20回繰り返す。その後、その配列をDataTableに追加する。 var myArray = []; for(var l=i;i<=l+19;i++) { var record = YAHOO.widget.DataTable._cloneObject(data); record.row = i; myArray.push(record); } myDataTable.addRows(myArray); },this,true); // 1行削除ボタンの生成と、クリックイベントハンドラの定義 var btnDeleteRow = new YAHOO.widget.Button("deleterow"); btnDeleteRow.on("click", function() { // データテーブルが空でないことを確かめて、最初の1行を削除する。 if(myDataTable.getRecordSet().getLength() > 0) { myDataTable.deleteRow(0); } },this,true); // 20行削除ボタンの生成と、クリックイベントハンドラの定義 var btnDeleteRows = new YAHOO.widget.Button("deleterows"); btnDeleteRows.on("click", function() { var length = myDataTable.getRecordSet().getLength(); if(length > 0) { var count = (length > 19) ? 20 : length; myDataTable.deleteRows(0,count); } },this,true); return { oDS: myDataSource, oDT: myDataTable }; }(); }); </script> </head> <body class=" yui-skin-sam"> <div id="main"> <p>Dynamicに行を増減させます。</p> <div id="buttons"> <span id="addrow" class="yui-button yui-push-button"> <span class="first-child"> <button type="button">1行追加</button> </span> </span> <span id="deleterow" class="yui-button yui-push-button"> <span class="first-child"> <button type="button">最初の1行を削除</button> </span> </span> <span id="addrows" class="yui-button yui-push-button"> <span class="first-child"> <button type="button">20行追加</button> </span> </span> <span id="deleterows" class="yui-button yui-push-button"> <span class="first-child"> <button type="button" name="button5">最初の20行を削除</button> </span> </span> </div> <div id="basic"></div> </div> </body> </html>