• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] Per Javascript Formular-Elemente hinzufügen ohne Datenverlust

befubo

New member
Guten Tag liebe JavaScript Community

Da sich meine Javascriptkenntnisse auf einem eher tiefen Niveau befinden wollte ich mich mal mit einer kleinen Problematik an Euch richten:
Ich möchte bei einem Formular mittels Plus und Minus Elemente hinzufügen / entfernen. Derzeit sieht meine Lösung so aus:

head:
HTML:
<script>
// Formularfelder dynamisch hinzufügen

var feld = 1;

function plus() {
 if (feld <= 50) {
  document.getElementById("dynamisch").innerHTML +=
  "<table><tr><td width='80px'>Slot " + feld + ":</td><td><select name='class_" + feld + "'><option value='1'>Gruppenführer</option></select></td></tr></table>";
  feld++;
 }
}

function minus() {
 if (feld > 1) {
  feld--;
  document.getElementById("dynamisch").innerHTML = "";
  for (var zaehler = 1; zaehler < feld; zaehler++) {
    document.getElementById("dynamisch").innerHTML +=
    "<table><tr><td width='80px'>Slot " + zaehler + ":</td><td><select name='class_" + zaehler + "'><option value='1'>Gruppenführer</option></select></td></tr></table>";
  }
 }
}
</script>

body:
HTML:
<input type="button" value="-" onClick="minus();">
<input type="button" value="+" onClick="plus();">

<div id="dynamisch"></div>

Das ganze funktioniert ja schon mal sehr gut. Codeverständnis ist ebenfalls vorhanden (Ist ein Script aus dem Netz mit einigen kleinen Modifikationen...)
Da ich ja mit dem Script aber immer alle Formulare neu schreibe, geht ja der Inhalt (In meinem Fall die Auswahl im <select> Formular verloren.
Zudem finde ich das eine eher unschöne Lösung, jedes Mal alle Formfelder neu zu schreiben.
Gibt es da eine Möglichkeit, das Ganze zu vereinfachen damit die Inhalte (Oder Auswahl) gespeichert bleibt?

Besten Dank und freundliche Grüsse
befubo

EDIT: Hab den unnötigen Code für die Auswahlliste mal entfernt, vielleicht etwas einfach zu lesen? ^^
 
Zuletzt bearbeitet:
Ach Du heilg'es Blechle ... aber Grüße erstmal! Du ... ähm ... ich finde es unnötig kompliziert! :D Hier mein Vorschlag, der Dir vielleicht eher zusagt ...

Grunsätzlich ...
- statt einem DIV nimmst Du eine leere Tabelle (<table id="dynamisch"></table>)

Erweitern um TR ...
- "plus()" erweitert diese Tabelle um ein <tr>

Entnahme von TR ...
- gib denen "leere Klassen" und eine Nummerierung mit (bspw. "feld"); <tr class="tr1"></tr>
- über diese Klasse kannst Du dann den kompletten TR entnehmen (Deine Minus-Funktion)

Speichern ...
- "vollständig" als Source in einer DB ablegen; nimmst Dir das DOM von "dynamisch" und legst es je User o. ä. weg

Anzeige/Unterscheidung "neu"/"gespeichert" ...
Bei Seitenaufruf prüft Du, ob "dynamisch" für den User (o. ä.) generiert wurde - falls ja, darstellen ... falls nicht, die leere Tabelle zwecks Aufbau (s. "Grunsätzlich")


Ich befürchte aber, dass Du nur die halbe Wahrheit hier zeigst und es daher "noch mehr Teile" gibt, die mein Modell obsolet machen. Mein Tipp wäre also, dass Du es auf den kleinsten Nenner runterbrichst - womöglich baut alles auf dem Gruppenführer auf (da bei dem bspw. noch Schergen, Ausrüstung o. ä. eingetragen werden). Unklar ist mir nur, ob diese Tabelle vom Gruppenführer angelegt wird oder von einer "höheren Instanz" (TE-Führer oder höher).

Aber 50 Tables mit einem Einzeiler? Eeeehm ... nö! ;)

Beste und sonnige Grüße
 
Da ich ja mit dem Script aber immer alle Formulare neu schreibe, geht ja der Inhalt (In meinem Fall die Auswahl im <select> Formular verloren.
Zudem finde ich das eine eher unschöne Lösung, jedes Mal alle Formfelder neu zu schreiben.
welches willst du denn entfernen? immer das letzte? warum gerade das? eigentlich doch ein bestimmtes. wenn immer das letzte, musst du dieses einfach suchen, das geht am einfachsten mit jquery sonst müsstest du alle deine elemente suchen und das letzte nehmen, z.b. über
Code:
var nodes = document.getElementById("dynamisch").querySelectorAll('table');
var last = nodes[nodes.length- 1];
oder über getElementsByTagName oder getElementsByClass
hast du das letzte, kannst du es mit jquery entfernen oder mit removeChild

warum hast du eigentlich soviele tabellen da drinn? warum überhaupt tabellen?
 
Ach Du heilg'es Blechle ... aber Grüße erstmal!
Ja das dacht ich auch :D Danke und Hallo!

Grundsätzlich ist das Ganze eine Seite um sich für Arma3 Events anzumelden. Das Ganze ist jetzt erst im Entstehen, heisst das wird dann mit dem Usersystem der Website verbunden.
Die ganze Seite sieht so aus:

screen.png

Diese Slots sind einfach nur Dropdowns, damit man definieren kann, welche Spielklassen belegbar sind.
Das ganze wird dann als eigene Tabelle in MySql gespeichert (Bei Absendung des gesamten Formulars):
HTML:
$sql = "
			CREATE TABLE `$slot` (
			`id` INT( 10 ) NOT NULL ,
			`slot` VARCHAR( 250 ) NOT NULL ,
			`squad` VARCHAR( 250 ) NOT NULL ,
			`player` VARCHAR( 250 ) NOT NULL
			) ENGINE = MYISAM ;
			";

Über eine separate Seite können die Spieler dann die Slots buchen:
screen2.png

Es kommen also keine weiteren Optionen zu den Slots dazu.
Das Problem ist ja jetzt, wenn ich z.B. einen Slot erstelle und auswähle, welche Klasse er sein soll: Jedesmal wenn ich dann einen neuen Slot erstelle, überschreibt es natürlich die vorherige Auswahl wieder, weil alle Elemente neu geschrieben werden.

Also so mal die Gesamtsituation.

welches willst du denn entfernen? immer das letzte?
Ja und Nein. Grundsätzlich sollte mal die Auswahl des DropDowns bleiben, wenn ich einen zusätzlichen Slot generiere. Dann kann es sein, dass ich vielleicht 2 Slots zuviel gemacht habe. Die soll ich dann einfach mit dem Minus entfernen können. In der Mitte muss ich ja nichts entfernen, die kann ich ja von Hand direkt wieder ändern...

warum hast du eigentlich soviele tabellen da drinn? warum überhaupt tabellen?
Da es mir jetzt zuerst um die Funktionalität geht war mir das Layouten egal. Darum habe ich kein DIV System oder so aufgebaut. Tabellen haben sich da halt als einfache Designer gut angeboten...

Danke euch für die Zeit und ebenfalls einen sonnigen Gruss
befubo
 
Das Problem ist ja jetzt, wenn ich z.B. einen Slot erstelle und auswähle, welche Klasse er sein soll: Jedesmal wenn ich dann einen neuen Slot erstelle, überschreibt es natürlich die vorherige Auswahl wieder, weil alle Elemente neu geschrieben werden.
ja, ich hatte dir schon geschrieben, wie du das lösen kannst

Ja und Nein. Grundsätzlich sollte mal die Auswahl des DropDowns bleiben, wenn ich einen zusätzlichen Slot generiere.
das erwartet man ja auch

In der Mitte muss ich ja nichts entfernen, die kann ich ja von Hand direkt wieder ändern...
das habe ich nicht ganz verstanden. du meinst nicht, daß wenn du in der mitte etwas entfernen willst, du das letzte löschst und dann ab dem eigentlich zu löschendem aus der mitte anfängst alle werte zu ändern?
 
Ich weiß ja nicht, was ihr immer mit euren dynamisch erzeugten Klassen bzw. IDs habt...
Code:
<!DOCTYPE html>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Fenstertitel</title>
<style type="text/css">
#dummySelect {
	display: none;
}
</style>
</head>
<body>
	<select id="dummySelect">
		<option>1</option>
		<option>2</option>
		<option>3</option>
		<option>4</option>
		<option>5</option>
		<option>6</option>
	</select>
	<button id="add">+</button>
	<ol id="list"></ol>
	<script type="text/javascript" src="//kkjs.kkapsner.de/modules/kkjs.load.js?modules=sprintf"></script>
	<script type="text/javascript">
	kkjs.event.add(kkjs.$("add"), "click", function(){
		var list = kkjs.$("list");
		var select = kkjs.$("dummySelect").cloneNode(true);
		select.id = "";
		var li = kkjs.node.create({
			tag: "li",
			parentNode: list,
			childNodes: [
				kkjs.sprintf("Slot %d: ", list.getElementsByTagName("li").length + 1),
				select,
				{
					tag: "button",
					innerHTML: "−",
					events: {
						click: function(){
							kkjs.node.remove(li);
							kkjs.css.$("li", {node: list}).forEach(function(li, i){
								li.firstChild.nodeValue = kkjs.sprintf("Slot %d: ", i + 1)
							});
						}
					}
				}
			]
		});
	});
	</script>
</body>
</html>
 
Guten Tag miteinander
Etwas spät, aber der letzte Monat war etwas ausgebucht :)
Vielen Dank für eure Hilf, jetzt muss ich aber zuerst mal mit diesem Script klar kommen.

@kkapsner
Ich blick bei deinem Code noch nicht so ganz durch.
Was ungefähr passiert kann ich nachvollziehen, aber wenn ich jetzt versuche, das Ganze in ein Formular einzubauen scheitere ich...
Wie wird das Select-Feld bereitgestellt? Also wo kann ich mit meinem <form> ansetzen, damit ich das sauber in das Formular bekomme?

Danke vielmals für eure Hilfe und liebe Grüsse
befubo
 
Die <select>s werden innerhalb des <ol id="list"> eingefügt. Wenn du also um dieses <ol> dein <form> machst, kannst du die Daten auch abschicken.

PS: Ich verwende da oben mein eigenes Framework. Du darfst das schon auch benutzen, ist nur nicht wirklich weit verbreitet. Hab' das mal auf natives JS umgeschrieben:
Code:
	<script type="text/javascript">
	document.getElementById("add").addEventListener(
		"click",
		function(){
			var list = document.getElementById("list");
			var select = document.getElementById("dummySelect").cloneNode(true);
			select.id = "";
			var li = document.createElement("li");
			li.appendChild(document.createTextNode("Slot " +(list.getElementsByTagName("li").length + 1) + ":"));
			li.appendChild(select);
			
			var button = document.createElement("button");
			button.innerHTML = "−";
			button.onclick = function(){
				li.parentNode.removeChild(li);
				Array.prototype.forEach.call(
					list.getElementsByTagName("li"),
					function(li, i){
						li.firstChild.nodeValue = "Slot " + (i + 1) + ": ";
					}
				);
			};
			li.appendChild(button);
			
			list.appendChild(li);
		},
		false
	);
	</script>
 
Hallo kkapsner

Danke für deine Antwort.
Das mit dem Formular ist jetzt klar, aber was ja jetzt noch fehlt ist, dass jedes Select einen eigenen Namen erhält.
Wenn ich ja jetzt den "dummySelect" so übergebe, kann ich ja meine Werte nicht identifizieren, da der Name fehlt. Wenn ich den Namen im dummySelect definiere, ist der ja nicht dynamisch und er überschreibt das value immer mit der letzten Auswahl.
So wie ich deinen Code verstanden habe, kann man ja nicht einfach bei jedem Durchlauf den Namen vom <select> anpassen.

Hier ja mal die Testseite:
Fenstertitel

Ich lasse die Übergaben per print_r ausgeben und da sieht man ja, dass er natürlich immer den letzten Value nimmt, da der Name nicht dynamisch ist...
Wie ich das in einem php script mit while lösen könnte ist mir klar, aber wie ich das in dein JS einbauen soll ist dafür gar nicht klar :D

Besten Dank für deine Zeit und liebe Grüsse
befubo
 
Man könnte schon den Namen im Durchlauf dynamisch ändern. Würde ich aber nicht machen.

Wenn du dem "dummySelect", das auf jeden Fall außerhalb des <form> definiert sein muss, jetzt einen Namen mit "[]" am Ende gibst, bekommst du in PHP automatisch einen Array mit den ganzen Werten.
 
Zurück
Oben