Lynnv: Variable in Javascript übergeben bei dynamischen Inputfeldern

Hallo Ihr Lieben,

bin Neuling in Javascript und benötige Hilfe.

Ich habe ein Formular, welches Daten aus einer Datenbank liest und dann Zeilenweise in Inputfelder ausgibt.

Nun möchte ich, dass per Javascript mit onkeyup die Werte einer Zeile addiert werden.

Im Internet habe ich einen Code gefunden, mit dem es bei einfachen Inputfeldern funktioniert, aber da ist ja jedes Feld auch nur einmal vorhanden.

  <form id="Bestellungen" name="Bestellungen"  method="post" action="http://testseite.designbock.de/bestellungen/" > ........


...............................

                               <div style="width:100px;float:left">           
                                   1x<br> Fingerlinge
                                   <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B8[<?php echo $index?>]' value='<?php echo $B8?>'/>            
                               </div>
                               <div style="width:100px;float:left">
                                   1x<br> Sch&uuml;rze      
                                    <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B9[<?php echo $index?>]' value='<?php echo $B9?>'/>             
                               </div>
                               <div style="width:150px;float:left">
                                   Notizen        
                                    <textarea style="min-height:0px" cols="50" rows="2" name='Notizen[<?php echo $index?>]'><?php echo $Notizen?></textarea>            
                               </div>
                               <div style="width:100px;float:left">
                                   Summe        
                                    <span id="output111">Startwert</span>             
                               </div>
                      </div>
                  </div>
              </div>
          </div>
      </div>                                       
                  <?php
                     $index++;  
          }  
    }
              if ($_SESSION['pruef'] == 0 )
              {
                 echo '                                      
                <input type="submit" name="Absenden" value="Absenden">';                   
              }
              if ($_SESSION['pruef'] == 1 )
              {
                  echo '                                         
                  <input type="submit" name="Speichern" value="Speichern">';
              } 
              echo ' </form>  '; 
?>
 
*************************************************************************************************************
Dies ist der Code aus dem Internet

 <script type="text/javascript"><!--
 
 function calculate() {
 	input1 = parseFloat( document.formu.input1.value.replace(/,/ , ".") );
 	input2 = parseFloat( document.formu.input2.value.replace(/,/ , ".") );
 	
 	document.getElementById("output").innerHTML= (input1 + input2).toString().replace(/\./ , ",");

 	input11 = parseFloat( document.Bestellungen.B8[1].value.replace(/,/ , ".") );     ************* Diesen Code habe ich hizugefügt
 	input22 = parseFloat( document.Bestellungen.B9[1].value.replace(/,/ , ".") );     ************* Diesen Code habe ich hizugefügt
                                       
 	document.getElementById("output1").innerHTML= (input11 + input22).toString().replace(/\./ , ",");     ************* Diesen Code habe ich hizugefügt   
 }


 //--></script>
 

 	<form name="formu" action=""><div>
 		<input type="text" name="input1" size="15" value="Eingabe 1" onkeyup="calculate()"/><br />
 		<input type="text" name="input2" size="15" value="Eingabe 2" onkeyup="calculate()"/><br />
     	<!--<input type="text" name="output" size="15" value="Ausgabe" /><br /> -->
 		</div></form>
 	 	<span id="output">Startwert</span>

Wie spreche ich die Felder richtig an ?

LG

Lynn

  1. @@Lynnv

    Nun möchte ich, dass per Javascript mit onkeyup die Werte einer Zeile addiert werden.

    Wie im anderen Thread gerade gesagt wurde, ist keyup das falsche Event.


    Im Internet habe ich einen Code gefunden, mit dem es bei einfachen Inputfeldern funktioniert

    Welcher unzählige Fehler enthält und nicht funktioniert.

    <div style="width:100px;float:left">           
      1x<br> Fingerlinge
      <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B8[<?php echo $index?>]' value='<?php echo $B8?>'/>            
    </div>
    

    Das Eingabefeld hat keine Beschriftung. Das „funktioniert“ nur für Nutzerinnen, die die Seite visuell wahrnehmen und das in der Nähe stehende „1x Fingerlinge“ als Beschriftung zuordnen. Für alle anderen Nutzerinnen funktioniert das nicht.

    Alle Eingabefelder müssen ein label haben, bspw. so:

    <label style="width:100px;float:left">           
      1x<br> Fingerlinge
      <input style="max-width:70px; max-height:12px" min="0" type="number" onkeyup="calculate()" name="B8[<?php echo $index?>]" value="<?php echo $B8?>"/>           
    </label>
    

    oder mit for und ID:

    <div style="width:100px;float:left">           
      <label for="B8[<?php echo $index?>]">1x<br> Fingerlinge</label>
      <input style="max-width:70px; max-height:12px" min="0" type="number" onkeyup="calculate()" id="B8[<?php echo $index?>]" name="B8[<?php echo $index?>]" value="<?php echo $B8?>"/>
    </div>
    

    Das „1x“ verstehe ich da nicht. Im Übrigen ist ein x kein Malzeichen – das sieht so aus: ×. Wer sich das nicht aus der Zeichentabelle raussuchen möchte, kann in HTML auch &times; verwenden.

    Die Anführungszeichen hab ich mal vereinheitlicht. Du kannst in HTML ' oder " verwenden; es ist aber kein guter Stil, beides zu mischen.

    Zu gutem Stil gehört auch, sämtliche Angaben zur Darstellung im Stylesheet unterzubringen, nicht inline in style-Attributen.

    Wo kommen die Werte $index und $B8 her? Prinzipiell sind alle Daten als potentiell gefährlich anzusehen und müssen beim Kontextwechsel entsprechend behandelt werden – beim Einbringen in HTML mit htmlspecialchars():

    <?php echo htmlspecialchars($index) ?> und
    <?php echo htmlspecialchars($B8) ?>

    (Wofür du auch kurz <?= htmlspecialchars($index) ?> und
    <?= htmlspecialchars($B8) ?> schreiben kannst.)

    Da kommt dann sowas wie name="B8[1]" raus, nicht wahr?

     	input11 = parseFloat( document.Bestellungen.B8[1].value.replace(/,/ , ".") );
    

    Nö, [/] haben in JavaScript eine (mehrere?) Sonderbedeutung. Hier wäre es, auf das zweite(!) Element des Arrays B8 zuzugreifen. Ach, B8 ist gar kein Array, sondern ein String? Dann liefert B8[1] das zweite Zeichen des Strings.

    Das willst du nicht, sondern 'B8[1]' als String. Dann musst du nicht die Schreibweise mit ., sondern die mit [/] verwenden: document.Bestellungen['B8[1]']. Oder (IMHO besser lesbar) document.Bestellungen.elements['B8[1]'].

    Die [/] im Namen des Eingabefeldes verwendest du wegen der serverseitigen Auswertung des Formulars?

    😷 LLAP

    --
    Wenn der Faschismus wiederkehrt, wird er nicht sagen: „Hallo, ich bin der Faschismus.“ Er wird sagen: „Hört auf zu zählen! Ich habe gewonnen!“
    1. Hallo Gunnar,

      WOW, soviel Hilfe investiert, unglaublich !!!

      Muss ich jetzt erst mal verarbeiten, bin total erschlagen.

      LG

      Lynn

  2. Hallo Lynnv,

    ich könnte in's gleiche Horn wie Gunnar stoßen, aber klingt sicher besser, wenn ich Gitarre dazu spielen (wobei das eigentlich Gunnars Instrument ist 😂).

    Vorweg: Arbeitest Du für Designbock oder bist Du dort Kunde?

    Ich werde gleich auch was zu deinem Problem schreiben, aber erstmal kommt mein Gitarrensolo 😉

    1. htmlspecialchars - nicht gedankenlos einsetzen

    Gunnars Hinweis zu htmlspecialchars auf der PHP Seite ist richtig und wichtig, aber eine Prise Salz gehört dazu. Diese Aufbereitung ist an den Stellen erforderlich, wo Daten Strings sind. Also Werte aus $_POST und $_GET, oder Textspalten einer Datenbank (alles, was im DB-Handbuch unter "String Data Types" steht). Bei numerischen Werten ist htmlspecialchars unangebracht, da muss man sich eher überlegen, ob man eine andere Form der Aufbereitung für den Leser braucht (z.B. zwei Nachkommastellen bei Geldbeträgen, Tausendertrenner, etc). In deinem Fall sieht $index nach einem Schleifenzähler oder so etwas aus, das ist ein ganzzahliger Wert der als Ganzzahl ins HTML soll, und den brauchst Du gar nicht zu behandeln. Aber: sowas nie ohne Nachdenken tun. Sobald Du einen Variableninhalt ins HTML einbaust, innehalten, überlegen wo das herkommt, die richtige Behandlung festlegen.

    2. Inkonsistente Eingabefelder

    <input ... name='B8[<?php echo $index?>]' value='<?php echo $B8?>'/>
    

    Das ist widersprüchlich. Der name des input legt nahe, dass es das Feld mit dem Namen B8 mehrfach gibt. Im PHP sollte $B8 demzufolge ein Array sein. Aber du gibst für den value $B8 aus, nicht $B8[$index]. Das passt also nicht zusammen. Entweder beides ein Array, oder beides nicht. Alles andere ist unlogisch.

    3. Lineare Programmierung?!

    1x<br> Fingerlinge
    <input ... value='<?php echo $B8?>'/>
    1x<br> Sch&uuml;rze
    <input ... value='<?php echo $B9?>'/>
    

    Das ist doch eine Art Warenkorb? Warum stehen Bestellmenge und Artikelname da als Konstante? Warum verwaltest Du den PHP-Seitig in unterschiedlichen Variablen - das kann die Verarbeitung nur unnötig kompliziert machen und erfordert sicherlich massive Code-Doppelungen. Es sollte im PHP genau ein fettes Array geben, worin alle Bestellungen stehen und woraus Du die Warenkorbansicht erzeugst.

    Ach ja, und wenn Du deinen HTML Quelltext mit einem Editor bearbeitest, der UTF-8 Codierung beherrscht, und dein Webserver das auch korrekt dem Browser mitteilt, dann kannst Du "Schürze" schreiben statt "Sch&uuml;rze".

    4. Namenswiderspruch

    <span id="output111">Startwert</span> 
    
    document.getElementById("output1").innerHTML = ...; 
    

    getElementById tut genau das: Es sucht das HTML Element mit dieser ID heraus und gibt das entsprechende Objekt aus dem Dokument-Objektmodell (DOM) zurück. Ein Element mit der ID output1 gibt es aber nicht. Es heißt bei Dir output111. Beide Namen sind wenig sinnvoll, überleg Dir einen ordentlichen und verwende ihn konsistent.

    Die Zuweisung an die Eigenschaft innerHTML des output-Elements funktioniert, ist aber eigentlich nicht richtig. Du weist kein HTML zu, sondern Text. Deswegen sollte die Zuweisung an textContent erfolgen, nicht an innerHTML. Damit hängst Du zwar Internet Explorer vor Version 9 ab, aber der interessiert heutzutage wohl niemanden mehr.

    5. Deine eigentlich Frage

    So, und nun zu deinem eigentlichen Problem: Du hast eine variable Anzahl Betragsfelder im Formular und möchtest diese aufsummieren. Eine variable, unbekannte Anzahl verarbeitet man mit einer Schleife.

    Ich habe im folgenden Text übrigens Links in unser Wiki untergebracht, bei Unklarheiten folge erstmal den Links. Möglicherweise hast Du viel Lesebedarf.

    Zum Summieren musst Du die input Elemente erst einmal finden. Das gelingt mit der DOM Methode querySelectorAll. Sie bekommt einen CSS Selektor und liefert alle Elemente im DOM, die darauf passen.

    let betraege = document.forms.Bestellungen.querySelectorAll("input[type=number]");
    

    Das sucht alle input-Elemente mit dem Attribut type="number" heraus und liefert Dir etwas Array-ähnliches: eine NodeList. Die musst Du nun in einer Schleife verarbeiten. Die Anzahl der Elemente in der Nodelist steht wie bei einem Array in der length-Eigenschaft, und wie bei einem Array greifst Du auch auf die Einträge zu.

    let summe = 0;
    for (let i=0; i<betraege.length; i++) {
       let summe = summe + betraege[i].valueAsNumber;
    }
    document.getElementById("output111").textContent = summe;
    

    (an alle Verbesserer: Ich habe .forEach mit Callback bewusst NICHT gezeigt)

    Hey, das war's fast schon. valueAsNumber liefert Dir den numerischen Wert eines type="number" Feldes. Um das Problem "Punkt oder Komma", das Du in deinem Code mit replace behandelt hast, kümmert sich valueAsNumber selbst.

    Die Frage ist noch, ob Du die Summe irgendwie als Betrag formatieren willst. Mit zwei Nachkommastellen und so. Das ist in JavaScript mit Hilfe von Intl.NumberFormat möglich (Infos bei Mozilla. Die letzte Zeile wird dann durch dies hier ersetzt:

    let formatter = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });
    document.getElementById("output111").textContent = formatter.format(summe);
    

    und Du bekommst zwei Nachkommastellen und ein Eurosymbol automatisch dazu.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo Rolf,

      maaaan, auch Du hast soviel Zeit für Deine Hilfe investiert, Ihr seid echt der Wahnsinn - vielen lieben Dank dafür.

      Aber auch hier, das muss ich jetzt erst mal sacken lassen.

      LG

      Lynn

    2. Hallo Rolf,

      nun habe ich mal entsprechend Deiner Hilfe (nochmals vielen Dank !!!) den Code abgeändert, aber es findet keine Ausgabe im Feld output111 statt.

      Ich habe lediglich den Namen betraege gegen mengen ausgetauscht !

      wo habe ich den Fehler eingebaut ?

        ........
                                   <div style="width:100px;float:left">           
                                         1x<br> Fingerlinge
                                         <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B8[]' value='<?php echo $data2['B8']?>'/>            
                                     </div>
                                     <div style="width:100px;float:left">
                                         1x<br> Sch&uuml;rze      
                                          <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B9[]' value='<?php echo $data2['B9']?>'/>             
                                     </div>
                                     <div style="width:150px;float:left">
                                         Notizen        
                                          <textarea style="min-height:0px" cols="50" rows="2" name='Notizen[]'><?php echo $data2['Notizen']?></textarea>            
                                     </div>
                                     <div style="width:100px;float:left">
                                         Summe        
                                          <span id="output111">Startwert</span>             
                                     </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>                                       
                        <?php 
                }  
          }
                    if ($_SESSION['pruef'] == 0 )
                    {
                       echo '                                      
                      <input type="submit" name="Absenden" value="Absenden">';                   
                    }
                    if ($_SESSION['pruef'] == 1 )
                    {
                        echo '                                         
                        <input type="submit" name="Speichern" value="Speichern">';
                    } 
                    echo ' </form>  '; 
      ?>
       
       <script type="text/javascript"><!--
       
       function calculate() {
          let mengen = document.forms.Bestellungen.querySelectorAll("input[type=number]");
          
          let summe = 0;
          for (let i=0; i<mengen.length; i++) {
             let summe = summe + mengen[i].valueAsNumber;
          }
          document.getElementById("output111").textContent = summe;
           }
      
      
       //--></script>
      

      LG

      Lynn

      1. Hallo Lynn,

        mal überlegen:

        function calculate() {
        
            ...
           
            /*Wie oft wird 'summe' in der Funktion initialisiert?*/
        
            let summe = 0;
        
            for (let i=0; i<mengen.length; i++) {
        
               /*Und was passiert hier mit 'summe'? Genau!*/
        
               let summe = summe + mengen[i].valueAsNumber;
        
            }
        
            document.getElementById("output111").textContent = summe;
        
        }
        

        Grüße, Martl

        1. Hallo Martl,

          vielen Dank für Deine schnelle Hilfe.

          Nun funktioniert es.

          LG

          Lynn

          1. Ahhh,

            noch nicht ganz :-(

            Jetzt werden alle Werte addiert, ist eigentlich nicht der Sinn.

            Im Moment wird 115 als Summe angezeigt.

            Ich möchte ja nur die Zeile addiert haben, deswegen hatte ich ja auch die Sache mit dem Index gemacht.

            Ist wohl doch nicht so einfach, also für mich als Unbedarfte.

            LG

            Lynn

            1. Hallo,

              Jetzt werden alle Werte addiert, ist eigentlich nicht der Sinn.

              Das ist aber genau das, was du in der Funktion sagst: Die Menge über die summiert werden soll, sind alle Inputs mit dem Typ Number.

              Im Moment wird 115 als Summe angezeigt.

              Aus deinem Bild wird leider nicht ersichtlich, wo diese Summer herkommt.

              Ich möchte ja nur die Zeile addiert haben, deswegen hatte ich ja auch die Sache mit dem Index gemacht.

              Dann musst die Menge der Inputs geschickter eingrenzen, z.B. über eine Klasse.

              Gruß
              Kalk

              1. Hallo,

                Jetzt werden alle Werte addiert, ist eigentlich nicht der Sinn.

                Das ist aber genau das, was du in der Funktion sagst: Die Menge über die summiert werden soll, sind alle Inputs mit dem Typ Number.

                Im Moment wird 115 als Summe angezeigt.

                Aus deinem Bild wird leider nicht ersichtlich, wo diese Summer herkommt.

                Dazu benötigt man jetzt ja nicht das Bild im Ganzen, ist doch logisch, dass weiter unten irgendwo eine Menge eingetragen ist 😉

                Ich möchte ja nur die Zeile addiert haben, deswegen hatte ich ja auch die Sache mit dem Index gemacht.

                Dann musst die Menge der Inputs geschickter eingrenzen, z.B. über eine Klasse.

                Wenn ich jetzt Java könnte, dann würde ich hier nicht nachfragen - hmmm.

                Aber warum hast Du keine Lösung gepostet, da lobe ich mir den Rolf !!

                Trotzdem Danke

                LG

                Lynn

                Gruß
                Kalk

                1. Hallo Lynnv,

                  Wenn ich jetzt Java könnte, dann würde ich hier nicht nachfragen - hmmm.

                  Java?

                  Aber warum hast Du keine Lösung gepostet, da lobe ich mir den Rolf !!

                  Weil es hier Hilfe zur Selbsthilfe gibt, nicht fertige Lösungen.

                  Bis demnächst
                  Matthias

                  --
                  Du kannst das Projekt SELFHTML unterstützen,
                  indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
                2. Hallo,

                  Dazu benötigt man jetzt ja nicht das Bild im Ganzen, ist doch logisch, dass weiter unten irgendwo eine Menge eingetragen ist 😉

                  Programmieren ist auch rein logisch, trotzdem kriegts nicht jeder hin… 😉

                  Wenn ich jetzt Java könnte, dann würde ich hier nicht nachfragen - hmmm.

                  Java kann ich sogar besser als Javascript...

                  Aber warum hast Du keine Lösung gepostet, da lobe ich mir den Rolf !!

                  … trotzdem erlaube ich mir, hier Lösungswege aufzuzeigen!

                  Trotzdem Danke

                  Danke mir, indem du versuchst, mitzudenken 😛

                  Gruß
                  Kalk

          2. 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
            1. Hallo,

              ist ja schön, dass ihr beide da einen Fehler seht - ich sehe keinen.

              vermutlich kann das let in der Schleife wech? Oder ist das Kunst?

              Gruß
              Kalk

              1. Hallo Tabellenkalk,

                hm, ja. Du heißt Kalk und bei mir rieselt er. Das hätte ich sehen können.

                Rolf

                --
                sumpsi - posui - obstruxi
            2. Also ich habe jetzt zwar nichts von Gruppen geschrieben, aber von Summen in einer Zeile 😉

              LG

              Lynn

            3. Hallo Rolf,

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

              da gibt mir sogar die Konsole recht:

              Uncaught ReferenceError: Cannot access 'summe' before initialization

              Grüß, Martl

            4. Hallo Rolf,

              leider nicht alles klar.

              Ich habe jetzt dieses fieldset eingebaut, aber jetzt kommt gar keine Summe mehr.

                                             <fieldset>
              
                                                 1x<br> Handschuh
                                                  <input style="max-width:70px; max-height:12px" min="0" type="number" class="form-control" onkeyup="calculate()" name='B1[]' value='<?php echo $data2['B1']?>'/>
                                                  <input type='hidden' name='PATNR[]' value='<?php echo $data2['PATNR']?>'/>
                                                  <input type='hidden' name='EdatumI[]' value='<?php echo $data2['Edatum']?>'/> 
                                                 H&auml;nde Desinfekt.
                                                  <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()"  name='B2[]' value='<?php echo $data2['B2']?>'/>          
                                                 Fl&auml;chen Desinfekt. <br>  1000 ml / 500 ml
                                                  <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B3[]' value='<?php echo $data2['B3']?>'/> 
                                                  <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B4[]' value='<?php echo $data2['B4']?>'/> 
                                                 Sch&uuml;rze waschbar
                                                 <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B5[]' value='<?php echo $data2['B5']?>'/>             
                                                 1x<br> Bettschutz
                                                  <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B6[]' value='<?php echo $data2['B6']?>'/>             
                                                 1x<br> Mundschutz
                                                  <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B7[]' value='<?php echo $data2['B7']?>'/>             
                                                 1x<br> Fingerlinge
                                                 <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B8[]' value='<?php echo $data2['B8']?>'/>            
                                                 1x<br> Sch&uuml;rze      
                                                  <input style="max-width:70px; max-height:12px" min="0" type='number' onkeyup="calculate()" name='B9[]' value='<?php echo $data2['B9']?>'/>             
                                             </div>
                                             <div style="width:150px;float:left">
                                                 Notizen        
                                                  <textarea style="min-height:0px" cols="50" rows="2" name='Notizen[]'><?php echo $data2['Notizen']?></textarea>            
                                             </div>
                                             </fieldset>
                                             <div style="width:100px;float:left">
                                                 Summe        
                                                  <output class="summe"></output>           
                                             </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>                                       
                                <?php 
                        }  
                  }
                            if ($_SESSION['pruef'] == 0 )
                            {
                               echo '                                      
                              <input type="submit" name="Absenden" value="Absenden">';                   
                            }
                            if ($_SESSION['pruef'] == 1 )
                            {
                                echo '                                         
                                <input type="submit" name="Speichern" value="Speichern">';
                            } 
                            echo ' </form>  '; 
              ?>
               
               <script type="text/javascript"><!--
               
                 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;
              
              }
               //--></script>
              

              Bei Deinem ersten Beispiel hattest Du ja

              document.getElementById("output111").textContent = summe;

              Dies ist für mich verständlich. Jetzt ist diese Zeile ja nicht mehr da, oder hätte ich die stehen lassen sollen ? Aber nö, habe es versucht, geht trotzdem nicht. In der Javascriptfunktion ist ja die Variable ausgabe vorhanden, aber was passiert mit dieser ?

              LG

              Lynn

              1. Hmmm,

                Javascript ist ziemlich schwer ! Ich habe nun den ganzen Tag damit verbracht, diese Zeilen zu verstehen, aber komme nicht weiter.

                Ich wollte jetzt einen einfachen alert('Hallo Welt') einbauen, aber nicht mal dies funktioniert.

                Da kann was nicht stimmen dachte ich und habe weiter recherchiert und bin dabei auf die Konsole gestossen. Dort werden ja Fehler angezeigt, sehr schön. Aber wo soll man nun z.B. dieses event definieren, das angemeckert wird.

                Vielleicht sollte ich jetzt ins Bett gehen, sitze da ja schon zu lange dran und sehe nur noch **** ;-(

                Müde Grüße sendet

                Lynn

                1. Hallo Lynnv,

                  äh, warum er event nicht kennt, ist mir gerade auch nicht klar. Benenn das Ding in den beiden Zeilen 23108 und 23109 mal um, z.B. in ev. Ein Parametername namens event sollte eigentlich kein Problem sein?! Welcher Browser ist das?

                  Ach - moment - hast Du die oninput-Attribute im HTML noch drin? Die müssen weg, die rufen calculate ohne Parameter auf und das würde den Bums erklären. Die werden ja durch die Registrierung mit addEventListener ersetzt.

                  Dass er summe nicht kennt, ist klar, du hast ja die Summierung nicht drin. Da wo uch "...summe bilden" geschrieben hatte, da muss das noch hin, so wie Du es vorher hattest.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Sehr frühes Guten Morgen,

                    na Ihr Zwei, leidet Ihr auch an schweren Depressionen und könnt nicht schlafen ?

                    Ja, ich hatte oninput noch drin und wenn man diese entfernt funktioniert es auch. Bin sehr glücklich !!!! Vielen Dank an Euch.

                    Warum jetzt aber trotz Erfolg noch dieses event angemeckert wird, ist schon seltsam

                    Vielleicht noch eine kleine Frage zu der DIV-Suppe, wie Du es so schön definiert hast. Nach dem die weg ist, werden die Felder ja nicht mehr nebeneinander angeordnet. Kann ich diese DIVS wieder benutzen oder muss ich nun Tabellen anwenden ?

                    Tabellen sind doch verpönt, oder ?

                    So meine Lieben, nun versuche ich es noch einmal, also das Schlafen, hoffentlich lässt der Tinnitus es zu ;-)

                    Vielen herzlichen Dank nochmals !!!!!

                    LG sendet

                    Lynn

                    1. Hallo Lynnv,

                      Warum jetzt aber trotz Erfolg noch dieses event angemeckert wird, ist schon seltsam

                      Guck genau hin: da steht "oninput" dabei. Das ist der Aufrufstapel - welche Funktion hat welche aufgerufen, bis der Code an dieser Stelle war. Offenbar hast Du irgendwo noch ein oninput übersehen.

                      Wenn die Anordnung nicht mehr stimmt, nachdem Du ein div durch ein fieldset ersetzt hast, dann musst Du gucken was Du in deinem Stylesheet nachjustieren musst, damit es wieder passt. Aber eigentlich - du floatest die Sachen nebeneinander, müsste eigentlich erhalten bleiben. Du hast es doch mit floats erzeugen können, dann müsstest Du durch Vergleichen alt/neu auch rauskriegen, was da grad nicht tickt.

                      Statt float kann man besser Flexbox verwenden oder Grid, das ist aber auch nicht trivial. Deine floats kennst Du und wenn's für Dich passt, dann bleib dabei. Oder lies Dir Flexbox und Grid in unserem Wiki durch. Aber eine Forenbegleitung um das bei Dir einzubauen mach ich nicht, das ist zu wüst.

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                      1. Hallo Rolf,

                        ja, da war noch ein onklick drin, danke.

                        Ich habe da noch eine Frage.

                        Nun habe ich auch Preise eingefügt und die Mengen multipliziert, dank Deiner Hilfe habe ich dies hinbekommen.

                        Aber jetzt scheitere ich an Folgendem:

                        Ich möchte bei Überschreitung des Gesamtpreises von 60,00, dass der Betrag mit rotem Hintergrund und einem Warntext versehen wird, ansonsten nur der Betrag in grün.

                        Soweit so gut, aaaaber, wenn ich beim nächsten Patienten bin, und der Gesamtpreis bleibt unter 60, bzw.60, dann wird aber der vorherige auch grün, obwohl größer 60.

                         <script type="text/javascript"><!--
                         
                        document.forms.Bestellungen.addEventListener("input", calculate);
                        
                        function calculate(event) {
                           var matches = document.querySelectorAll("fieldset");
                            for (let iy=0; iy<matches.length; iy++) {
                        
                               let gruppe = event.target.closest("fieldset");
                               let mengen = gruppe.querySelectorAll("input[type=number]");
                               let preise = gruppe.querySelectorAll("input.preisss");
                               let summe = 0;                                                                          
                               let preisesu = 0;
                               
                               for (let i=0; i<mengen.length; i++) {
                                   summe = summe + mengen[i].valueAsNumber;
                               }
                               for (let iz=0; iz<preise.length; iz++) {
                                   preisesu = preisesu + parseFloat(preise[iz].value) * mengen[iz].valueAsNumber;
                               }   
                               let ausgabep = gruppe.querySelector(".preise");
                                  
                               if (preisesu > 60) {
                                    document.getElementsByTagName('output')[iy].style.backgroundColor = 'red';
                                    document.getElementsByTagName('output')[iy].style.color = 'white';
                                    ausgabep.textContent = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(preisesu) + " Achtung - Der Maximalbetrag von 60,- Euro wurde überschritten !";
                                }
                                else{
                                   document.getElementsByTagName('output')[iy].style.backgroundColor = 'white';
                                   document.getElementsByTagName('output')[iy].style.color = 'green';
                                   ausgabep.textContent = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(preisesu);
                                }        
                           }
                        }                                              
                        
                         //--></script>
                        

                        Wenn ich nun den esten Patienten verändere, kommt die rote Zeile - dies ist korrekt so.

                        Nun bearbeite ich den 2. Patienten und der wird in grün - das ist gut. Jedoch wird der obere Patient ebenfalls grün - das ist schlecht.

                        Wo liegt mein Fehler, bzw. geht das überhaupt ??

                        LG sendet Dir

                        Lynn

                        1. Hallo Lynnv,

                                 let ausgabep = gruppe.querySelector(".preise");
                          
                                 if (preisesu > 60) {
                                      document.getElementsByTagName('output')[iy].style.backgroundColor = 'red';
                                      document.getElementsByTagName('output')[iy].style.color = 'white';
                                      ausgabep.textContent = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(preisesu) + " Achtung - Der Maximalbetrag von 60,- Euro wurde überschritten !";
                                  }
                                  else{
                                     document.getElementsByTagName('output')[iy].style.backgroundColor = 'white';
                                     document.getElementsByTagName('output')[iy].style.color = 'green';
                                     ausgabep.textContent = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(preisesu);
                                  }      
                          

                          Ich mutmaße, dass Du mehr output-Elemente hast als Du glaubst und deswegen iy nicht der richtige Index ist. Aber das ist nur geraten, dazu müsste man dein HTML kennen.

                          Man sollte einen robusteren Ansatz verfolgen. Steht in ausgabep nicht das output-Element drin, das Du stylen möchtest? Wenn ja, dann ändere einfach ausgabep.style ab, statt erneut mit getElementsByTagName über das ganze Dokument zu laufen.

                          (Exkurs: Verbesserungspotenzial)

                          Eigentlich sollte man auch die styles nicht direkt zuweisen. Dass Klassen und ein Stylesheet (eine .css Datei oder eine <style> Abteilung im <head> Bereich deines Dokuments) die bessere Vorgehensweise sind, hatten wir Dir schon gesagt. Wenn Du das noch nicht kennst, findest Du dazu eine Menge in unserem Wiki. Ein max-height auf einem input-Element ergibt übrigens meiner Meinung nach keinen Sinn, das ist ein inline-Element, das macht sich seine Höhe selbst.

                          Mit Klassen kann man es so machen, dass Du die classList von ausgabep veränderst (vorausgesetzt, ausgabep ist das output-Element, das zu stylen ist). Das geht so:

                          let preisText = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(preisesu);
                          
                          if (preisesu > 60) {
                             ausgabep.classList.add("zu-hoch");
                             ausgabep.classList.remove("ok");
                             ausgabep.textContent = preisText + " Achtung - ...";
                          }
                          else {
                             ausgabep.classList.remove("zu-hoch");
                             ausgabep.classList.add("ok");
                             ausgabep.textContent = preisText;
                          }
                          

                          Aspekt 1: Den Betrag nur einmal formatieren Aspekt 2: Styling über Klassen. Im CSS schreibst Du

                          .preise.ok {
                             color: green;
                             background-color: white;
                          }
                          .preise.zu-hoch {
                             color: white;
                             background-color: red;
                          }
                          
                          

                          Wenn Du noch gar kein Stylesheet drin hast und Dir das zu kompliziert wird, dann vergiss das wieder. Aber die Idee, den Text nur einmal zu formatieren, könntest Du aufgreifen.

                          (Exkurs Ende)

                          Wenn das Element in ausgabep und das output-Element, das Du stylen willst, verschiedene Elemente sind - hm. Dann schauen wir noch mal. Sieht das HTML noch so aus, wie Du am 12.11. um 16:00 gepostet hast? Oder ist das output-Element mittlerweile ins fieldset hinein gewandert? Vielleicht zeigst Du das aktuelle HTML nochmal. Den Eingabebereich von 1xHandschuhe bis 1xSchürze (meinst Du da Einweg-Artikel? Sollte man das dann nicht auch so schreiben? Aber ok, es ist euer Jargon...). Aber ich würde gerne das Fieldset und den output-Bereich dazu sehen.

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                          1. Hallo,

                            Hallo Lynnv,

                            Eigentlich sollte man . . .

                            … sich überlegen, ob das wirklich so geschickt ist, in der Ansicht gleich mehrere Patienten darzustellen. Sicherer ist es, immer nur eine Person zur Zeit zu bearbeiten.

                            Gruß
                            Kalk

                            1. Hallo Kalk,

                              das stimmt absolut. Aber wenn man über 300 Patienten einzeln aufrufen muss, ist auch doof.

                              LG

                              Lynn

                          2. Hallo Rolf,

                            das output ist pro fieldset nur 1 mal drin:

                                                           <div style="width:100px;float:left">           
                                                               1x<br> Fingerlinge
                                                               <input style="max-width:70px; max-height:12px" min="0" type='number' name='B8[]' value='<?php echo $data2['B8']?>'/>
                                                               <input style="max-width:70px; max-height:12px" min="0" class="form-control preisss" name='B8P[]' value='<?php echo $data2['B8P']?>'/>             
                                                           </div>
                                                           <div style="width:100px;float:left">
                                                               1x<br> Sch&uuml;rze      
                                                                <input style="max-width:70px; max-height:12px" min="0" type='number' name='B9[]' value='<?php echo $data2['B9']?>'/>
                                                                <input style="max-width:70px; max-height:12px" min="0" class="form-control preisss" name='B9P[]' value='<?php echo $data2['B9P']?>'/>              
                                                           </div>
                                                           <div style="width:150px;float:left">
                                                               Notizen        
                                                                <textarea style="min-height:0px" cols="50" rows="2" name='Notizen[]'><?php echo $data2['Notizen']?></textarea>            
                                                           </div>
                                                           <div style="width:650px;float:left">       
                                                               Preise
                                                               <output class="preise"></output> 
                                                            </fieldset>
                                                  </div>
                                              </div>
                                          </div>
                                      </div>
                                  </div>                                       
                                              <?php               $indexi++;
                                      }  
                                }
                                          if ($_SESSION['pruef'] == 0 )
                                          {
                                             echo '                                      
                                            <input type="submit" name="Absenden" value="Absenden">';                   
                                          }
                                          if ($_SESSION['pruef'] == 1 )
                                          {
                                              echo '                                         
                                              <input type="submit" name="Speichern" value="Speichern">';
                                          } 
                                          echo ' </form>  '; 
                            ?>
                            

                            Ich habe Deinen Rat mit Stylesheet befolgt, aber nun ist der Effekt umgekehrt: Der 2. Patient ist nun rot, obwohl er kleiner als 60 ist.

                            LG

                            Lynn

                            1. Hallo Lynnv,

                              man darf Code nie einfach abschreiben, da kann immer ein Fehler drin sein. Diesmal: die Klassennamen waren nicht konsistent, das kommt davon, wenn man sich mittendrin was anderes überlegt.

                              Also: Klassennamen sind jetzt "ok" und "zu-hoch". Im "zu teuer" Fall wird zu-hoch gesetzt und ok entfernt, und im "gut" Fall umgekehrt. Und im CSS müssen die Klassen natürlich entsprechend genutzt werden.

                              Guck Dir das Codestück in meinem Posting nochmal an, ich habe es editiert.

                              Und guck Dir dein HTML an, die div-Gruppe um das preise-Output wird nicht geschlossen.

                              Rolf

                              --
                              sumpsi - posui - obstruxi
                              1. Lieber Rolf,

                                Du bist ein echt coooler Typ !!!!

                                Es funktioniert nun einwandfrei, dank Deiner unendlichen Geduld und großartigen Unterstützung.

                                Ja, Du hast recht, mit dem Code abschreiben, aber vielleicht (ganz sicher) sitze ich auch schon wieder zu lange dran.

                                Dir einen schönen Sonntag und gute Nacht.

                                Lynn

                                1. Hallo Rolf,

                                  habe jetzt wieder ein Problem, bei dem ich nicht weiter komme, vielleicht hast Du ja Lust und vor allem Zeit mal drüber zu schauen.

                                  Ich habe nun die Preise als hidden umgestellt, sollen nicht angezeigt werden. Dann sollen gewisse Artikel bei manchen Patienten ebenfalls nicht angezeigt werden.

                                  Wenn bei einem Patient alle Artikel angezeigt werden, funktioniert alles noch einwandfrei. Jedoch wenn ein Artikel nicht angezeigt wird, dann erscheint

                                  Uncaught TypeError: mengen[iz] is undefined

                                  mit alert(mengen.length) wird die korrekte Anzahl an Feldern angezeigt.

                                  LG sendet

                                  Lynn

                                  1. Hallo Lynnv,

                                    du solltest sowas nicht mit alert debuggen. Beschäftige Dich mit den Entwicklerwerkzeugen deines Browsers, da kannst Du im Sourcecode Unterbrechungspunkte (Breakpoints) setzen, du kannst Variablen abfragen, du kannst - wenn Du auf einem Breakpoint hältst, in der Konsole JavaScript Ausdrücke eingeben die dann im Kontext des Breakpoints abgearbeitet werden (wie z.B. mengen.length), du kannst Werte beobachten, du kannst einzelschrittweise durch deinen Code laufen.

                                    Aber wie auch immer, ich sehe nur den Code, den Du am 14.11 um 21:06 gepostet hast und da kommt mengen[iz] nur einmal vor: in der Schleife. Die von Dir genannte Fehlermeldung dürfte kommen, wenn es mehr Preise als Mengen gibt, so dass preise.length > mengen.length ist. Wie das zu Stande kommt, kann ich von hier aus nicht sagen. Nur eins: Ein Element mit gesetztem hidden-Attribut wird von querySelectorAll mit erfasst. Wenn Du also 10 Mengen und 10 Preise hast, und davon teilweise welche hidden sind, dann sollte das nicht zu Unterschieden in den Längen führen.

                                    Rolf

                                    --
                                    sumpsi - posui - obstruxi
                                    1. Guten Morgen Rolf,

                                      das mit den Mengen und Preisen ist ein sehr guter Hinweis, denn die stimmen nicht überein, die versteckten Preise sind immer 9 Stück, die Mengen abundzu aber weniger.

                                      Ich Danke Dir, nun kann ich mich an diesem Punkt festkrallen ;-)

                                      Das mit dem Debugger hatte ich gestern schon entdeckt und mich auch mal daran versucht, aber bin nicht auf Deinen Ansatz gekommen.

                                      LG sendet Dir

                                      Lynn

                                    2. Lieber Rolf,

                                      Du bist die Granate schlecht hin - es war die Lösung !

                                      Vielen Dank für Deine immer beste Lösungen.

                                      LG sendet Dir

                                      Lynn

                                      1. Hallo Lynnv,

                                        Du bist die Granate schlecht hin

                                        Das stimmt. Ich kann ziemlich schnell explodieren. 😉

                                        Rolf

                                        --
                                        sumpsi - posui - obstruxi
                2. @@Lynnv

                  Hast du da noch irgendwelche oninput-Attribute im HTML zu stehen?

                  Geht: HTMLElement.addEventListener('click', action)

                  Geht auch: <button onclick="action(event)">

                  Geht nicht: <button onclick="action()">

                  Codepen

                  😷 LLAP

                  --
                  Wenn der Faschismus wiederkehrt, wird er nicht sagen: „Hallo, ich bin der Faschismus.“ Er wird sagen: „Hört auf zu zählen! Ich habe gewonnen!“