javascriptでテーブルを操作する

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)タグから数えて何番目かの違い。

テーブル追加・削除サンプルを読み解く

こちらのページで紹介されているスクリプトを考えて見ます。

if(window.addEventListener) {
	window.addEventListener('click',function(e){
		window.event = e;
		window.event.srcElement = e.target;
	},true);
}

イベントリスナで、クリックイベント全般に対して関数を実行。イベントリスナの関数の引数は起こしたイベントが自動的に入り、window.eventはそのイベント、そのイベントのsrcElement(要素)は、そのイベントのターゲット(要素)と同じ。trueはキャプチャーフェーズ(外から内へ)、falseはバブリングフェーズ(内から外へ)。

これの意味はFirefoxがsrcElementプロパティに対応していないため(targetには対応してる)、次で使うsrcElementをtargetに置き換えるため。

function sample(){
	var bt = window.event.srcElement;
	if(bt.nodeName != 'INPUT') return;
	if(bt.parentNode.cellIndex>1) return;
	var tr = bt.parentNode.parentNode;
	var thF = (tr.parentNode.nodeName == 'THEAD');
	var tbod = (thF)?tr.parentNode.parentNode.tBodies[0]:tr.parentNode;

変数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)までを代入。

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の次の行(エレメント)へ。

2012年12月18日11:46 PM | カテゴリー: javascript | コメント(0)

コメントを残す

メールアドレスが公開されることはありません。