Tabellenzeile hinzufügen

timpanse

Grünschnabel
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.

Code:
<!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 ;)
 
ok Frage 2 konnte ich mir gerade selbst beantworten.

Code:
<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?
 
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.
Code:
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:
Code:
function removeRow(){
 var objTable = document.getElementById('dok').getElementsByTagName('tbody')[0];
 if(objTable.rows.length > 1){
    objTable.deleteRow(objTable.rows.length-1);
    wert--;
 }
}
Ciao
Quaese
 
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.

Code:
	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 ;)
 
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:
Code:
<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
 
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
 
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?
 
Zuletzt bearbeitet:
Hi,

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

Beispiel:
Code:
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
 
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.

Code:
<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>
 

Neue Beiträge

Zurück