# Tabellenzeile hinzufügen



## timpanse (23. August 2010)

Huhu,

nun schon seid mehreren Tagen hänge ich fest an dieser Funktion. Ich bin mit Javascript nicht sehr vertraut, deswegen bitte ich um eure Hilfe.

Ich möchte in eine Tabelle per Klick eine neue Zeile hinzufügen, die Formularfelder enthalten soll. Das ganze klappt soweit auch, nur gibt es noch 3 Dinge, die ich nicht hinbekomme. 


```
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Test</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
//<![CDATA[
function tester(x)
{
    var tabelle = document.getElementById('dok')
           .getElementsByTagName('tbody')[0];

    for (var i = 0; i < x; i++)
       {
   var menge = document.createElement('input');
      menge.setAttribute("type", "text");
      menge.setAttribute("name", "menge"+[i]);
      menge.setAttribute("value", "menge"+[i]);
      menge.setAttribute("size", "5");
      menge.setAttribute("class", "textfeld");
   var einheit = document.createElement('input');
      einheit.setAttribute("type", "text");
      einheit.setAttribute("name", "einheit"+[i]);
      einheit.setAttribute("value", "einheit"+[i]);
      einheit.setAttribute("size", "5");
      einheit.setAttribute("class", "textfeld");
   var ep = document.createElement('input');
      ep.setAttribute("type", "text");
      ep.setAttribute("name", "ep"+[i]);
      ep.setAttribute("value", "ep"+[i]);
      ep.setAttribute("size", "10");
      ep.setAttribute("class", "textfeld");
   var kurztext = document.createElement('textarea');
      kurztext.setAttribute("name", "kurztext"+[i]);
      kurztext.setAttribute("class", "textfeld");

    var tr = tabelle.insertRow(0);

var td = tr.insertCell(0);
td.appendChild(document.createTextNode('leer'));
var td = tr.insertCell(0);
td.appendChild(document.createTextNode('leer')); 
var td = tr.insertCell(0);
td.appendChild(ep);
var td = tr.insertCell(0);
td.appendChild(kurztext);
var td = tr.insertCell(0);
td.appendChild(menge);
td.appendChild(einheit);
var td = tr.insertCell(0);
td.appendChild(document.createTextNode('leer'));
}
}
//]]>
</script>
</head>
<body>
   <form id="dok" action="auswertung.php">
<img src="add.jpg" onClick="javascript:tester(1);"></img>
      <table border="1">
      <tr><td>leer</td><td>Menge/Einheit</td><td>Kurztext</td><td>EP</td><td>leer</td><td>leer</td></tr>
         <tbody>

         </tbody>
      <tr><td>leer</td><td>leer</td><td>leer</td><td>leer</td><td>leer</td><td>leer</td></tr>
      </table>
<input type=submit value=abschicken>
   </form>
</body>
</html>
```

1. Die Zeile soll genau zwischen <tbody> und </tbody> eingefügt werden.

2. Die Formularfelder sollen nummeriert werden mittels variable "i". Also jedes neue Feld soll heißen z.B. einheit0, einheit1, einheit2, usw. damit man die auch später mit php ansprechen kann.

3. Wie kann man zuletzt eingefügte Zeile per klick wieder entfernen? Also ein Button mit "1 Zeile hinzufügen" aber auch einen mit "1 Zeile entfernen".


Im Prinzip kann das alles nur ne Kleinigkeit sein. Hat jemand ne kurze Beschreibung für mich, wie ich das umsetzen kann?

Vielen Dank im vorraus


----------



## timpanse (23. August 2010)

ok Frage 2 konnte ich mir gerade selbst beantworten.


```
<html>
<head>
<title>Test</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">
//<![CDATA[

var wert = 1;

function tester()
{
    var tabelle = document.getElementById('dok')
			  .getElementsByTagName('tbody')[0];

    if (wert == 10)
	{
	return;
	}
	else
    	{
	var menge = document.createElement('input');
		menge.setAttribute("type", "text");
		menge.setAttribute("name", "menge"+[wert]);
		menge.setAttribute("value", "menge"+[wert]);
		menge.setAttribute("size", "5");
		menge.setAttribute("class", "textfeld");
	var einheit = document.createElement('input');
		einheit.setAttribute("type", "text");
		einheit.setAttribute("name", "einheit"+[wert]);
		einheit.setAttribute("value", "einheit"+[wert]);
		einheit.setAttribute("size", "5");
		einheit.setAttribute("class", "textfeld");
	var ep = document.createElement('input');
		ep.setAttribute("type", "text");
		ep.setAttribute("name", "ep"+[wert]);
		ep.setAttribute("value", "ep"+[wert]);
		ep.setAttribute("size", "10");
		ep.setAttribute("class", "textfeld");
	var kurztext = document.createElement('textarea');
		kurztext.setAttribute("name", "kurztext"+[wert]);
		kurztext.setAttribute("class", "textfeld");

    var tr = tabelle.insertRow(0);

var td = tr.insertCell(0);
td.appendChild(document.createTextNode('leer'));
var td = tr.insertCell(0);
td.appendChild(document.createTextNode('leer'));  
var td = tr.insertCell(0);
td.appendChild(ep);
var td = tr.insertCell(0);
td.appendChild(kurztext);
var td = tr.insertCell(0);
td.appendChild(menge);
td.appendChild(einheit);
var td = tr.insertCell(0);
td.appendChild(document.createTextNode('leer'));
wert++;
}
}
//]]>
</script>
</head>
<body>
	<form id="dok" action="auswertung.php">
<img src="add.jpg" onClick="javascript:tester();"></img><img src="add.jpg" onClick="javascript:tester(exp-1);"></img>
		<table border="1">
		<tr><td>leer</td><td>Menge/Einheit</td><td>Kurztext</td><td>EP</td><td>leer</td><td>leer</td></tr>
			<tbody>

			</tbody>
		<tr><td>leer</td><td>leer</td><td>leer</td><td>leer</td><td>leer</td><td>leer</td></tr>
		</table>
<input type=submit value=abschicken>
	</form>
</body>
</html>
```

Nun sollte die Zeile nur noch zwischen den <tbody> erscheinen und wie kann ich auf Klick wieder eine Zeile wegnehmen?


----------



## Quaese (23. August 2010)

Hi,

zu 1.:
Füge die neue Zeile am Ende des tbody-Objekts ein. Dazu übergibst du die Länge des Zeilenarrays als Argument an die Methode *insertRow*.

```
var tr = tabelle.insertRow(tabelle.rows.length);
```

zu 2.:
Zum Löschen der letzten Zeile aus der Tabelle verwendest du am besten die Methode *deleteRow*.

Beispiel:

```
function removeRow(){
 var objTable = document.getElementById('dok').getElementsByTagName('tbody')[0];
 if(objTable.rows.length > 1){
    objTable.deleteRow(objTable.rows.length-1);
    wert--;
 }
}
```
Ciao
Quaese


----------



## timpanse (23. August 2010)

Juhu 

Vielen Dank Quaese!

I love you!


----------



## timpanse (31. August 2010)

Ist es möglich nun zwischen den neu eingefügten Zeilen noch weitere hinzuzufügen? Wenn man z.B. merkt das man irgendwo noch eine Zeile einfügen will.

Ich habe es mal so versucht, das ich die addRow und removeRow buttons mit in die Funktion geschrieben habe.


```
var addrow_button = document.createElement('img');
	        addrow_button.setAttribute("src", "image/add.png");
		addrow_button.setAttribute("title", "Neue Position hinzufügen");
		addrow_button.setAttribute("onclick", "javascript:addRow();");
		addrow_button.setAttribute("height", "35");
		addrow_button.setAttribute("width", "35");
		addrow_button.setAttribute("border", "0");
		addrow_button.setAttribute("class", "button_add_del");
......

    var tr = tabelle.insertRow(tabelle.rows.length);
 
var td = tr.insertCell(0);
td.appendChild(document.createTextNode(''));
var td = tr.insertCell(0);
td.appendChild(document.createTextNode('')); 
var td = tr.insertCell(0);
td.appendChild(ep);
var td = tr.insertCell(0);
td.appendChild(kurztext);
var td = tr.insertCell(0);
td.appendChild(pos);
td.appendChild(menge);
td.appendChild(einheit);
var td = tr.insertCell(0);
td.appendChild(addrow_button);
```

Das klappt auch. Ich bekomme nun vor jeder neu eingefügten Zeile die 2 buttons mit, jedoch fügt er dann die neue Zeile immer am Ende an. Ich möchte sie aber an der Stelle eingefügt haben, wo man draufklickt.

Wie lässt sich das umsetzen?

Ich hoffe man kann verstehen wie ich das meine


----------



## Quaese (31. August 2010)

Hi,

möglich wäre, die Funktionen zum Zufügen und Entfernen dahingehend zu modifizieren, dass sie als Argument das auslösende Element entgegennehmen können. Von diesem ausgehend kann die zugehörige Eltern-Tabellenzeile ermittelt werden. Jetzt sollten die weiteren Operationen kein Problem mehr darstellen.

Beispiel:

```
<html>
<head>
<title>www.tutorials.de</title>
<meta name="author" content="Quaese">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
//<![CDATA[
/*
 * Funktion zum Einfügen einer neuen Zeile
 * In die letzten beiden Zellen werden Buttons zum Einfügen einer Zeile davor und zum Entfernen der aktuellen
 * Zeile eingefügt.
 *
 * i)  Wird kein Argument übergeben, so wird die neue Zeile an das Ende der Tabelle angehängt
 * ii) Wird ein auslösendes Element im Argument übergeben, so wird dessen Eltern-Tabellenzeile ermittelt
 *     und vor diese eine neue Zeile eingehängt
 */
function newRow(objSrc){
  var objTBody = document.getElementById("table_id").getElementsByTagName("tbody")[0];

  // Falls kein auslösendes Objekt übergeben wurde
  if(typeof objSrc=="undefined"){
    var objTR = objTBody.insertRow(objTBody.rows.length);
  }else{
    // Eltern-Tabellenzeile des auslösenden Elements ermitteln
    var objHelpTR = objSrc.parentNode;
    while(objHelpTR && (objHelpTR.nodeName.toLowerCase()!="tr")){
      objHelpTR = objHelpTR.parentNode;
    }
    if(!objHelpTR) return;

    // Neue Zeile generieren
    var objTR = document.createElement("tr");
    // Neue Zeile vor aktueller Zeile einfügen
    objHelpTR.parentNode.insertBefore(objTR, objHelpTR);

  }

  // Erste Zelle
  var objTD = objTR.insertCell(objTR.cells.length);
  objTD.innerHTML = objTBody.rows.length;

  // Zweite Zelle mit Button "Zeile davor einfügen"
  objTD = objTR.insertCell(objTR.cells.length);
  var objBtn = document.createElement("button");
  objTD.appendChild(objBtn);
  objBtn.innerHTML = "Zeile davor einfügen";
  // Button mit onclick-Handler versehen
  objBtn.onclick = function(){
    // Funktion zum Einfügen einer neuen Zeile mit auslösendem Element aufrufen
    newRow(this);
  }

  // Dritte Zelle mit Button "Zeile löschen"
  objTD = objTR.insertCell(objTR.cells.length);
  objBtn = document.createElement("button");
  objTD.appendChild(objBtn);
  objBtn.innerHTML = "Zeile löschen";
  // Button mit onclick-Handler versehen
  objBtn.onclick = function(){
    // Funktion zum Entfernen einer Zeile mit auslösendem Element aufrufen
    removeRow(this);
  }
}

/*
 * Funktion zum Entfernen einer Zeile
 *
 * i)  Wird kein Argument übergeben, so wird die letzte Zeile der Tabelle gelöscht
 * ii) Wird ein auslösendes Element im Argument übergeben, so wird dessen Eltern-Tabellenzeile ermittelt
 *     und diese aus der Tabelle entfernt
 */
function removeRow(objSrc){
  var objTBody = document.getElementById("table_id").getElementsByTagName("tbody")[0];

  // Falls kein auslösendes Objekt übergeben wurde -> es wird die letzte Zeile entfernt
  if(typeof objSrc=="undefined"){
    // Falls mindestens eine Zeile existiert
    if(objTBody.rows.length > 0)
      objTBody.deleteRow(objTBody.rows.length-1);
  }else{
    // Eltern-Tabellenzeile des auslösenden Elements ermitteln
    var objTR = objSrc.parentNode;
    // Solange es sich nicht um eine Tabellenzelle handelt
    while(objTR && (objTR.nodeName.toLowerCase()!="tr")){
      objTR = objTR.parentNode;
    }
    if(!objTR) return;
    // Zeile aus Tabelle entfernen
    objTR.parentNode.removeChild(objTR);
  }
}
//]]>
</script>
</head>
<body>
<button onclick="newRow();">Zeile einfügen</button>
<button onclick="removeRow();">Zeile entfernen</button>
<table id="table_id">
  <tbody></tbody>
  <tbody><tr><td>leer</td><td>leer</td><td>leer</td></tr></tbody>
</table>
</body>
</html>
```
Auf weitere Erklärungen will ich an dieser Stelle verzichten und verweise stattdessen auf die Kommentare im Quellcode.

Ciao
Quaese


----------



## timpanse (31. August 2010)

Vielen herzlichen Dank Quaese!
Auch das du dir die Mühe gemacht hast, es in einem so schönen Beispiel zu verdeutlichen.
Ich werde das gleich morgen Früh umsetzen und mich nochmal melden.

LG tim


----------



## timpanse (7. September 2010)

Hallo, mal wieder 

Die Daten die man in diese Zeilen/Felder eingibt werden anschließend in eine Datenbank gespeichert. Wichtig ist es, für die spätere Rekonstruierung des Dokuments, eine korrekte Reihenfolge der Zeilen zu bekommen so wie sie dort auch eingegeben wurden.

Ich habe also:

1
2
3

und möchte nun zwischen 1 und 2 noch eine einfügen:

1
2
3 (vorher 2)
4 (vorher 3)

Also müsste man doch bei jedem neuen hinzufügen und entfernen einer Zeile alle anderen "id´s" updaten.

Ich habe mir schon eine Zwischenlösung überlegt, sodass ich einfach auch die Reihenfolge abspeichere. Sprich: 1,4,2,3 ist in Wirklichkeit 1,2,3,4

Das kann man so machen, muss man aber nicht 

... wenn man weiss wie es mit javascript funktioniert.

Die Formel müsste doch sein:
Neue ZeileNr=ElternZeile-1 & alle weiteren +1
Nur wie und wo bau ich das ein?


----------



## Quaese (8. September 2010)

Hi,

du könntest nach dem Einfügen/Entfernen einer Zeile alle Zeilen durchlaufen und die IDs neu setzen.

Beispiel:

```
var objTBody = document.getElementById("table_id").getElementsByTagName("tbody")[0];

// Anweisungen zum Einfügen/Entfernen einer Zeile

// IDs neu schreiben
for(var i=0; i<objTBody.rows.length; i++){
  objTBody.rows[i].id = "id_" + i;
}
```
Ciao
Quaese


----------



## timpanse (9. September 2010)

Hi Quaese und Danke.

Zeig mir doch mal kurz an welcher Stelle deines Beispiels man genau den Code einfügt, damit bei "test.value" also im Textfeld immer die neue, richtige id steht.

Hab schon wild hin und her probiert, komme aber nicht zum gewünschten Ergebnis.


```
<html>
<head>
<title>www.tutorials.de</title>
<meta name="author" content="Quaese">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
//<![CDATA[

function newRow(objSrc){
  var objTBody = document.getElementById("dokument").getElementsByTagName("tbody")[0];
  if(typeof objSrc=="undefined"){
    var objTR = objTBody.insertRow(objTBody.rows.length);
  }else{
    // Eltern-Tabellenzeile des auslösenden Elements ermitteln
    var objHelpTR = objSrc.parentNode;
    while(objHelpTR && (objHelpTR.nodeName.toLowerCase()!="tr")){
      objHelpTR = objHelpTR.parentNode;
    }
    if(!objHelpTR) return;
    // Neue Zeile generieren
    var objTR = document.createElement("tr");
    // Neue Zeile vor aktueller Zeile einfügen
    objHelpTR.parentNode.insertBefore(objTR, objHelpTR);
  }
  // Erste Zelle
  var objTD = objTR.insertCell(objTR.cells.length);
  objTD.innerHTML = objTBody.rows.length;
  var objTD = objTR.insertCell(objTR.cells.length);
  var test = document.createElement("input");
  		test.setAttribute("value", objTBody.rows.length);
  objTD.appendChild(test);
  // Zweite Zelle mit Button "Zeile davor einfügen"
  objTD = objTR.insertCell(objTR.cells.length);
  var objBtn = document.createElement("button");
  objTD.appendChild(objBtn);
  objBtn.innerHTML = "Zeile davor einfügen";
  // Button mit onclick-Handler versehen
  objBtn.onclick = function(){
    // Funktion zum Einfügen einer neuen Zeile mit auslösendem Element aufrufen
    newRow(this);
  }
  // Dritte Zelle mit Button "Zeile löschen"
  objTD = objTR.insertCell(objTR.cells.length);
  objBtn = document.createElement("button");
  objTD.appendChild(objBtn);
  objBtn.innerHTML = "Zeile löschen";
  // Button mit onclick-Handler versehen
  objBtn.onclick = function(){
    // Funktion zum Entfernen einer Zeile mit auslösendem Element aufrufen
    removeRow(this);
  }
}

function removeRow(objSrc){
  var objTBody = document.getElementById("dokument").getElementsByTagName("tbody")[0];
 
  // Falls kein auslösendes Objekt übergeben wurde -> es wird die letzte Zeile entfernt
  if(typeof objSrc=="undefined"){
    // Falls mindestens eine Zeile existiert
    if(objTBody.rows.length > 0)
      objTBody.deleteRow(objTBody.rows.length-1);
  }else{
    // Eltern-Tabellenzeile des auslösenden Elements ermitteln
    var objTR = objSrc.parentNode;
    // Solange es sich nicht um eine Tabellenzelle handelt
    while(objTR && (objTR.nodeName.toLowerCase()!="tr")){
      objTR = objTR.parentNode;
    }
    if(!objTR) return;
    // Zeile aus Tabelle entfernen
    objTR.parentNode.removeChild(objTR);
  }
}
//]]>
</script>
</head>
<body>
<button onClick="newRow();">Zeile einfügen</button>
<button onClick="removeRow();">Zeile entfernen</button>
<table id="dokument" border="1">
  <tbody></tbody>
  <tbody><tr><td>leer</td><td>leer</td><td>leer</td></tr></tbody>
</table>
</body>
</html>
```


----------



## timpanse (13. September 2010)

Ok, ich bin ein Stück weiter.
Auf Klick auf "richtig nummerieren" soll nun function helga aufgerufen werden und richtig nummeriert werden. Trotzdem nummeriert er aber neue Zeile zwischendrinne nicht der Reihenfolge entsprechend richtig sondern so wie eingefügt wurden.

Funktion "helga" durchläuft doch aber bei jedem Klick alle reihen, ermittelt die Reihenanzahl und vergibt dann fortlaufend die Nr.

Verstehe ich nicht!
Muss doch was mit getElementById("test"+i) zu tun haben, oder?
Aber wie soll ich sonst die Felder ansprechen?


```
<html>
<head>
<style type="text/css"><!--
.button_add_del {cursor:pointer;}
--></style>
<script type="text/javascript">
//<![CDATA[

function newRow(objSrc)
{
  	var objTBody = document.getElementById("dokument").getElementsByTagName("tbody")[0];
 	if(typeof objSrc=="undefined")
		{
   			var objTR = objTBody.insertRow(objTBody.rows.length);
		}
	else
		{
    			var objHelpTR = objSrc.parentNode;
    			while(objHelpTR && (objHelpTR.nodeName.toLowerCase()!="tr"))
				{
      					objHelpTR = objHelpTR.parentNode;
    				}
			if(!objHelpTR) return;
    			var objTR = document.createElement("tr");
    			objHelpTR.parentNode.insertBefore(objTR, objHelpTR);
		}
  
  	var einheit = document.createElement('select');
		theOption1=document.createElement("OPTION");
		theText1=document.createTextNode("cm");
		theOption1.appendChild(theText1);
		theOption1.setAttribute("value","cm");
		einheit.appendChild(theOption1);
		theOption2=document.createElement("OPTION");
		theText2=document.createTextNode("g");
		theOption2.appendChild(theText2);
		theOption2.setAttribute("value","g");
		einheit.appendChild(theOption2);
        	einheit.setAttribute("name", "einheit"+objTBody.rows.length);
        	einheit.setAttribute("id", "einheit"+objTBody.rows.length);
        	einheit.setAttribute("class", "textfeld");
    	var pos = document.createElement('input');
        	pos.setAttribute("type", "text");
        	pos.setAttribute("name", "pos"+objTBody.rows.length);
        	pos.setAttribute("id", "pos"+objTBody.rows.length);
        	pos.setAttribute("size", "3");
        	pos.setAttribute("class", "textfeld");
    	var menge = document.createElement('input');
        	menge.setAttribute("type", "text");
        	menge.setAttribute("name", "menge"+objTBody.rows.length);
        	menge.setAttribute("id", "menge"+objTBody.rows.length);
        	menge.setAttribute("size", "2");
        	menge.setAttribute("class", "textfeld");
    	var ep = document.createElement('input');
        	ep.setAttribute("type", "text");
        	ep.setAttribute("name", "ep"+objTBody.rows.length);
        	ep.setAttribute("id", "ep"+objTBody.rows.length);
        	ep.setAttribute("size", "6");
        	ep.setAttribute("class", "textfeld");
    	var kurztext = document.createElement('textarea');
        	kurztext.setAttribute("name", "kurztext"+objTBody.rows.length);
        	kurztext.setAttribute("id", "kurztext"+objTBody.rows.length);
        	kurztext.setAttribute("cols", "60");
        	kurztext.setAttribute("rows", "2");
        	kurztext.setAttribute("class", "textfeld");
	var addrow_button = document.createElement('img');
		addrow_button.setAttribute("src", "image/add_above.png");
		addrow_button.setAttribute("title", "Neue Position darüber einfügen");
		addrow_button.setAttribute("onclick", "javascript:newRow(this);");
		addrow_button.setAttribute("height", "35");
		addrow_button.setAttribute("width", "35");
		addrow_button.setAttribute("border", "0");
		addrow_button.setAttribute("class", "button_add_del");
	var delrow_button = document.createElement('img');
		delrow_button.setAttribute("src", "image/del_above.png");
		delrow_button.setAttribute("title", "Diese Position entfernen");
		delrow_button.setAttribute("onclick", "javascript:removeRow(this);");
		delrow_button.setAttribute("height", "35");
		delrow_button.setAttribute("width", "35");
		delrow_button.setAttribute("border", "0");
		delrow_button.setAttribute("class", "button_add_del");
	var test_button = document.createElement('input');
		test_button.setAttribute("id", "test"+objTBody.rows.length);
 	var id_button = document.createElement('input');
      		id_button.setAttribute("name", "anzahl");
      		id_button.setAttribute("value", +objTBody.rows.length);
  	
	var objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(id_button);

  	objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(addrow_button);
  	objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(delrow_button);
  
  	objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(pos);
  	objTD.appendChild(menge);
  	objTD.appendChild(einheit);

  	objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(kurztext);
 
  	objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(ep);

  	objTD = objTR.insertCell(objTR.cells.length);
  	objTD.appendChild(test_button);

	//helga();
}

function removeRow(objSrc)
{
  	var objTBody = document.getElementById("dokument").getElementsByTagName("tbody")[0];
	if(typeof objSrc=="undefined")
		{
    			if(objTBody.rows.length > 0)
			objTBody.deleteRow(objTBody.rows.length-1);  
  		}
	else
		{
			var objTR = objSrc.parentNode;
			while(objTR && (objTR.nodeName.toLowerCase()!="tr"))
				{
      					objTR = objTR.parentNode;
				}
    			if(!objTR) return; 
			objTR.parentNode.removeChild(objTR);
  		}
}

function helga()
{
	var objTBody = document.getElementById("dokument").getElementsByTagName("tbody")[0];
	for(var i=1; i<=objTBody.rows.length; i++)
		{
			document.getElementById("test"+i).value = "Nr.: "+i;
		}
}

//]]>
</script>
</head>
<body>
<a href=# onclick="javascript:helga();">richtig Nummerieren</a><br><br>
<img src="image/add.png" title="Neue Position hinzufügen" onClick="javascript:newRow();" height="35" width="35" border="0" class="button_add_del">
<img src="image/del.png" title="Letzte Position entfernen" onClick="javascript:removeRow();" height="35" width="35" border="0" class="button_add_del">
<form action="auswertung.php">
<table id="dokument" border="1">

  <tbody></tbody>

</table>
<input type="submit" value="senden">
</form>
</body>
</html>
```


----------



## Quaese (15. September 2010)

Hi,

ich beziehe mich mit meinen Ausführungen auf mein letztes Beispiel:

Du könntest alle Tabellenzeilen durchlaufen und mit neuen IDs versehen.

Die Input-Elemente innerhalb der Zeile ermittelst du über *getElementsByTagName*. Das resultierende Array durchläufst du und vergibst den Input-Elementen neue IDs - z.B. der Form "ID_zeilennummer_inputnummer".

Beispiel:

```
<html>
<head>
<title>www.tutorials.de</title>
<meta name="author" content="Quaese">
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<script type="text/javascript">
//<![CDATA[
/*
 * Funktion zum Einfügen einer neuen Zeile
 * In die letzten beiden Zellen werden Buttons zum Einfügen einer Zeile davor und zum Entfernen der aktuellen
 * Zeile eingefügt.
 *
 * i)  Wird kein Argument übergeben, so wird die neue Zeile an das Ende der Tabelle angehängt
 * ii) Wird ein auslösendes Element im Argument übergeben, so wird dessen Eltern-Tabellenzeile ermittelt
 *     und vor diese eine neue Zeile eingehängt
 */
function newRow(objSrc){
  var objTBody = document.getElementById("table_id").getElementsByTagName("tbody")[0];

  // Falls kein auslösendes Objekt übergeben wurde
  if(typeof objSrc=="undefined"){
    var objTR = objTBody.insertRow(objTBody.rows.length);
  }else{
    // Eltern-Tabellenzeile des auslösenden Elements ermitteln
    var objHelpTR = objSrc.parentNode;
    while(objHelpTR && (objHelpTR.nodeName.toLowerCase()!="tr")){
      objHelpTR = objHelpTR.parentNode;
    }
    if(!objHelpTR) return;

    // Neue Zeile generieren
    var objTR = document.createElement("tr");
    // Neue Zeile vor aktueller Zeile einfügen
    objHelpTR.parentNode.insertBefore(objTR, objHelpTR);

  }

  // Erste Zelle
  var objTD = objTR.insertCell(objTR.cells.length);
  objTD.innerHTML = objTBody.rows.length;
  var objInput = document.createElement("input");
  objInput.type = "text";
  objInput.value = objTBody.rows.length;
  objTD.appendChild(objInput);
  objInput = document.createElement("input");
  objInput.type = "text";
  objInput.value = objTBody.rows.length;
  objTD.appendChild(objInput);

  // Zweite Zelle mit Button "Zeile davor einfügen"
  objTD = objTR.insertCell(objTR.cells.length);
  var objBtn = document.createElement("button");
  objTD.appendChild(objBtn);
  objBtn.innerHTML = "Zeile davor einfügen";
  // Button mit onclick-Handler versehen
  objBtn.onclick = function(){
    // Funktion zum Einfügen einer neuen Zeile mit auslösendem Element aufrufen
    newRow(this);
  }

  // Dritte Zelle mit Button "Zeile löschen"
  objTD = objTR.insertCell(objTR.cells.length);
  objBtn = document.createElement("button");
  objTD.appendChild(objBtn);
  objBtn.innerHTML = "Zeile löschen";
  // Button mit onclick-Handler versehen
  objBtn.onclick = function(){
    // Funktion zum Entfernen einer Zeile mit auslösendem Element aufrufen
    removeRow(this);
  }
  reorganizeIDs(objTBody);
}

/*
 * Funktion zum Entfernen einer Zeile
 *
 * i)  Wird kein Argument übergeben, so wird die letzte Zeile der Tabelle gelöscht
 * ii) Wird ein auslösendes Element im Argument übergeben, so wird dessen Eltern-Tabellenzeile ermittelt
 *     und diese aus der Tabelle entfernt
 */
function removeRow(objSrc){
  var objTBody = document.getElementById("table_id").getElementsByTagName("tbody")[0];

  // Falls kein auslösendes Objekt übergeben wurde -> es wird die letzte Zeile entfernt
  if(typeof objSrc=="undefined"){
    // Falls mindestens eine Zeile existiert
    if(objTBody.rows.length > 0)
      objTBody.deleteRow(objTBody.rows.length-1);
  }else{
    // Eltern-Tabellenzeile des auslösenden Elements ermitteln
    var objTR = objSrc.parentNode;
    // Solange es sich nicht um eine Tabellenzelle handelt
    while(objTR && (objTR.nodeName.toLowerCase()!="tr")){
      objTR = objTR.parentNode;
    }
    if(!objTR) return;
    // Zeile aus Tabelle entfernen
    objTR.parentNode.removeChild(objTR);
    reorganizeIDs(objTBody);
  }
}

function reorganizeIDs(objTBody){
  // IDs neu schreiben
  for(var i=0; i<objTBody.rows.length; i++){
    objTBody.rows[i].id = "id_" + i;
    // Alle Inputs der Tabellenzeile ermitteln
    var arrInputs = objTBody.rows[i].getElementsByTagName("input");
    // Alle Inputs durchlaufen
    for(var j=0; j<arrInputs.length; j++){
      arrInputs[j].id = "id_" + i + "_" + j;
    }
  }
}
//]]>
</script>
</head>
<body>
<button onclick="newRow();">Zeile einfügen</button>
<button onclick="removeRow();">Zeile entfernen</button>
<table id="table_id">
  <tbody></tbody>
  <tbody><tr><td>leer</td><td>leer</td><td>leer</td></tr></tbody>
</table>
</body>
</html>
```
Mit dem Zuweisen des *onclick*-Handlers über die Methode *setAttribute* solltest du vorsichtig sein, da der IE Probleme damit hat.

Ciao
Quaese


----------



## timpanse (15. September 2010)

Perfekt!

Ein Stück komfortabler wäre es allerdings die Textfelder per Name anzusprechen, da es ja verschiedene gibt. 


```
for(var i=0; i<objTBody.rows.length; i++)
		{
			var input = objTBody.rows[i].getElementsByName("menge");
			for(var j=0; j<input.length; j++)
				{
					input[j].value = "input_" + i + "_" + j;
				}
		}
```

klappt aber nicht. Geht das nur mit getElementsByTagName?


----------



## SpiceLab (15. September 2010)

Schau mal zum Vergleich deines Codeschnipsels hier: getElementsByName().


----------



## timpanse (15. September 2010)

Das spricht nur 1 bestimmtes an.

...ab und zu sollte ich aufhören dumme Fragen zu stellen und erst mal lesen.

Gibts es den überhaupt einen Weg zu sagen z.b. pack alle textfelder mit Attr. name="menge" in ein Array?


----------



## Quaese (16. September 2010)

Hi,

*getElementsByName* ist eine Methode des *document*-Objekts, nicht des *node*-Objekts. Somit ist es nicht möglich, die Methode im Kontext der Tabellenzeilen aufzurufen.

Vorstellbar wäre es, alle Elemente im *onload*-Event mit einer eigenen Methode zu versehen, die alle Kindknoten ermittelt, die ein gefordertes *name*-Attribut enthalten. Die gefundenen Elemente könnten in einem Array zurück gegeben werden.

Beispiel:

```
var fnLoadHandler = function(){
  var arrAll = (document.all)? document.all : document.getElementsByTagName("*");

  for(var i=0; i<arrAll.length; i++){
    arrAll[i].getElementsByName = function(strName){
      var arrAll = (this.all)? this.all : this.getElementsByTagName("*");
      var arrRet = [];

      for(var i=0; i<arrAll.length; i++){
        if(arrAll[i].attributes.getNamedItem("name") != null){
          if(arrAll[i].attributes.getNamedItem("name").value == strName){
            arrRet[arrRet.length] = arrAll[i];
          }
        }
      }

      return arrRet;
    }
  }
}


if(window.addEventListener){
  window.addEventListener('load', fnLoadHandler, false);
}else if(window.attachEvent){
  window.attachEvent("onload", fnLoadHandler);
}else{
  var fnLoad = window.onload;
  window.onload = function(){
    fnLoadHandler();
    fnLoad();
  }
}
```
Verwendet wird die Methode wie ihr Äquivalent des *document*-Objekts.

Ciao
Quaese


----------

