javaScriptを使ってテーブルの行を追加・削除する

何かJavaScriptばかりになっているが、
とりあえず過去の作成物ソースコードを載せておくことにします。
あんま役に立たないかも。

これ作ったときは勉強したてで、色々試したいこととかも混ぜてます。
prototype.jsの存在は知ってましたが、使わず。
まずは自力でやって見るべしって感じでやりました。

任意のテーブルから行を削除するのと追加するためのメソッドです。

行の追加は、ある特定の行をコピーしてその下に同じ物を配置します。
ただし、テキストは空になり、idも異なるものにします。入れ子でも大丈夫。なはず。
行の削除は、ある特定の行を削除します。
ただし、行が1行の場合は削除しません。

出来る限り解説突っ込んでおきます。
tests.js

<!-- 名前空間がぶつからぬよう。javaっぽく -->
var com;
if(!com) {com={};};
if(!com.sample) {com.sample={};};
if(!com.sample.Class) {com.sample.Class={};};

<!-- 上記のショートカット -->
var al;
if(!al){al=com.sample.Class;};

<!-- 使い方。グローバル関数に入れ子して使うと見た目すっきり -->
<!-- テーブル行増メソッド -->
function addTableRow(target) {
	al.addTableRow(target);
}
<!-- テーブル行減メソッド -->
function remTableRow(target) {
	al.remTableRow(target);
}


<!-- テーブルに行を追加する -->
<!-- target:tagオブジェクト  -->
al.addTableRow=function(target) {
	var trtop=this.findParent(target, "tr");
	if(trtop.tagName.toLowerCase() != "tr") {
		alert("親取得に失敗しました");
		return;
	}
	var trtopParent=trtop.parentNode;
	<!--対象行のインデックスを取得し、+1-->
	var newColN=trtop.sectionRowIndex+1;
	var tr=trtopParent.insertRow(newColN);
	<!--行の全体数-->
	var torowN=trtopParent.rows.length;
	var len=trtop.cells.length;
	for(var i=0;i<len;i++) {
		var tdtop=trtop.cells[i];
		var clonechild=this.copyChild(tdtop);
		tr.appendChild(clonechild);
	}
}


<!-- 子供ノードをコピーする.入れ子は全てコピーする. -->
al.copyChild=function(tdNode) {
	var copy=tdNode.cloneNode(false);
	<!-- 属性は全てリセットする. -->
	this.resetAttributes(copy);
	<!-- tdNodeの子をコピーし、全属性をリセット. -->
	if(tdNode.hasChildNodes()) {
		var len=tdNode.childNodes.length;
		for(var i=0;i<len;i++) {
			var cchild=this.copyChild(tdNode.childNodes[i]);
			copy.appendChild(cchild);
		}
	}
	return copy;
}


<!-- 属性のリセットする. テキストは空に設定.idも一意に設定-->
al.resetAttributes=function(node) {
	if(node == null || node == undefined || node.nodeType != 1) {
		return node;
	}
	<!-- typeがテキスト以外のtagはそのまま返す.-->
	<!-- node.attributes.length < 0でないなら次の条件が実行できる.-->
	<!-- node.getAttribute("type")がnullか.つまり、定義されていないか-->
	<!-- node.typeが"text"ではないか.-->
	if(node.attributes.length < 0 || 
                        node.getAttribute("type") == null || node.type != "text") {
		<!-- idを一意に設定する.-->
		if(node.id != null && node.id != undefined && node.id !="") {
			node.id=this.changeValue(node.id);
		}
		<!-- nameを一意に設定する.-->
		if(node.name != null && node.name != undefined && node.name !="") {
			node.name=this.changeValue(node.name);
		}
		return node;
	<!--text-->
	}else {
		<!-- idを一意に設定する.-->
		if(node.id != null && node.id != undefined && node.id !="") {
			node.id=this.changeValue(node.id);
		}
		<!-- nameを一意に設定する.-->
		if(node.name != null && node.name != undefined && node.name !="") {
			node.name=this.changeValue(node.name);
		}
		node.value="";
		return node;
	}
}


<!-- idなどを一意にするためのメソッド -->
<!-- idは基本 form名:テーブル名:カラム番号:タグID といった順序 -->
al.changeValue=function(attr) {
	if(attr == null || attr == undefined) {
		return attr;
	}
	<!-- 他の方法で実装する場合はここへ -->
	
	return attr + ":" + this.createSuffix();
}


<!-- 接頭辞を作成。100%一意である時間を使うmath.randumは一意にならない. -->
al.createSuffix=function() {
	return new Date().getTime();
}


<!-- テーブルの行を削除する -->
al.remTableRow=function(target) {
	var trtop=this.findParent(target, "tr");
	<!-- テーブルに存在する行が1つなら削除不可 -->
	if(!this.searchRemainTr(trtop)) {;
		alert("can not delete any more");
		return false;
	}
	<!-- 行を削除 -->
	trtop.parentNode.deleteRow(trtop.sectionRowIndex);
	return true;
}


<!-- 指定した親がいたらそれを返す -->
<!-- target:親を捜す対象タグオブジェクト pname:親のタグ名 -->
al.findParent=function(target, pname) {
	if(target.tagName.toLowerCase() == "html" || target == top) {
 		return target;
 	}
	var parent=target.parentNode;
	if(parent.tagName.toLowerCase() != pname.toLowerCase()) {
		parent=this.findParent(parent, pname);
	}
 	return parent;
}


<!-- 行を削除可能か確認 -->
al.searchRemainTr=function(node) {
	var par=node.parentNode;
	var relen=par.childNodes.length;
	var eleCount=0;
	
	for(var i=0;i<relen;i++) {
		<!-- nodeがテキスト要素か確認。trueならカウントしない -->
		if(par.childNodes[i].nodeType == 3) {
			continue;
		}
		eleCount++;
	}
	if(eleCount == 1 ) {
		return false;
	}
	return true;
}

htmlソース

<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja" >
  <head>
    <meta http-equiv="Content-Type" content="text/html; charaset=UTF-8" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <link href="tests.js" rel="Javascript" type="text/javascript" media="all" />
    <script src="tests.js" type="text/javascript"></script>
    <title>sample</title>
  </head>

  <body>
    <form id="form1">
      <table border="1" id="tdata">
        <thead></thead>
        <tbody id="tbody1">
          <tr>
            <td>
	       <div>
	          <input type="text" id="sendt1" name="sendt1" value="xx" size="30"/>
	          <input type="button" value=" add " onClick="addTableRow(this);"/>
                  <input type="button" value=" rem " onClick="remTableRow(this);"/>
	       </div>
            </td>
           </tr>
           <tr>
	     <td>
                <div>
                   <input type="text" id="sendt2" name="sendt2" value="" size="30"/>
		   <input type="button" value=" add " onClick="addTableRow(this);"/>
		   <input type="button" value=" rem " onClick="remTableRow(this);"/>	
		</div>
	     </td>
           </tr>
         </tbody>
         <tfoot></tfoot>
      </table>
    </form>
  </body>
</html>

サンプルを起動するとこうなります。

fig.1 起動時

fig.2 「add」ボタン押下

fig.3 「remove」ボタン押下

fig.4 「remove」ボタン押下するも、行が1つしかないため警告表示される

テーブルに行を追加・削除するのにエラいコード書いているような気がしつつも、
そろそろPythonとかもソース書いてみようかなと思う今日この頃でした。
Erlangも。。

ちなみに最近「グラフデータベース」という言葉を知った。
ちょっと気になってます。