Parameter aus Formular an Funktion übergeben

  • Hallo,

    ich bin dabei den Warenkorb zu einer Reiseseite zu gestalten und habe hierfür bereits eine Tabelle erstellt. In dieser Tabelle tauchen der Artikel (die Reise), die Personenanzahl, Kinderanzahl, sowie Einzelpreis und Gesamtpreis auf. Mittels + und - Buttons kann die Personen- bzw. Kinderanzahl verändert werden. Dabei werden per "onclick" Funktionen ausgeführt, die die Gesamtpreise berechnen, sowie auch die Summe des Warenkorbs. Mich stört nun, dass ich für jede Artikelzeile jeweils immer die gleichen Funktionen schreiben muss. Ich hätte z.B. gerne eine + Funktion, der die richtigen Parameter übergeben werden, anstatt in jeder Funktion immer nur mit document.getElementByID zu arbeiten. Aber seht selbst.


    Folgendes ist ein JS-Auszug. Diese Funktionen ändern die Personenanzahl und errechnen den Gesamtbetrag. Summe() errechnet die Summenpreis des Warenkorbs.


    Dies ist ein Ausschnitt aus der Tabelle. (Eine Tabellenzeile)


    Der Code funktioniert wie er soll. Aber für jede weitere Zeile, müsste ich beispielsweise die abwählen-Funktion erneut schreiben und dann abwählen1, abwählen2... nennen. Wie kann ich der Funktion die Parameter Kind, Person, Gesamtpreis übergeben, sodass ich die abwählen-Methode nur einmal schreiben muss? Das Problem ist hierbei, dass sich die Werte für Kind oder Person jedes Mal ändern, sodass ich nicht einfach abwählen(2.35, 4, 6) schreiben kann.


    Und ich bin sicher, dass ich den Code etwas kompliziert geschrieben habe. Für generelle Vereinfachungen oder Verbesserungen bin ich auch dankbar.

  • Solch eine Aufgabe tritt relativ häufig auf. Ich schlage folgende Lösung vor:

    Die IDs durch Klassen ersetzen. Hat man jetzt z. B. den Plus-Button, kann man das dazugehörige Eingabefeld mit der Anzahl ermitteln, indem man das Elternelement ermittelt, in dem Fall das <td> und davon ausgehend über die Funktion querySelector mit der Klasse als Parameter das Eingabefeld.

    Außerdem schlage ich vor, um mehrfachen Code zu vermeiden, Herauf- und Herunterzählen mit nur einer Funktion zu erledigen.

    Ich habe davon eine Demo gemacht:

    Ich hoffe, durch die Kommentare ist es verständlich.

  • Sorry erstmal, dass ich mich erst jetzt melde und danke für die ausführliche Antwort.

    Da ist einiges an Code dabei, den ich noch nicht kenne. Ich werde mich da reinlesen. Aber im Groben habe ich es denke ich verstanden. Danke!


    EDIT: Ich hab's durchgearbeitet und es funktioniert wunderbar. Dein Code hat mir gleich mehrere neue Dinge beigebracht. Ein paar Verständnisfragen habe ich aber noch.

    1. Wenn man mittels querySelector nach .nr-person sucht, findet er trotzdem die dazugehörigen Klassen, obwohl sie "nr-person adult" und "nr-person child" heißen. Sucht er sich lediglich den Wortlaut "nr-person" raus?

    2. Ist es bei Javascript üblich Variablen in einer Schleifen zu definieren?

    3. Wozu benötige ich das console.log am Ende der summieren() Funktion?

  • 3. Wozu benötige ich das console.log am Ende der summieren() Funktion?

    Das brauch man nicht.

    Doch in den fall kannst du in der Konsole das Ergebniss sehen.

    Es gibt auch Leute die console.log() nicht nutzen und dafür alert() nehmen.

    Alert() würde auch funktionieren , doch wenn du alert() in einer Endlos Schleife benutzen würdest hast du ein problem, und der Browser könnte abstürzen weil du die Alerts nicht weg klicken kannst ist es schwer das zu beenden.

    Bei console.log sollte das nicht vorkommen, auch eine Endlos Schleife läßt sich dann im normalfall noch beenden

  • Zitat

    1. Wenn man mittels querySelector nach .nr-person sucht, findet er trotzdem die dazugehörigen Klassen, obwohl sie "nr-person adult" und "nr-person child" heißen. Sucht er sich lediglich den Wortlaut "nr-person" raus?

    "nr-person child" ist nicht eine Klasse sondern man kann einem Element mehrere zuteilen, durch Leerzeichen getrennt, und auch mehrere abfragen:

    document.querySelectorAll('.nr-person') würde beide Elemente liefern, Erwachsene und Kinder

    document.querySelectorAll('.nr-person.child') dagegen nur das Eingabefeld für die Kinder

  • Zitat

    2. Ist es bei Javascript üblich Variablen in einer Schleifen zu definieren?

    Ja, häufig ist es sogar erforderlich, z. B. wenn man in einer Schleife HTML-Elemente anlegt:

    Code
    for (let i = 0; i < 10; i++) {
        let inp = document.createElement('input');
        document.getElementById('container').appendChild(inp);
    }

    Weil die Variable innerhalb der Schleife definiert wird, wird bei jedem Durchlauf ein neues Input-Element erzeugt und in der Container mit der ID 'container' eingefügt.

  • Da habe ich gleich das nächste bzw. ein ähnliches Problem. Ich möchte nun eine reset-Funktion schreiben, die ein Inputtextfeld auf Null setzt. Ich habe mich hierbei an obigem Code orientiert und folgendes zusammengebastelt.


    Code
    const buttons = document.querySelectorAll('.delete'); //alle delete-Buttons
    for (let i = 0; buttons.length > i; i++) {
       const thebutton = buttons[i];
       thebutton.addEventListener('click', function () {
          const totalo = this.parentNode.parentNode;
          totalo = totalo.querySelector('.total');        //total = das zu löschende Textfeld
          totalo.value = 0;
          Summe();
       });
    }

    Der Code soll alle delete-Buttons sammeln und für jeden einen Eventhandler registrieren. Da dem Code wieder eine Tabelle zugrunde wäre <td> das Elternelement. Ich benötige aber <tr>, da dass zu löschende Textfeld total in einem anderen <td> liegt, als der delete-Button. Demnach habe ich this.parentNode.parentNode geschrieben. Abschließend sollte dann das total-Textfeld auf Null gesetzt und eine Funktion ausgeführt werden. Es klappt nicht. Wo liegt der/ liegen die Fehler?


    PS: Die klassische reset()-Funktion bringt mir nichts, da sie das komplette Form löscht.

  • Poste am besten auch das HTML, das dazu gehört, denn davon hängt es ab, wie Du im DOM navigieren musst. Von deiner Beschreibung her müsste es funktionieren, denn this.parentNode wäre das <td> und davon das parentNode das <tr>, jedenfalls wenn das HTML so aufgebaut ist wie bisher.

  • Jep, das HTML ist wie oben aufgebaut. Ich habe mal deinen Code kopiert und angepasst. Im Prinzip sind ja nur die letzten beiden <td> wichtig.


    Ich habe schon vermutet, dass <a> ebenfalls als Elternelement zählt und deswegen noch ein parentNode drangehängt, aber das ändert auch nichts.

  • Zitat

    Ich habe schon vermutet, dass <a> ebenfalls als Elternelement zählt und deswegen noch ein parentNode drangehängt, aber das ändert auch nichts.

    Eigentlich trifft das aber zu, das <a> zählt mit. Um das Ganze übersichtlicher zu machen, empfehle ich aber, die Verschachtelung von einem Button in einem <a> wegzulassen. Diese ist nicht valide und das hat seine Gründe: Was soll jetzt beim Klick ausgeführt werden, der click-Handler der Buttons oder das Javascript im href-Attribut des <a>?

  • Es soll beides ausgeführt werden, was auch geklappt hat, als ich noch onclick anstelle von class="delete" verwendet habe. Lösche ich das <a> weg, löst es auch nicht das Problem. Der Code funktioniert dann immer noch nicht.

    Das mit der Verschachtelung hat mich aber auch schon gestört. Da versuche ich hinterher noch, dass irgendwie zusammenzufassen.


    Habs jetzt erstmal umgeschrieben.

    Code
    <td>
        <input type="button" value="X" class="delete" onclick="blend_out('zeile1')">
    </td>
  • Zitat

    Da versuche ich hinterher noch, dass irgendwie zusammenzufassen.

    Besser gleich weil die Verschachtelung die Ursache dafür sein kann, dass es nicht funktioniert. Du kannst ja beide Aktionen in einem Eventhandler zusammen fassen.

  • Ja, stimmt schon. Es handelt sich auch nur um diese kleine Funktion.

    Code
    function blend_out(id) {
       document.getElementById(id).style.display = 'none'
    }

    Die lege ich in den geschriebenen Eventhandler rein. Nur funktioniert es dennoch nicht.

  • Genau, der Button soll dazu dienen, dass der "Kunde" einen Artikel aus dem Warenkorb rauslöschen kann. Er löscht den Gesamtpreis der Tabellenzeile. Danach wird die Summenfunktion ausgelöst, die sämtliche Gesamtpreise aller Zeilen zusammenrechnet und dann die Endsumme des gesamten Warenkorbs ausgibt. Im Endeffekt wird also nur die Endsumme aktualisiert. Als optische Unterstützung habe ich dazu die blend_out Funktion eingebaut, die die Tabellenzeile zusätzlich ausblendet, damit der Kunde auch direkt sieht, dass der Artikel "gelöscht" ist.


    Die Summenfunktion habe übrigens auch nur aufgrund deiner Hilfe basteln können. ;) Die funktioniert. Da brauchen wir nix dran machen.

  • Denke, jetzt verstehe ich es vollständig. Ich habe jetzt in meiner Testdatei die Zeile mit dem Löschbutton hinzu gefügt:

    Wenn ich jetzt dein Javascript aus Posting #8 nehme und nur die Namen ein wenig ändere, funktioniert es, das Eingabefeld für den Gesamtpreis wird gelöscht, wenn man das X klickt.

  • Erst dachte ich, es kann nicht an den Namen gelegen haben, aber doch. Der Fehler liegt hier:

    Code
    const totalo = this.parentNode.parentNode;
    totalo = totalo.querySelector('.total');        //total = das zu löschende Textfeld

    const bedeutet, dass man eine Konstante definiert, d. h. eine Variable die im weiteren Verlauf nicht geändert werden kann. Daher schlägt die Zuweisung in der zweiten Zeile fehl. Ich würde erwarten, dass das auch in der Console angezeigt wird. Hättest Du totalo mit let definiert, hätte es sicher funktioniert.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!