Javascriptでのtableの選択に関する操作

Tableの選択に関するクラスを実装してみました。以下の機能を含むものにしました。

マウスが現在ある行のスタイルを通常の行と違うものにする。
各行に含まれるチェックボックスの全チェックと全チェッククリア
チェックされている行を通常の行と違うものにする。
チェックされている行の削除
チェックされている行の取得

prototype.jsの1.6を使っての実装としました。

Javascriptのクラスの定義

var TableSelector = Class.create({
	initialize : function(tableId) {
		this.tableId = tableId;
	},

	_mouseover : function(e, elem) {
        elem.className = this.hoverClassName;
	},

	_mouseout : function(e, elem) {
        elem.className = this.normalClassName;
		selector = this;
		elem.select('input').each(function(inputElem) {
			if(inputElem.checked) {
		        elem.className = selector.selectedClassName;
			}
			else {
			}
		});
	},

	// マウスオーバー時、行選択時の行のスタイル変更を有効にする。
	// 引数のHashでそれぞれれの状態のクラス名を指定。指定するHashのキーは以下のとおり。
	// normal => 通常, hover => マウスオーバー時, selected => 行をチェックボックスで選択時
	enableHoverRow : function() {
		var args = arguments.length > 0 ? $A(arguments) : new Array();
		if(args.size() > 0 )  {
			ids = args[0];
			this.normalClassName 
				= ids.get("normal") ? ids.get("normal") : "tr-normal";
			this.hoverClassName
			 	= ids.get("hover") ? ids.get("hover") : "tr-hover";
			this.selectedClassName 
				= ids.get("selected") ? ids.get("selected") : "tr-selected";
		}
		else {
			this.normalClassName = "tr-normal";
			this.hoverClassName = "tr-hover";
			this.seletedClassName = "tr-selected";
		}
		if($(this.tableId)) {
			var selector = this;
			$(this.tableId).select("tbody tr").each(function(elem) {
	            elem.observe("mouseover", 
					selector._mouseover.bindAsEventListener(selector,elem)); 
	            elem.observe("mouseout", 
					selector._mouseout.bindAsEventListener(selector,elem)); 
			} ); // each
		}  // if($(this.tableId))
		$(this.tableId).select("tbody tr").each(function(tr) {
			tr.select('input').each(function(elem) {
				if(elem.checked) {
					tr.className = selector.selectedClassName;
				}
				else {
					tr.className = selector.normalClassName;
				}
			});
		});
	},
	
	// 全行チェックのイベントを登録。引数指定したIDのタグ要素がクリックされると全行がチェックされる。
	addCheckAllEvent : function(linkId) {
		if($(this.tableId) && $(linkId)) {
			var selector = this;
			$(linkId).observe("click", function(e) {
				$(this.tableId).select("tbody tr").each(function(tr) {
					tr.select('input').each(function(elem) {
						elem.checked = true;
						tr.className = selector.selectedClassName;
					} );
					
				} );
			}.bindAsEventListener(selector)); 
		}
	},
	
	// 全行チェッククリアのイベントを登録。引数指定したIDのタグ要素がクリックされると全行がチェックがクリアされる。
	addClearCheckEvent : function(linkId) {
		if($(this.tableId) && $(linkId)) {
			var selector = this;
			$(linkId).observe("click", function(e) {
				$(this.tableId).select("tbody tr").each(function(tr) {
					tr.select('input').each(function(elem) {
						elem.checked = false;
						tr.className = selector.normalClassName;

					} );
					
				} );
			}.bindAsEventListener(selector)); 
		}
	},
	
	// 選択されている行を削除
	removeSelected : function() {
		if($(this.tableId) ) {
			$(this.tableId).select("tbody tr").each(function(tr) {
				tr.select('input').each(function(elem) {
					if(elem.checked == true) {
						tr.remove();
					} 
				});
			} );
		}
	},

	// 選択されている行の(trタグの)idのArrayを返す。
	getSelected : function() {
		var selected = new Array();
		if($(this.tableId) ) {
			$(this.tableId).select("tbody tr").each(function(tr) {
				tr.select('input').each(function(elem) {
					if(elem.checked == true) {
						selected.push(tr.id);
					}
				} );
			} );
		}
		return selected;
	}
		
} );

各メソッドは以下のとおりです。

コンストラクタ(initialize)

対象となるテーブルタグのid属性名を指定してオブジェクトを生成することになる。

enableHoverRow

マウスが現在ある行とチェックされている行のスタイルを通常の行と違うものになるようにイベントを登録する。
引数としてHashを渡す。それぞれれの状態のクラス属性名を要素として指定していく。指定するHashのキー名とその内容は以下のとおり。
normal => 通常, hover => マウスオーバー時, selected => 行をチェックボックスで選択時。

addCheckAllEvent

各行に含まれるチェックボックスの全チェックイベントを登録する。引数として、イベント起動元タグ(リンクかボタン)のid属性を指定。

addClearCheckEvent

各行に含まれるチェックボックスの全チェッククリアイベントを登録する。引数として、イベント起動元タグ(リンクかボタン)のid属性を指定。

removeSelected

チェックされている行を削除する。

getSelected

チェックされている行のtrタグのId属性名を含むArrayを返す。

Htmlへの組み込み(ヘッダー部分)

Htmlのヘッダー部分にJavascriptを記述、オブジェクトの生成と各イベント登録がドキュメントロード後に行われるようにしています。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <link rel="stylesheet" type="text/css" href="css/table.css">

    <script type="text/javascript" src="js/prototype.js"></script>
    <script type="text/javascript" src="js/table.js"></script>
    <script language="JavaScript" type="text/javascript">
    <!--
      function init() {
		var selector = new TableSelector('subjects');
		selector.enableHoverRow($H({normal: 'subject-normal', 
			hover: 'subject-hover', 
			selected: 'subject-selected'}));
		selector.addCheckAllEvent('check-all');
		selector.addClearCheckEvent('clear-check');
		$('remove-button').observe("click", selector.removeSelected.bind(selector));
		
      }
	document.observe('dom:loaded', init);

    //-->
    </script>
    <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
    <title></title>
   </head>

Htmlへの組み込み(ヘッダー部分)

body部分には、対象のtableなどを含んでいます。tableのid属性名「subjects」がTableSelectorオブジェクト生成時の引数と対応しています。

  <body >
<div id="main-div">
	<div id="controls">
		<a id="check-all" href="javascript:void(0);" >
			全て
		</a>
		&nbsp;
		<a id="clear-check"  href="javascript:void();" >
			なし
		</a>
		<input id="remove-button" type="button" value="削除"/>
	</div>
	<table id="subjects" >
		<thead>
			<tr>
				<th>
			 	</th>
				<th>Subject
			 	</th>
			<tr>
		</thead>
		<tbody>
			<tr id="row-1" class="subject-normal">
				<td>
					<input type="checkbox" name="check-1" />
				</td>
				<td>件名1
				</td>
			</tr>
			<tr id="row-2" class="subject-normal">
				<td>
					<input type="checkbox" name="check-2" />
				</td>
				<td>件名2
				</td>
			</tr>
			<tr id="row-3" class="subject-normal">
				<td>
					<input type="checkbox" name="check-3" />
				</td>
				<td>件名3
				</td>
			</tr>
		</tbody>
	</table>
</div>
  </body>

</html>

css

以下、今回利用したcssです。後半3つのセレクターに対する定義が、行のスタイル変更に関するものです。これらのセレクターがenableHoverRowの引数で指定しているクラス名と対応しています。

body {
  background-color: #FFFFFF;
  color:#333333;
  font-size:12px;
  letter-spacing:1px;
  line-height:20px;
  margin:0;
  text-align:center;
  width:600px;
}

div#main-div {
	position:relative;
	left:10pt;
	width:580px;
}

div#controls {
	text-align:left;
}


table#subjects {
	width:100%;
	margin:10px 2px 0px 10px;
}

table#subjects thead {
  background-color: #CCFFAA;
}

table#subjects tbody {
 }

table#subjects tbody td {
	text-align:left;
	border-style:solid;
	border-width:thin;
	bottom:20pt;
}

table#subjects tbody td {
	text-align:left;
	border-style:solid;
	border-width:thin;
	bottom:20pt;
}

tr.subject-normal {
 	background-color: #DDDDFF;
}

tr.subject-hover {
 	background-color: #FFEECC;
}

tr.subject-selected {
 	background-color: #FFDDCC;
}