JavaScriptでテーブルを操作する
テーブルを操作するプロパティやらメソッド。-1がデフォルトで最後の行。
命令 | プロパティ | メソッド | オブジェクト |
---|---|---|---|
列の取得 | rows | table,thead,tbody,tfoot | |
セルの取得 | cells | tr,th,rows[i] | |
列の追加 | insertRow | table,thead,tbody,tfoot | |
セルの追加 | insertCell | tr,th,rows[i] | |
列の削除 | deleteRow | table,thead,tbody,tfoot | |
セルの削除 | deleteCell | tr,th,rows[i] | |
セルの番号取得 | cellIndex | td,cells[i] | |
テーブル全体での列の番号取得 | rowIndex | table | |
列の番号取得 | sectionRowIndex | tr,th,row[i] |
cellIndexでは、同じ列のセルは同じ番号が振られる。
0 1 2
0 1 2
columnが列、rowが行という意味らしいが、日本語で考えたら横の行がcolumnで、縦の列がrowですから上手く整理しないとごちゃごちゃになります。
rowIndexとsectionRowIndexは、特定のtrとかの列番号を返すのは同じだけど、テーブル全体から数えて何番目か、そのtrのセクション(thead,tfoot,tbody)タグから数えて何番目かの違い。
テーブル追加・削除サンプルを読み解く
こちらのページで紹介されているスクリプトを考えて見ます。
<table id="sample" border="1"> <thead id="samplethead"> <tr> <th>名前A</th> <th>名前B</th> <th>名前C</th> </tr> </thead> <tbody id="sampleTbodyA"> <tr> <td>1行目1列目</td> <td>1行目2列目</td> <td>1行目3列目</td> </tr> </tbody> <tbody id="sampleTbodyB"> <tr> <td>2行目1列目</td> <td>2行目2列目</td> <td>2行目3列目</td> </tr> <tr> <td>3行目1列目</td> <td>3行目2列目</td> <td>3行目3列目</td> </tr> </tbody> </table>
このサンプルスクリプトではsrcElementを使用しているので、Firefoxでは動きません。そこで、Firefoxに対応させるためのイベントリスナを先に実行しておきます。
//srcElementをtargetに関連付ける if (window.addEventListener){ //IE以外に適用(IE8以下はattachEvent) window.addEventListener("click",function(e){ //クリックイベントが起こったら window.event = e; //発火したイベントはwindow.eventと同じ window.event.srcElement = e.target; //firefox用のイベントを起した要素を、非対応のwindow.event.srcElementに対応させる。 },true); //trueはキャプチャーフェーズでIEだけ非対応 }
function sample(){ var bt = window.event.srcElement;//この場合押されたボタンのinput要素 if(bt.nodeName != 'INPUT') return;//ボタン以外(inputでなければ)なら抜け出す //if(bt.parentNode.cellIndex>0) return;//押されたボタンのinputの親のtd、thのcellが1以上(+ーのボタンでなければ)なら抜け出す var tr = bt.parentNode.parentNode;//押されたボタンのinputの親の親すなわちtr //var thF = (tr.parentNode.nodeName == 'THEAD');//trの親の要素はthead→題名欄thの親を指定 var tbod = tr.parentNode; //var tbod = (thF)?tr.parentNode.parentNode.tBodies[0]:tr.parentNode;//theadならtbod=tBodies[0]、tbodyならtbod=押されたボタンの属するtbody if(bt.value == '削除'){//マイナスボタンなら //if(thF)return; /*if(tbod.rows.length<1){ alert("こんなことないけどエラーだよ"); return; }*/ tbod.deleteRow(tr.sectionRowIndex);//sectionRowIndexはtrのtbodyから数えて何番目か。 } }
変数btに値を代入。もしbt.event.srcElement(クリックイベントが起こったinput要素)のノード名が、inputじゃなかったら、undefinedを返す。function内だからforとかのようなbreakとはちょっと違う。
もしbt.bt.parentNode.cellIndex>1(inputの親であるtdのセル番号が1より大きい=+とーボタンが入ったセル行でない)ならreturn。
変数trにイベントが起こったinputの親(td)の親(tr)を代入。その変数trの親(theadかtbody)のノード名がtheadという比較文自体をthFという変数に代入。
tbodという変数に、P=A?B:C;(PはAが真ならB、偽ならC文)を利用して、theadつまり1行目だったら、tbodはtrの親(thead)の親(table)の最初のtbodyまでを代入、違う(tbodyだった)なら、trの親(tbody)までを代入。
var newt = document.getElementById("sample").tBodies[0];//tbodyがなければtableの最後の行 var newtr = newt.insertRow(-1);//引数:新しい行の行番号( 0 が一行目)index に -1 または行数に等しい場合、行は最後の行として追加される。 var newtd0 = newtr.insertCell(0); var newtd1 = newtr.insertCell(1);//row、th、trオブジェクトのメソッド var newtd2 = newtr.insertCell(2); var newtd3 = newtr.insertCell(3); var newtd4 = newtr.insertCell(4); var newtd5 = newtr.insertCell(5); var newtd6 = newtr.insertCell(6); var newtd7 = newtr.insertCell(7); var newtd8 = newtr.insertCell(8); newtd0.innerHTML = ""; newtd1.innerHTML = "1"; newtd2.innerHTML = "2"; newtd3.innerHTML = "3"; newtd4.innerHTML = "4"; newtd5.innerHTML = "5"; newtd6.innerHTML = "6"; newtd7.innerHTML = "7"; newtd8.innerHTML = "8"; */
DOMで行を追加するtbodyを選んで、insertRow()で追加する。これを変数にいれるんで、それ以下のinsertCell()は、その追加した行に対して追加される。
以下の様な形にすると、行がその都度追加されてしまって、追加したセルが横一列に並ばない。同じindex番号のセルは縦並びになる。
var newt = document.getElementById("sample").tBodies[0];//tbodyがなければtableの最後の行 newt.insertRow(-1).insertCell(0).innerHTML = ""; newt.insertRow(-1).insertCell(0).innerHTML = "1"; newt.insertRow(-1).insertCell(1).innerHTML = "1"; newt.insertRow(-1).insertCell(2).innerHTML = "2"; newt.insertRow(-1).insertCell(3).innerHTML = "3"; newt.insertRow(-1).insertCell(4).innerHTML = "4"; newt.insertRow(-1).insertCell(5).innerHTML = "5"; newt.insertRow(-1).insertCell(6).innerHTML = "6"; newt.insertRow(-1).insertCell(7).innerHTML = "7"; newt.insertRow(-1).insertCell(8).innerHTML = "8";
テーブルにセル追加、削除のスクリプトはこれでいいと思われる。
function clrow(o){ var inp = o.getElementsByTagName('input'); for(var i=0;inp[i];i++){ if(inp[i].type == 'text') { inp[i].value = inp[i].defaultValue; } } }
とばして、clrow関数の宣言。inp変数に引数(2行目)のinputを代入。その行のinputは+と-とテキストフィールドの3つある。<
for文にて、inputを1個ずつ探して、typeがtextのものが見つかったら、そのvalueをdefaultvalueにする。最後の1行を削除しようとすると内容(input)のクリアだけ行われるための命令。
if(bt.value == '-'){ if(thF)return; if(tbod.rows.length<2){ clrow(tbod.rows[0]); return; } tbod.deleteRow(tr.sectionRowIndex);
もし選択されたinputのvalueがマイナスなら、もし親がtheadならundefiend、もしtbodyの行が2よりも小さいなら、clrowが実行されて内容だけがクリアされる。
それ以外なら、tbodyの(押されたinputのtrの行の番号)がdeleterowで行削除される。
} else { var rcopy = tbod.rows[0].cloneNode(true); clrow(rcopy); if(!thF && tr.sectionRowIndex+1==tbod.rows.length) { tbod.appendChild(rcopy); } else { tbod.insertBefore(rcopy,(thF)?tbod.rows[0]:tr.nextSibling); } }
押されたボタンがマイナスじゃない(+)なら、変数rcopyにtbodyの1行目のノードを複製するしたものを代入。trueだから値もコピーされるため、clrow関数でテキストフィールドを初期化。
もし、クリックされたinputの親がtheadでなく、そのtrの行番号+1番目がtbodyの総列数と同じなら、tbodyの最後部にrcopyを追加する。(最後の行に追加するパターン)
それ以外なら、tbodyの子ノードとして、rcopyを、押したボタンの親がtheadならtbodyの先頭に、押したボタンの親がtbodyならそのtrの次の行(エレメント)へ。
コメントor補足情報orご指摘あればをお願いします。
記事No2393 題名:よろしくお願いいたします 投稿者:家島ダイアグラム 投稿日:2023-02-05 20:01:30
家島の情報サイトです。船やバスの時刻表や天気など様々な情報を発信中!!時刻表が変わった・間違いがある・ご要望の場合は連絡お願いします。Twitter・LINEをフォローまたはRSSでサイト更新時に通知します。
家島ダイアグラム
https://hyogo.ie-t.net/ #家島 #坊勢 #男鹿 #時刻表 #船 #神姫バス
- << 前のページ
- 次のページ >>