Rolf B: Variable in Javascript übergeben bei dynamischen Inputfeldern

Beitrag lesen

Hallo Lynnv und Martl,

ist ja schön, dass ihr beide da einen Fehler seht - ich sehe keinen. Aber wenn's geholfen hat, will ich nichts sagen 😀

Zum Problem "115" - dass dein Form mehrere Gruppen von Zahlenwerten enthält und du pro Gruppe addieren willst, das hast Du nicht verraten.

D.h. es sieht bei Dir stark reduziert so aus:

<form name="Bestellungen">
<div>
   <input value="number" oninput="calculate()">
   <input value="number" oninput="calculate()">
   <output id="summe1"></output>
</div>
<div>
   <input value="number" oninput="calculate()">
   <input value="number" oninput="calculate()">
   <output id="summe2"></output>
</div>
</form>

Das kriegt man eigentlich ganz gut in den Griff. Es wird nur ein bisschen magischer als vorher 😉

Zunächst einmal sorgen wir dafür, dass der Container, der die Gruppe enthält, in der div-Suppe eindeutig auffindbar ist. Dafür könnte man eine Klasse vergeben, aber schöner ist das fieldset Element, es zeichnet automatisch einen Gruppenrahmen und über das <legend> Element kann man einen Titel vergeben. Muss man aber nicht.

Das Ausgabefeld identifiziert man am besten über eine Klasse (id muss eindeutig sein, class nicht). Und die Eventhandler registrieren wir anders, über addEventListener auf dem form-Element. Aus Gründen...

<form name="Bestellungen">
<fieldset>
   <input value="number">
   <input value="number">
   <output class="summe"></output>
</fieldset>
<fieldset>
   <input value="number">
   <input value="number">
   <output class="summe"></output>
</fieldset>
</form>

Das ist ein Prinzip-HTML, nicht das, wie es fertig aussehen soll. Labels und so brauchst Du natürlich immer noch.

Das folgende Script muss hinter dem Form im HTML stehen, sonst findet es das Form nicht.

document.forms.Bestellungen.addEventListener("input", calculate);

function calculate(event) {
   let gruppe = event.target.closest("fieldset");
   let mengen = gruppe.querySelectorAll("input[type=number]");
   ...summe bilden
   let ausgabe = gruppe.querySelector(".summe");
   ausgabe.textContent = summe;
}

Zeile 1 sucht das Bestellungen-Form und registriert darauf einen Handler für das input-Event. Das ist ähnlich wie oninput="calculate()", der Unterschied ist, dass Du hier noch ohne weitere Mühe eine Wert übergeben bekommst, das „Event-Objekt“. Das brauchen wir.

Events haben eine interessante Eigenschaft: Sie blubbern wie Luftbläschen im Wasser nach oben. Ein input-Event, das auf einem Eingabefeld ausgelöst wird, wird also als erstes auf dem input-Element selbst gefeuert, dann auf dem Elternelement, etc, bis ganz nach oben, dem body. Auf jeder Ebene kann darauf reagiert werden.

Damit man dann weiß, wo das Event herkam, gibt es den event-Parameter und die target-Eigenschaft. Die enthält das input-Element. Darauf rufe ich die closest-Methode auf, die sucht die Liste der Elternelemente durch bis sie den CSS Selektor findet, den man übergeben hat. .closest("fieldset") sucht also in der Elternkette des input-Elements ein fieldset Element, und das ist auch der Grund, warum ich die Abänderung von div in fieldset vorgeschlagen habe. divs hast Du viele, aber ein Fieldset gibt es in der Elternkette nur einmal.

Die Summierung erfolgt dann wie bekannt, mit dem fieldset als Ausgangsbasis, und danach suche ich mit querySelector ein Element im Fieldset, dass die Klasse "summe" trägt (dafür ist der Punkt in ".summe" da).

Du hast also nun etwas Anpassungsaufwand im PHP und etwas Arbeit im Stylesheet, weil Du das Setzen des Rahmens anpassen musst.

Alles klar?

Rolf

--
sumpsi - posui - obstruxi