Franz: Schleife in einer Javascript funktion

0 59

Schleife in einer Javascript funktion

Franz
  • javascript
  1. 1
    Tabellenkalk
    1. 0
      Franz
      1. 0
        Tabellenkalk
        1. 0
          Franz
          1. 0
            Rolf B
  2. 2
    Rolf B
    1. 0
      Franz
      1. 1
        JürgenB
        1. 0
          Rolf B
          1. 0
            JürgenB
          2. 0
            Tabellenkalk
      2. 1
        Rolf B
        1. 0
          Franz
          1. 0
            Rolf B
            1. 0
              Franz
              1. 0
                Rolf B
                1. 0
                  Franz
                  1. 0

                    Wert(e) aus function speichern für andere function vorbehalten und wiederverwenden

                    Franz
                    1. 0
                      Der Martin
                      1. 0
                        Rolf B
                    2. 1
                      Rolf B
                      1. 0
                        Franz
                        1. 0
                          Rolf B
                      2. 0

                        Summenzuweisung wird nicht ausgeführt

                        Franz
                        1. 0
                          Rolf B
                          1. 0
                            Franz
                            1. 0
                              Rolf B
                              1. 0

                                Summenzuweisung wird nicht ausgeführt, wenn INPUT Felder nicht übergen werden

                                Franz
                                1. 0
                                  Tabellenkalk
                                2. 0
                                  Der Martin
                                3. 0
                                  Rolf B
                                  1. 0
                                    Franz
                                    1. 0
                                      Rolf B
                                      1. 0
                                        Franz
                                        1. 0
                                          Rolf B
                                          1. 0
                                            Felix Riesterer
                                            1. 0
                                              Rolf B
                                              1. 0
                                                Felix Riesterer
                                                1. 0
                                                  Rolf B
                                          2. 0
                                            Franz
                                            1. 0
                                              Rolf B
                                              1. 0
                                                Franz
                                                1. 1
                                                  Rolf B
                                                  1. 0
                                                    Franz
                            2. 0
                              Rolf B
                              1. 0
                                Franz
                                1. 0
                                  Rolf B
                                  1. 0
                                    Franz
                                    1. 0
                                      Rolf B
                                      1. 0

                                        function setOptionalValue

                                        Franz
                                        1. 0
                                          Rolf B
                                          1. 0
                                            Franz
                                            1. 0
                                              Rolf B
                                    2. 0
                                      Matthias Scharwies
  3. 0
    Felix Riesterer
    1. 0
      Rolf B
  4. 0

    Bei fehlender Variable WIEDER Abbruch ?

    Franz
    1. 1
      Felix Riesterer

Ich habe eine function die funktionier :-)

function rechnen() {
let summe_1 = 	getInputAsFloat(document.formular1.FeldWert1) +
				getInputAsFloat(document.formular1.FeldWert2) +
				getInputAsFloat(document.formular1.FeldWert3) +
				getInputAsFloat(document.formular1.FeldWert4) +
				getInputAsFloat(document.formular1.FeldWert5) +
				getInputAsFloat(document.formular1.FeldWert6) +
				getInputAsFloat(document.formular1.FeldWert7) +
				getInputAsFloat(document.formular1.FeldWert8) 
				;	
}

Doch nun möchte ich sie verkürzen und kompakter machen, so habe ich mir gedacht eine immer wiederkehrende Zeile in einer Schleife unterzubringen. Aber irgendwie funktioniert das nicht so wie geplant.

function rechnen() {
let summe_1 = 	for (var i = 1; i <= 7; i++) {
				getInputAsFloat(document.formular1.FeldWert+i)  + 
				}    

				getInputAsFloat(document.formular1.FeldWert8) ;	
				}

  1. Hallo,

    Doch nun möchte ich sie verkürzen und kompakter machen, so habe ich mir gedacht eine immer wiederkehrende Zeile in einer Schleife unterzubringen. Aber irgendwie funktioniert das nicht so wie geplant.

    D.h. du möchtest nicht mehr nur mit den Werten der Variablen rechnen sondern auch noch mit Namen der Variablen. Das geht so nicht.

    Mach dich mit Arrays vertraut.

    Gruß
    Kalk

    1. Ich möchte eigentlich nur den NAmen der VAriable ändern

      1. Hallo,

        Ich möchte eigentlich nur den NAmen der VAriable ändern

        Nein.

        Gruß
        Kalk

        1. theoretisch könnte es doch so funktionieren?

          
          function rechnen() {
          
          var anhang = [1,2];
          var wert = "FeldWert";
          
          let summe_1 = 	getInputAsFloat(document.formular1.wert+anhang) +
          				getInputAsFloat(document.formular1.wert+anhang) 
          				;	
          }
          
          1. Hallo Franz,

            schon besser, aber da ist JavaScript sturer als Du gern möchtest. Ich habe das in meinem anderen Posting detailliert aufgeschlüsselt, das ist für Einsteiger überhaupt nicht trivial.

            Rolf

            --
            sumpsi - posui - obstruxi
  2. Hallo Franz,

    document.formular1.FeldWert+i

    So kann's nicht gehen. Aber warum? Dafür muss man etwas tiefer in die Regeln von JavaScript einsteigen. Versuche bitte zu folgen - sowas muss man exakt verstanden haben. Ohne dieses Verständnis drohen ständige Überraschungen.

    Dieser Ausdruck besteht aus 3 Operatoren (Punkt, Punkt, Plus) und 4 Operanden (Variablenname document, Eigenschaftsname formular1, Eigenschaftsname FeldWert und Variablenname i). JavaScript hat zunächst den Job, deren Ausführungsreihenfolge festzulegen. Dafür gibt es eine Prioritätenliste.

    Wir haben also zweimal den Punkt-Operator und einmal das Plus. Punkt hat einen höheren Rang als Plus, damit wird Plus zurückgestellt. Und Punkt ist linksassoziativ, d.h. in einem Ausdruck wie a.b.c wird der linke Punkt vor dem rechten Punkt ausgewertet.

    Damit ergibt sich diese Ausführungsreihenfolge:

    • Wende den Punkt-Operator auf das Objekt in document und den Namen formular1 an. Ergebnis ist ein Objekt des Typs HTMLFormElement. Hoffentlich :)
    • Wende den Punkt-Operator auf das ermittelte Form-Objekt und den Namen FeldWert an. Das Ergebnis ist bei Dir undefined, weil es kein Form-Element dieses Namens gibt. Wenn es eins gäbe, wäre das Ergebnis bspw. ein Objekt des Type HTMLInputElement.
    • Wende den Plus-Operator auf undefined und den (numerischen) Wert in i an. Der Plus-Operator kratzt sich nun am Kopf. Das sind aber keine gleichen Typen. Da muss ich erstmal einen gemeinsamen Typ finden, in die ich beide konvertieren kann. Javascript hat dafür interne Regeln. In der Konstellation undefined/Number macht es undefined zu einer Zahl, was NaN ergibt. NaN+1 bleibt NaN. Muh.

    Naheliegend wäre es also, die Ausführungsreihenfolge zu ändern. Dafür gibt es Klammern. Und FeldWert ist keine Variable, sondern ein Namensteil, müsste also ein String in Anführungszeichen sein. Eigentlich...

    document.formular1.("FeldWert"+i)
    

    Das könnte funktionieren, wenn die Sprachdesigner es gewollt hätten. Wollten sie aber nicht. JavaScript erwartet rechts von einem Punkt einen festen Eigenschaftsnamen, und keinen Ausdruck, der den Namen bestimmt. Ist historisch so entstanden, das ist die Syntax der Sprache C und ihrer Abkömmlinge.

    Statt dessen gibt es für diesen Fall eine andere Syntax, die Du von Arrays schon kennst:

    document.formular1["FeldWert"+i]
    

    Lektüre.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo (geduldiger) Rolf,

      das heißt der Grundgedanke war schon mal gar nicht gar so schlecht.

      FeldWert+i
      
      

      so kann ich Variablen zusammensetzen für eine einfache sofortige Ausgabe.

      ["FeldWert"+i]
      
      

      so den Namen ändern um diesen aufzurufen, und mit der Wert zu arbeiten...

      Einzeln funktioniert das jetzt. Doch in der Schleife leider nicht, aber ich denke hier ist die Schleife das Problem in der let Zuordnung

      function rechnen() {
      let summe_1 = 	for (var i = 1; i <= 7; i++) {
      				getInputAsFloat(document.formular1["FeldWert"+i])  + 
      				}    
      
      				getInputAsFloat(document.formular1.FeldWert8) ;	
      				}
      
      
      1. Hallo Franz,

        wäre jetzt nicht der richtige Zeitpunkt für

        https://wiki.selfhtml.org/wiki/JavaScript/Tutorials/Einstieg ?

        Gruß
        Jürgen

        1. Hallo Jürgen,

          das wird bestimmt helfen.

          Problem ist: genau die Fallstricke, an denen Franz sich verhakt, finde ich dort nicht erklärt. Darum schreibe ich hier diese Romane.

          Rolf

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

            ich bewundere ja auch deine Geduld.

            Gruß
            Jürgen

          2. Hallo,

            Darum schreibe ich hier diese Romane.

            Aber ist es nicht sinnvoller, die „Romane“ im Wiki zu schreiben?

            Gruß
            Kalk

      2. Hallo Franz,

        Du scheinst zu glauben, dass eine Schleife die darin befindlichen Codestücke einfach aneinander klebt. Nein. Eine Schleife führt dazu, dass die im Schleifenrumpf befindlichen Anweisungen mehrfach ausgeführt werden. Deshalb muss jeder einzelne Befehl im Rumpf in sich vollständig sein.

        Wenn Du Werte in einer Schleife aufsummieren willst, musst Du eine Variable haben, in der Du summierst. Die setzt Du erstmal auf 0, und pro Durchlauf wird ein Summand hinzugerechnet. FeldWert8 muss dabei nicht extra behandelt werden.

        let summe=0;
        for (let i=1; i<=8; i++) {
           summe = summe + getInputAsFloat(document.formular1["FeldWert"+i]);
        }
        

        wobei es für summe = summe + wert; noch eine Kurzschreibweise gibt: summe += wert;

        let summe=0;
        for (let i=1; i<=8; i++) {
           summe += getInputAsFloat(document.formular1["FeldWert"+i]);
        }
        

        Was ich eben zu erwähnen vergaß: Der Plus-Operator in den eckigen Klammern kratzt sich auch hier am Kopf. Du addierst ja einen String und eine Zahl. Auch hier muss eine Angleichung der Typen erfolgen, und das wird kompliziert durch den Umstand, dass das Plus ein Chamäleon ist. String plus String verkettet, und Zahl plus Zahl addiert. Ganz übel wäre sowas wie "2"+2 - da gibt's die Wahl zwischen der Zahl 4 und dem String "22".

        Das Plus addiert nur dann, wenn beide Operanden „numerisch genug“ sind. Dabei werden nur Typen betrachtet, keine Werte. "2" ist ein String, in dem zufällig etwas steht was in eine Zahl konvertiert werden kann - die mögliche Konvertierung wird nicht beachtet. Das würde zu viel Zeit kosten. JavaScript betrachtet null, undefined und die booleschen Werte false und true als „numerisch genug“, alles andere (Strings, Arrays, Objekte) führt dazu, dass die Operanden in Strings verwandelt und verkettet werden. 2+"2" ergibt darum "22" und "FeldWert"+j wird zu "FeldWert1".

        Ich müsste dazu wirklich mal was ins Wiki schreiben, aber ich weiß nicht so genau, wo es passt und ob ich übersehe, dass es das schon gibt. Und ich müsste Zeit dafür finden 🤓

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Ja es funktioniert... jetzt werde ich die ganzen genialen Infos von hier einmal durcharbeiten.

          Danke...

          1. Hallo Franz,

            wie genau lauten die IDs (oder name-Attribute) der zu summierenden Felder?

            Bisher hatten wir die Feldnamen als ["FeldWert" + j] erzeugt, was auf inputs mit id oder name "FeldWert1", "FeldWert", ... "FeldWert8" zutrifft.

            Nun hast Du da eine 1 und eine 2 eingeschoben. Das führt zu anderen Namen für die inputs. Heißen die denn wirklich so?

            Und Felix hatte offenbar den richtigen Riecher; wenn Du mehrere solcher Gruppier-Schleifen hast, dann kann es tatsächlich hilfreich sein, wenn man nicht die Feldnamen konstruiert, sondern mit querySelectorAll die passenden DOM Elemente heraussucht.

            Rolf

            --
            sumpsi - posui - obstruxi
            1. Es ist wie eine Excel Tabelle aufgebaut, in der ersten Spalte ist der Name, dann folgen 8 Eingabe Felder und in der letzten Spalte das Ergebnis. Weiter soll dann immer wieder zwischen Zeilen mit dem Ergebnis vertikal erzeigt werden.

              Name,des Feldes	Feld1 		feld2 		feld3 f			 ergebnis
              Id:wert_1		id:wert1_2	id:wert1_3  	…weiter…   		id: ergebnis_1
              Id:wert_2		id:wert2_2	id:wert2_3  	…weiter…   		id: ergebnis_2
              Id:wert_3		id:wert3_2	id:wert3_3  	…weiter…   		id: ergebnis_3
              Weiter…
              ----------------------
              		Id: ergebnis_z_10_1	Id: ergebnis_z_10_2	Id: ergebnis_z_10_§
              
              
              1. Hallo Franz,

                d.h. du summierst die Zeilen und die Spalten? Knifflig, das mit CSS Selektoren zu lösen 😀

                Sind die genannten IDs die realen IDs deiner Seite? Wenn ja, sind sie ungeschickt gewählt, weil die Namensvergabe inkonsistent ist.

                Spalte 1 sind nur Namen? Brauchen die überhaupt IDs?

                Die Spalten 2 bis N sind Wertespalten. Ob Du da nun mit _1 oder _2 als Suffix beginnst, ist gehupft wie gesprungen, aber das Suffix der zu summierenden Felder und das Suffix des Ergebnisfeldes sollten identisch sein. Das vereinfacht das Programmieren deutlich, aber das scheint bei Dir nicht der Fall. Ein Ergebnisfeld ergebnis_z_10_1 sollte Daten der Eingabefelder wert1_1, wert2_1 etc beinhalten.

                Wie auch immer: Wenn die IDs der Spalte 2 "wert1_2", "wert2_2", ..., "wert8_2" heißen, dann muss natürlich auch der Ausdruck, der diese IDs erzeugt, passend dazu sein. Das wäre ["wert"+i+"_2"].

                Dieses Suffix kannst Du der rechnen() Funktion auch als Parameter mitgeben. D.h. bei den input-Feldern der ersten Spalte könntest Du oninput="rechnen(1)" schreiben, und in rechnen verwendest Du das:

                function rechnen(spalte) {
                   let summe = 0;
                   for (let i=1; i<=8; i++)
                      summe += getInputAsFloat(document.formular1["wert"+i+"_"+spalte]);
                
                   document.formular1["ergebnis_z_10_"+spalte].value = summe;
                }
                

                Schreib das nicht einfach ab. Überlege genau, welche Werte Du brauchst, damit es zu den von Dir gewählten Namen passt.

                Ob Du beim Ergebnis .value oder .text verwenden musst hängt davon ab, was für ein HTML Ding das ist.

                Ich sehe aber noch ein grundsätzliches Bedienbarkeitsproblem in deiner Seite: Ein Eingabefeld muss eine Beschriftung (<label>) haben. Du hast aber nur vor jeder Zeile eine Beschriftung für diese Zeile, und vermutlich ist die auch nicht an ein Eingabefeld gebunden. Wer sehbehindert ist und einen Screenreader braucht, kommt nicht zurecht. Es ist natürlich deine Entscheidung, ob Du diese Form von Able-ism - zumindest vorläufig - hinnehmen willst.

                Rolf

                --
                sumpsi - posui - obstruxi
                1. Ich bin schon mal sehr zufrieden mit mir und er Welt.

                  function rechnen(spalte) {
                  	let summe=0;
                  	for (let i=1; i<=8; i++) {
                  		summe += getInputAsFloat(document.formular1["Wert"+spalte+i]);
                  		}
                  document.getElementById("Wert"+spalte).value= summe;	
                  }	
                  
                  
                  rechnen(1);
                  rechnen(2);
                  rechnen(3);
                  rechnen(4);
                  
                  

                  Jetzt werde ich mal den nächsten Schritt angehen und die vertikalen Summen berechnen.

                  PS: Wahrscheinlich hast du Recht mit dem Label.... also auch das noch...

                  1. Ich durchlaufe die function ja mehrmals ums sie anschliessend sofort auszugeben.

                    Aber

                    function rechnen(spalte) {
                    	let summe=0;
                    	for (let i=1; i<=8; i++) {
                    		summe += getInputAsFloat(document.formular1["Wert"+spalte+i]);
                    		}
                    document.getElementById("Wert"+spalte).value= summe;	
                    }	
                    
                    
                    rechnen(1);
                    rechnen(2);
                    rechnen(3);
                    rechnen(4);
                    
                    

                    wenn ich die drei ersten Zeilen, jeweils die Spalten zusammenrechen und ausgebe, mache ich da so

                    function rechnen_spalte() {
                    let summe=0;
                    for (let i=1; i<=8; i++) {
                    	summe = getInputAsFloat(document.formular1["Wert1"+i])+
                    			getInputAsFloat(document.formular1["Wert2"+i])+
                    			getInputAsFloat(document.formular1["Wert3"+i]);
                    			document.getElementById("Wert10"+i).value= summe;	
                    			}
                    }	
                    

                    Wenn ich die einzelnen Summen später nochmal brauche, muss ich dann alles wieder durchrechen, oder kann ich mir den Wert der Ausgabe, ausgeben UND für später vorbehalten und wiederverwenden??

                    Franz

                    1. Hallo,

                      function rechnen_spalte() {
                      let summe=0;
                      for (let i=1; i<=8; i++) {
                      	summe = getInputAsFloat(document.formular1["Wert1"+i])+
                      			getInputAsFloat(document.formular1["Wert2"+i])+
                      			getInputAsFloat(document.formular1["Wert3"+i]);
                      			document.getElementById("Wert10"+i).value= summe;	
                      			}
                      }	
                      

                      Wenn ich die einzelnen Summen später nochmal brauche, muss ich dann alles wieder durchrechen, oder kann ich mir den Wert der Ausgabe, ausgeben UND für später vorbehalten und wiederverwenden??

                      du hast die Summe doch schon gespeichert: In der value-Eigenschaft des betreffenden Formularfeldes. Selbsterständlich kannst du sie bei Bedarf auch wieder von dort lesen. Das ist keine Write-Only-Eigenschaft.

                      Live long and pros healthy,
                       Martin

                      --
                      Home is where my beer is.
                      1. Hallo Martin,

                        sorry, nein, davon rate ich ab. Es ist undefiniert, in welcher Reihenfolge die Behandlungsroutinen für die DOM Ereignisse aufgerufen werden. Demzufolge sollte sich auch nicht eine Behandlungsroutine auf Ergebnisse einer anderen verlassen. Solcher Code ist zerbrechlich.

                        Abgesehen davon hilft ihm die bereits ermittelte Spaltensumme nichts für die Zeilensumme der Zeilen 1 bis 3.

                        Wenn es - was bisher nicht gezeigt wurde - eine Behandlungsroutine gibt, die bei einer Zelländerung die Zeilensumme bildet und die Zeilensumme in ein Ausgabefeld schreibt, dann sähe das anders aus. Allerdings sollte diese Abhängigkeit dann ausdrücklich programmiert werden.

                        Wenn beispielsweise jedes Eingabefeld eine Zeilen- und eine Spaltensumme zu aktualisieren hat, dann würde ich das so steuern (mit direktem oninput Attribut)

                        <input type="number" id="EingabeS5Z7" oninput="cellChange(5,7)">
                        

                        Mit meinen vorhin dargestellten Helpern wär's dann so:

                        function cellChange(spalte, zeile) {
                           const zsFeld = getZeilensummeFeld(zeile),
                                 ssFeld = getSpaltensummeFeld(spalte):
                        
                           zsFeld.value = getZeilensumme(zeile);
                           ssFeld.value = getSpaltensumme(spalte);
                        
                           if (zeile >= 1 && zeile <= 3) {
                              // **jetzt** kann auf die Feldinhalte der drei 
                              // Zeilensummenfelder zurückgegriffen werden
                           }
                        }
                        

                        getZeilensummeFeld und getSpaltensummeFeld sind analog zu getEingabefeld aus dem anderen Beitrag zu bauen.

                        Aber das ist jetzt nur skizziert, da muss man vermutlich noch etwas mehr Hirnschmalz reinstecken, ohne Franz dabei zu überfordern.

                        Eine Sache wäre vermutlich eine unaufdringliche Registrierung des oninput Events auf dem Container für alle diese Felder, und die Ermittlung von Zeile und Spalte aus der ID dieses Events. Das würde das HTML deutlich verschlanken und änderungsfreundlicher machen.

                        Rolf

                        --
                        sumpsi - posui - obstruxi
                    2. Hallo Franz,

                      wenn ich die drei ersten Zeilen, jeweils die Spalten zusammenrechen und ausgebe, mache ich da so

                      function rechnen_spalte() {
                      let summe=0;
                      for (let i=1; i<=8; i++) {
                      	summe = getInputAsFloat(document.formular1["Wert1"+i])+
                      			getInputAsFloat(document.formular1["Wert2"+i])+
                      			getInputAsFloat(document.formular1["Wert3"+i]);
                      			document.getElementById("Wert10"+i).value= summe;	
                      			}
                      }	
                      

                      Also - die Summenzuweisung sollte eine Zeile tiefer, die muss nicht im Schleifenrumpf stehen. Du musst nicht jedes Zwischenergebnis ins Ergebnis schreiben.

                      Speichern kann man die Ergebnisse natürlich, aber in einer ereignisgesteuerten Welt bist Du nicht unbedingt sicher, in welcher Reihenfolge die Behandlungsfunktionen ablaufen. Das Verwenden von Zwischenergebnissen setzt aber eine Reihenfolge voraus. Darum lieber neu rechnen.

                      Damit kommen wir zum Thema Wiederverwendung von Code. Du merkst, dass dein Code dafür noch nicht geeignet ist. Kein Ding, wir sind ja keine Bauingenieure, wir können auch nach Abbinden des Betons noch umbauen. Man nennt das refaktorieren.

                      Ein Punkt ist das Ermitteln von Werten. Dein Namenskonzept ist an allen möglichen Stellen in Code gebrannt. Das könnte man durch Zugriffsfunktionen einkapseln:

                      function getEingabefeld(spalte, zeile) {
                         return document.formular1["Wert"+zeile+spalte];
                      }
                      
                      function getEingabewert(spalte,zeile) {
                         return getInputAsFloat(getEingabefeld(spalte, zeile));
                      }
                      

                      Der Befehl "return" bewirkt, dass die Funktion einen Wert zurückgibt. Man könnte das Auslagern in getEingabefeld auch lassen, aber ich möchte hier das Konzept der Zuständigkeitstrennung betonen. Eine Funktion sollte genau eine Aufgabe haben. getEingabefeld: Beschaffe das Eingabe-input-Element für eine bestimme Spalte und Zeile. getInputAsFloat: Stelle den Wert des Eingabeelements als float bereit. getEingabewert: Orchestriere die beiden anderen.

                      An der Stelle ein Hinweis zur Benennung: id="Wert57" ist das Eingabefeld aus Zeile 5, Spalte 7. Du hast ein Ausgabefeld namens Wert103. Das schreit nach Namenskollisionen. Es wäre besser, wenn die ids die Rolle des Feldes widerspiegeln. Ich würde sie "EingabeS5Z7" nennen, und in der getEingabefeld-Funktion auf formular1["EingabeS"+zeile+"Z"+spalte] zugreifen. Dadurch, dass es in einer einzigen Funktion gekapselt ist, musst Du das auch nur an genau einer Stelle programmieren. Die Ausgabefelder sollten dementsprechend "Ausgabe" in der id tragen.

                      Wir bauen uns gleich noch zwei kleine Helfer: zeilensumme und spaltensumme. Die laufen hier beide bis 8, was eine 8x8 Matrix voraussetzt. Wenn das bei Dir anders ist, musst Du es anpassen.

                      function getZeilensumme(zeile) {
                         let summe = 0;
                         for (let spalte=1; spalte <= 8; spalte++) {
                            summe += getEingabewert(spalte, zeile);
                         }
                         return summe;
                      }
                      
                      function getSpaltensumme(spalte) {
                         let summe = 0;
                         for (let zeile=1; zeile<= 8; zeile++) {
                            summe += getEingabewert(spalte, zeile);
                         }
                         return summe;
                      }
                      

                      Diese Funktionen sind jetzt viel universeller einsetzbar, weil sie ihr Ergebnis zurückliefern statt es direkt anderswo abzulegen. Das Ablegen machen wir in den Funktionen, mit denen Du angefangen hast:

                      // Dieser Name ist, meine ich, besser als rechnen_spalte
                      function rechnen_zeilen123() {
                         document.getElementById("Wert10"+i).value = getZeilensumme(1) + 
                                                                     getZeilensumme(2) + 
                                                                     getZeilensumme(3);
                      }
                      
                      function rechnen(spalte) {
                         document.getElementById("Wert"+spalte).value = getSpaltensumme(spalte);	
                      }
                      

                      So baut man sich einen wiederverwendbaren Funktionenbaukasten. Je weniger eine Funktion tut, je weniger Abhängigkeiten sie zu anderen Funktionen hat, desto besser kann man sie wiederverwenden.

                      Rolf

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

                        danke erst mal... Ich fange jetzt wieder von vorne an.

                        als erstes habe ich ein html erstellt und den alten Code nochmal hergenohmen, aber schon die Eingabe Variable geändert. EingabeS"+zeile+"Z"+spalte.

                        es läuft jetzt:

                        https://jsfiddle.net/xk1hwupe/1/

                        ich würde nun gerne Stück für Stück deinen Code einsetzen und vor allem verstehen.

                        Also erstes müssten doch die functionen

                        function getEingabefeld(spalte, zeile) {
                           return document.formular1["Wert"+zeile+spalte];
                        }
                        
                        function getEingabewert(spalte,zeile) {
                           return getInputAsFloat(getEingabefeld(spalte, zeile));
                        }
                        

                        eingestezt werden, die dann mit denen weiter arbeiten

                        function getZeilensumme(zeile) {
                           let summe = 0;
                           for (let spalte=1; spalte <= 8; spalte++) {
                              summe += getEingabewert(spalte, zeile);
                           }
                           return summe;
                        }
                        
                        function getSpaltensumme(spalte) {
                           let summe = 0;
                           for (let zeile=1; zeile<= 8; zeile++) {
                              summe += getEingabewert(spalte, zeile);
                           }
                           return summe;
                        }
                        
                        1. Hallo Franz,

                          function getEingabefeld(spalte, zeile) {
                             return document.formular1["Wert"+zeile+spalte];
                          }
                          

                          wie gesagt: Wenn Du die Felder umbenennst, muss auch die Ermittlung der Namen angepasst werden. "Wert"+zeile+spalte kann niemals etwas wie "EingabeZ3S5" liefern.

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                      2. function rechnen_spalte() {
                        let summe=0;
                        for (let i=1; i<=8; i++) {
                        	summe = getInputAsFloat(document.formular1["Wert1"+i])+
                        			getInputAsFloat(document.formular1["Wert2"+i])+
                        			getInputAsFloat(document.formular1["Wert3"+i]);
                        			document.getElementById("Wert10"+i).value= summe;	
                        			}
                        }	
                        
                        

                        Also - die Summenzuweisung sollte eine Zeile tiefer, die muss nicht im Schleifenrumpf stehen. Du musst nicht jedes Zwischenergebnis ins Ergebnis schreiben.

                        Aber wenn ich sie eine Zeile tiefer setze geht gar nichts mehr

                        function rechnen_spalte() {
                        let summe=0;
                        for (let i=1; i<=8; i++) {
                        	summe = getInputAsFloat(document.formular1["Wert1"+i])+
                        			getInputAsFloat(document.formular1["Wert2"+i])+
                        			getInputAsFloat(document.formular1["Wert3"+i]);
                        			
                        			}
                        document.getElementById("Wert10"+i).value= summe;	
                        }	
                        
                        

                        https://jsfiddle.net/qvkx6tze/

                        1. Hallo Franz,

                          ich bitte um Entschuldigung. Ich hatte deinen Code nicht verstanden. Die Zeile war da, wo sie stand, richtig.

                          Du hast aber eigentlich 8 Zeilen, ja? Und brauchst die Summe der Zeilen 1-3?

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                          1. Da bin ich ja froh, wenn der Profi eine winzigklitzekleinigkeit übersieht!

                            Aber es geht trotzdem nicht richtig

                            Hier geht es: https://jsfiddle.net/3gfs9cwa/2/

                            und wenn einige Abfragewerte nicht da sind, geht es nicht (es fehlt jeweils die erste Spalte mit den Werten Wert11, Wert21, Wert31 und Wert41 ), aber horizontal eben shcon.

                            ** Es ist so, ich möchte das Script öfter hernehmen und manchmal fehlern die ersten Spalten, deshalb sollte es auch gehen, wenn eben einige Var nicht vorhanden sind**

                            https://jsfiddle.net/3gfs9cwa/3/

                            das verstehe ich jetzt noch viel weniger...

                            1. Hallo Franz,

                              ich bin so langsam auch komplett durcheinander. Muss an der Hitze liegen. Und ich habe vermutlich einiges bei Dir nicht so kapiert wie Du es gemacht hast.

                              1: Funktion rechnen. Ich hatte Dich so verstanden, dass diese Funktion eine Spalte aufsummiert. Nö. Tut sie nicht. Sie summiert eine Zeile. D.h. der Parameter spalte sollte in zeile umbenannt werden (und natürlich jeder Gebrauch von spalte in dieser Funktion auch.

                              2: Funktion rechnen_s4. Diese Funktion bildet Spaltensummen, ich hatte gedacht, das wären Zeilensummen gewesen. Der Schleifenzähler darin zählt aber nur bis 3. Und du hast jetzt 4 Spalten. Darum wird die 4. Spalte nicht summiert.

                              3: rechnen(4) bildet die Summe von Zeile 4, also die Summe der Spaltensummen. Ist das das, was Du willst? Um die Gesamtsumme zu bilden, kannst Du auch in rechnen_s4 die Spaltensummen aufsummieren - hier habe ich deine Frage mit dem zwischenspeichern nicht richtig gedeutet.

                              function rechnen_s4() {
                                 let total = 0;
                                 for (let i=1; i<=4; i++) {
                                    let summe = getInputAsFloat(document.formular1["Wert1"+i] )+
                                                getInputAsFloat(document.formular1["Wert2"+i] )+
                                                getInputAsFloat(document.formular1["Wert3"+i] );
                                    total += summe;
                                    document.getElementById("Wert4"+i).value = summe;	
                                 }
                                 document.getElementById("Wert4).value = total;	
                              }	
                              

                              So, wie Du es im Moment hast, bildest Du zuerst die Zeilensummen, darunter auch die Summe der Zeile 4. Danach bildest Du Spaltensummen, was Zeile 4 verändert - aber die Summe der Zeile 4 ("Wert4") nicht. Deshalb zeigt das Gesamtsummenfeld den falschen Wert.

                              Das mitsummieren in rechnen_s4 behebt das. Alternativ müsstest Du rechnen_s4 zuerst aufrufen, und dann erst rechnen(1) bis rechnen(4), damit Du die richtigen Spaltensummen addierst.

                              Rolf

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

                                Ich will ja nicht nerven, aber...

                                document.getElementById("Wert4).value = total;

                                Wenn ich das reinschreibe, sagt mir fiddle... Fehler

                                und ich habe auch hier das gleiche Phänomen, das die Summen die horizontal berechnet werden stimmen, und die summen vertikal nicht, wenn Input Variablen fehlen.

                                https://jsfiddle.net/onk76vrL/1/

                                1. Hallo,

                                  Ich will ja nicht nerven, aber...

                                  dann solltest du dir dringend...

                                  ("Wert4)

                                  ...vernünftige Debugging-Kenntnisse zulegen!

                                  Gruß
                                  Kalk

                                2. Hallo,

                                  document.getElementById("Wert4).value = total;

                                  Wenn ich das reinschreibe, sagt mir fiddle... Fehler

                                  dann zähl mal die Anführungszeichen.
                                  Tipp: Normalerweise sollten sie paarweise auftreten.

                                  Live long and pros healthy,
                                   Martin

                                  --
                                  Home is where my beer is.
                                3. Hallo Franz,

                                  du hast immer noch Chaos in deinen IDs. Das führt wohl zum Problem. Bring das in Ordnung. SPEICHERE DAS!

                                  Natürlich kann man auch fehlerverzeihender programmieren, aber hilft das hier? Wenn Du willst, dass fehlende IDs dein Script nicht zum abrauchen bringen, schreib eine Funktion, die das abfängt.

                                  function setValue(id, wert) {
                                     let element = document.getElementById(id);
                                     if (element)
                                        element.value = wert;
                                  }
                                  

                                  Statt

                                  document.getElementById("Wert"+spalte).value = summe;

                                  schreibst Du dann

                                  setValue("Wert"+spalte, summe);

                                  Das kaschiert den Fehler, statt ihn zu beheben. Um es drastischer zu machen, könntest Du setValue in der Aggro-Version erstellen, und weißt dann auch gleich, welche ID Dir den Knoten in die Schnürsenkel macht:

                                  function setValue(id, wert) {
                                     let element = document.getElementById(id);
                                     if (element)
                                        element.value = wert;
                                     else
                                        alert("Die ID " + id + " existiert nicht, du Depp!");
                                  }
                                  

                                  Rolf

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

                                    ich fange an alles umzusetzen, bessere Bezeichner und auch die Variablen

                                    So habe ich jetzt einen Titel, 12 Zahlenfelder und ein Ergebnissfeld pro Zeile.

                                    
                                    function rechner_zeile(nr) {
                                    	let summe=0;
                                    	for (let i=1; i<=12; i++) {
                                    		summe += getInputAsFloat(document.j_um["EingabeS"+i+"Z"+nr] );		
                                    		}
                                    	setValue("Ausgabe"+nr, summe);
                                    	}	
                                    
                                    

                                    dann zu deiner function, danke, jetzt weis ich was fehlt ;-)

                                    function setValue(id, wert) {
                                       let element = document.getElementById(id);
                                       if (element)
                                          element.value = wert;
                                       else
                                          alert("Die ID " + id + " existiert nicht, du netter toller Typ");
                                    }
                                    
                                    

                                    ich habs drin stehen lassen, weil es mich an Alles erinnert.

                                    Es funktioniert alles besstens, aber eine funktion macht mir noch Probleme.

                                    
                                    function rechner_spalte(nr) {
                                    	let total=0;
                                    	for (let i=1; i<=12; i++) {	
                                    		let summe = getInputAsFloat(document.j_um["EingabeS"+i+"Z94"] )+	
                                    					getInputAsFloat(document.j_um["EingabeS"+i+"Z95"] )+	
                                    					getInputAsFloat(document.j_um["EingabeS"+i+"Z151"] );	
                                    		total += summe;	
                                    		setValue("EingabeS"+i+"Z"+nr, summe);
                                    		}
                                    	setValue("Ausgabe"+nr, total);
                                    	}
                                    

                                    Weil, wenn hier z.B. danke deines Scriptes, der Fehler

                                    *Die ID EingabeS1Z96 existiert nicht, du netter toller Typ

                                    aufpoppt, bleibt diese funktion leer. Wie könnte man diesen Fehler abfangen?

                                    1. Hallo Franz,

                                      „abfangen“ bedeutet, dass ein Programm mit einer Fehlersituation umzugehen lernt, die im Normalbetrieb zu erwarten ist. Ist das so? Gibt es EingabeS1Z96 nicht immer?

                                      Mir scheint es aber eher so, als wäre da ein Konzeptfehler und Du ermittelst für diese Ausgabe den falschen Namen. Wenn mir das richtig scheint, dann müsstest Du überlegen, wie das Ausgabefeld richtig heißt und den Namen passend erzeugen.

                                      Rolf

                                      --
                                      sumpsi - posui - obstruxi
                                      1. Da ich immer die gleiche HTML Maske hernehmen möchte, kann es sein, das die erste, zweite, dritte spalte manchmal fehlt. und deshlab dann die Felder

                                        
                                        EingabeS1Z96
                                        EingabeS2Z96
                                        EingabeS3Z96
                                        
                                        
                                        EingabeS1Z97
                                        EingabeS2Z97
                                        EingabeS3Z97
                                        
                                        

                                        nicht da sind. Das einfachste wäre wenn dann diese Felder einfach mit 0 gefüllt werden. Aber was komsich ist, ist, das bei der

                                        function rechner_zeile(nr)

                                        wird es berechnet und bei

                                        function rechner_spalte(nr) {

                                        nicht

                                        1. Hallo Franz,

                                          Das einfachste wäre wenn dann diese Felder einfach mit 0 gefüllt werden.

                                          Wenn die Felder nicht da sind, kannst Du sie auch nicht mit 0 füllen. D.h. du brauchst hier einen Klon von setValue, sowas wie setOptionalValue, in dem der Alert fehlt.

                                          Rolf

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

                                            Wenn die Felder nicht da sind, kannst Du sie auch nicht mit 0 füllen.

                                            hehe, klingt logisch.

                                            D.h. du brauchst hier einen Klon von setValue, sowas wie setOptionalValue, in dem der Alert fehlt.

                                            Wirklich?

                                            Liebe Grüße

                                            Felix Riesterer

                                            1. Hallo Felix,

                                              Wirklich?

                                              Ja, wirklich. Er summiert ja nicht blindlings alles was da ist. Diese Zeilennummern scheinen magic numbers zu sein, und die Seite scheint wirklich monströs, wenn die Zeilen bis 151 gehen. Vermutlich gerät die Seite so langsam an die Performancegrenzen des Browsers und ist sehr langsam, weil ja bei jedem Tastendruck neu durchgerechnet wird. Das sind fast 2000 Datenfelder, das ist eine Masse. Aber ich wüsste nicht, wie ich Franz eine Optimierungsstrategie vermitteln könnte.

                                              Rolf

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

                                                Er summiert ja nicht blindlings alles was da ist.

                                                wieso nicht? Was nicht da ist, kann ja nicht summiert werden. Ein anderer Ansatz ist ja nicht sinnvoll.

                                                Diese Zeilennummern scheinen magic numbers zu sein,

                                                Es wäre interessant zu wissen, wie er zu seinem unglaublichen HTML kommt. Wenn er eine Tabelle hätte, könnte man noch genauer rechnen, ohne dass fehlende Felder inmitten einer Zeile dazu führen, dass die restlichen Felder nach links aufrücken und so die Lücken jeweils ans Ende verschoben werden.

                                                und die Seite scheint wirklich monströs, wenn die Zeilen bis 151 gehen. Vermutlich gerät die Seite so langsam an die Performancegrenzen des Browsers und ist sehr langsam, weil ja bei jedem Tastendruck neu durchgerechnet wird.

                                                Vielleicht genügt es schon, eine Verzögerung einzubauen, innerhalb derer weitere Tastendrücke unwirksam werden. So eine Art Entprellen.

                                                Das sind fast 2000 Datenfelder, das ist eine Masse.

                                                Prinzipiell sollte das kein Problem sein. Nur auf wirklich ganz schwachen Rechnern kann das ein Performance-Problem werden. Vielleicht hilft es schon, wenn die Felder nur einmal ermittelt werden, um bei den Neuberechnungen diesen Schritt nicht wiederholen zu müssen?

                                                Aber ich wüsste nicht, wie ich Franz eine Optimierungsstrategie vermitteln könnte.

                                                Ja, Franz erscheint mir inzwischen sehr betriebsblind geworden zu sein. Vermutlich wäre ihm in einem direkten Gespräch (z.B. Telefonat) mehr geholfen, weil das seine Aufmerksamkeit bündelt, während dieser Thread die Aufmerksamkeit breit streut.

                                                Liebe Grüße

                                                Felix Riesterer

                                                1. Hallo Felix,

                                                  Was nicht da ist, kann ja nicht summiert werden.

                                                  Schon klar, aber wie willst Du Zeilen- und Spaltensummen durch HTML Struktur gruppieren? Man könnte versuchen, durch schlauen Einsatz von Klassen die Abläufe zu vereinfachen, aber das artet auch in Arbeit aus (und wirklich einfacher ist das auch nicht).

                                                  Das sind fast 2000 Datenfelder, das ist eine Masse.

                                                  Prinzipiell sollte das kein Problem sein.

                                                  Da ständig im DOM rumgesucht und string in float konvertiert wird, denke ich schon, dass das ein Problem ist. Wie du schriebst: Einmal auslesen wäre besser. D.h. der input-Handler sollte den Feldwert in ein globales Array übertragen und die Neuberechnung dann auf dem Array aufsetzen. Da wird man viel optimieren können, aber das ist dann schon anspruchsvoll.

                                                  Vermutlich wäre ihm in einem direkten Gespräch (z.B. Telefonat) mehr geholfen,

                                                  Plus einer Screenshare-Session und viel Zeit, um zu kapieren, worauf das eigentlich hinauslaufen soll.

                                                  Rolf

                                                  --
                                                  sumpsi - posui - obstruxi
                                          2. Also könnte man hier die fehlende Variable erstellen?

                                            function setValue(id, wert) {
                                               let element = document.getElementById(id);
                                               if (element)
                                                  element.value = wert
                                               else
                                            	!
                                            	Hier theoretisch 
                                            	!
                                            	}
                                            
                                            1. Hallo Franz,

                                              vielleicht verstehe ich ja wieder mal nicht, was Du erreichen möchtest.

                                              Was willst Du denn erstellen? Welche Variable, zu welchem Zweck? Das input Element mit dieser ID ist nicht da. Willst Du ein neues input Element in die Seite einfügen? Warum sollte man das tun, wenn die ganze Spalte fehlt?

                                              for (let i=1; i<=12; i++) {	
                                              		let summe = getInputAsFloat(document.j_um["EingabeS"+i+"Z94"] )+	
                                              					getInputAsFloat(document.j_um["EingabeS"+i+"Z95"] )+	
                                              					getInputAsFloat(document.j_um["EingabeS"+i+"Z151"] );	
                                              		total += summe;	
                                              		setValue("EingabeS"+i+"Z"+nr, summe);
                                              }
                                              

                                              Du schreibst, dass die Eingabefelder mit Spalte 1,2,3 ggf. nicht existieren. Außer EingabeS1Z96 dürften also auch EingabeS1Z94, EingabeS1Z95 und EingabeS1Z151 ebenfalls fehlen.

                                              Mir scheint es am sinnvollsten zu sein, mit setOptionalValue den Schreibvorgang einfach ins Leere laufen zu lassen.

                                              Rolf

                                              --
                                              sumpsi - posui - obstruxi
                                              1. Ja, aber ich versteh nicht wie ich setOptionalValue anwende!

                                                1. Hallo Franz,

                                                  jetzt geht mir langsam doch die Geduld aus. Wieso schreib ich mir den Wolf, wenn Du nichts davon verstehst und nur Code abschreibst?

                                                  Du hast alle Informationen. Versuch's.

                                                  Rolf

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

                                                    erst mal danke, nein ich schreibe nicht nur den Code ab, ich versuche zu verstehen, und ich danke dir tierisch das du so eine Engelsgedult hast.

                                                    Ja, und ich versuche es weiter....

                                                    Und das mit den fehlenden Werten habe ich seit Anfang versucht zu erklären..

                                                    Sorry, das ich mich anscheinend zu blöd ausgedrückt habe.

                                                    Franz 🙈

                            2. Hallo Franz,

                              ich hatte vor 3 Stunden auch selbst mal gebastelt.

                              Here be spoilers: https://jsfiddle.net/Rolf_b/za3hdogj/

                              Rolf

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

                                ja und wenn ich dir die ersten input felder jeder Zeile nehme geht es nicht mehr

                                https://jsfiddle.net/9b30kdtg/

                                schau bitte 😱

                                1. Hallo Franz,

                                  kann ja auch nicht gehen, weil ich gestern noch nicht gewusst habe, dass fehlende Felder der Normalfall sind. Ich sag nur: setOptionalValue.

                                  Rolf

                                  --
                                  sumpsi - posui - obstruxi
                                  1. Rolf, langsam blicke ich nicht mal hier in den Beiträgen durch, ich habe total den Faden verloren.

                                    Du meinst wahrschienlich das hier...

                                    function setValue(id, wert) {
                                       let element = document.getElementById(id);
                                       if (element)
                                          element.value = wert
                                       else
                                    	!
                                    	Hier theoretisch 
                                    	!
                                    	}
                                    
                                    1. Hallo Franz,

                                      Nein.

                                      Guck hier: https://forum.selfhtml.org/self/2020/aug/10/schleife-in-einer-javascript-funktion/1774464#m1774464

                                      Rolf

                                      --
                                      sumpsi - posui - obstruxi
                                      1. Okey, also so etwa

                                        function setOptionalValue(element) {
                                        	if(!element){
                                        		 !
                                        		 Element erstellen
                                        		 !
                                        		} 	
                                        	}
                                        
                                        1. Hallo Franz,

                                          ich fragte es schon dreimal, aber ich wiederhole mich auch nochmal: wieso sollte etwas erstellt werden?

                                          Rolf

                                          --
                                          sumpsi - posui - obstruxi
                                          1. ich brauche anscheinden länger als gewöhnlich.

                                            Weil ich eigentlich dachte, das das mein Problem sowie lösst

                                            wenn nicht vorhanden dann 0

                                            function getInputAsFloat(element) {
                                            
                                            return parseFloat(element.value.replace(/[^0-9 ]/g, "")) || 0;
                                            }
                                            

                                            deshalb dachte ich muss ich es erstellen....

                                            1. Hallo Franz,

                                              ich brauche anscheinden länger als gewöhnlich.

                                              Oder du denkst in komplett anderen Bahnen als ich, weil ich die Umstände nicht kapiere, unter denen Du operierst.

                                              Du hast mir erklärt:

                                              In deinem HTML fehlen gelegentlich mal Spalten. Zum Beispiel die Spalten 1, 2 und 3. Du hast dein Script aber so geschrieben, dass es einfach über alle Spaltennummern läuft, und es soll die fehlenden Spalten ignorieren. Ja?

                                              Du summierst - zum Beispiel für Spaltennummer 1 - die nicht existierenden input Elemente aus den Zeilen 94, 95 und 151. getInputAsFloat sorgt dafür, dass das Programm dabei nicht abbricht, sondern einfach 0 summiert.

                                              Das Element mit der ID "EingabeS1Z96" existiert ebenfalls nicht. Weil ja die ganze Spalte nicht existiert.

                                              Deswegen frage ich: Was soll da erstellt werden?

                                              Die logische Lösung wäre doch, in dem Fall einfach gar nichts zu tun, oder? Dafür habe ich setOptionalValue vorgeschlagen. Eine Funktion, die bei einem fehlenden Ziel nicht das Script tötet oder den lieben netten Programmierer ermahnt, sondern einfach schweigend schmollt und nichts tut.

                                              Rolf

                                              --
                                              sumpsi - posui - obstruxi
                                    2. Servus Franz!

                                      Rolf, langsam blicke ich nicht mal hier in den Beiträgen durch, ich habe total den Faden verloren.

                                      Ich verfolge das ganze auf mobilen Geräten und weiß auch nicht mehr richtig, wo's langgeht.

                                      Mir hilft es oft, noch mal zurückzugehen und mit dem jetztigen Wissen neu anzufangen.

                                      1. Ziele formulieren
                                      2. HTML optimieren
                                      3. JS
                                        • welche Variablen benötige ich?
                                        • was mache ich mit ihnen?

                                      Evtl. hilft Dir Felix Ansatz, der hier in einem Sub-Thread gepostet wurde.

                                      Vor ein paar Monaten hatte @Felix Riesterer bereits einmal eine Demo für einen Durchschnittsrechner geschrieben, bei dem unklar war, wie viele Eingabeelemente es gibt:

                                      https://forum.selfhtml.org/self/2020/may/12/mehrere-input-felder-in-einem-array-speichern-mit-javascript/1770439#m1770439

                                      Herzliche Grüße

                                      Matthias Scharwies

                                      --
                                      Einfach mal was von der ToDo-Liste auf die Was-Solls-Liste setzen.“
  3. Lieber Franz,

    ich hätte da noch eine grundlegende Idee.

    Was willst Du eigentlich erreichen? Du willst die Summe von Fließkommazahlen aus mehreren Eingabefeldern berechnen. In Deiner Funktion ist die Anzahl als auch die Namen der Elemente fest kodiert. Das funktioniert, ist aber sehr unflexibel.

    Wie wäre es, wenn Deine Funktion nur einen kleinen Informationshappen vorgeworfen bekäme, mit dem sie dann den Rest von selbst erledigte? Etwa so:

    function summe_eingaben (elternelement) {
      const felder = elternelement.querySelectorAll('[type="number"]');
      var summe = 0;
    
      felder.forEach((f) => { summe += getInputAsFloat(f); });
    
      return summe,
    }
    

    Mein Vorschlag basiert auf zwei Annahmen: Alle zu berechnenden Werte stehen in Elementen mit dem Attribut type und dessen Wert number (z.B. <input type="number">). Außerdem stehen alle diese Elemente irgendwo als Nachfahrenelemente eines bestimmten Elternelements, in dem ansonsten keine weiteren Elemente dieser Art stehen, die nicht mitberechnet werden sollen.

    Mit der Methode querySelectorAll kann man eine Liste von Elementen erhalten, auf die ein Selektor passt (wie bei CSS auch). Diese Liste ist ein Objekt, welches die Methode forEach kennt (nur alte Browser haben hier eventuell ein Problem), mit der man jedes Element der Liste abarbeiten kann. Dazu muss man der forEach-Methode eine Funktion als Argument übergeben, in der geregelt wird, was mit dem einzelnen Element der Liste passieren soll. Meine Schreibweise oben ist mit einer Pfeilfunktion, aber das hätte man auch "altmodisch" so schreiben können:

    felder.forEach(
      function (f) {
        summe += getInputAsFloat(f);
      }
    );
    

    Die Funktion, die man forEach zum Fraße vorwirft, bekommt zwei Parameter übertragen, von denen der erste eine Referenz auf das aktuelle Element der Liste ist (hier in der Variable f entgegen genommen), und der zweite die laufende Nummer innerhalb der Liste (wird hier ignoriert).

    Damit hast Du eine flexiblere Lösung, die sich auch nicht um Namen, ID oder sonstwas kümmert, sondern brav nimmt, was da ist, um dann zusammen zu rechnen.

    Liebe Grüße

    Felix Riesterer

    1. Hallo Felix,

      eigentlich eine schöne Idee. Ich frage mich nur, ob sie für Franz nicht zu kryptisch ist. Sein Versuch, die Schleife mit einem "hängenden Plus" zu bauen, zeigt noch massiven Lernbedarf bei den Basic-Basics, und ihm da mit geschachtelten Funktionen, forEach Callbacks und all dem Scoping-Gedöns zu kommen, was da dran hängt, das ist schon eine Herausforderung.

      Deshalb würde ich die Einsteigerformulierung eher so gestalten:

      function summe_eingaben (elternelement) {
        const felder = elternelement.querySelectorAll('[type="number"]');
      
        let summe = 0;
        for (let i=0; i < felder.length; i++) {
          summe += getInputAsFloat(felder[i]);
        }
      
        return summe,
      }
      

      Das Problem „was muss addiert werden“ könnte man übrigens, wenn das mit dem Elternelement nicht hinhaut, auch mit Klassen lösen. Ggf. könnte man sogar den Selektor als zweiten Parameter übergeben (mit 'input[type=number]' als Default).

      Rolf

      --
      sumpsi - posui - obstruxi
  4. Ganz am Anfang wird ja geschaut ob die Variable da ist oder nicht. Falls Sie nicht da ist, wird eine 0 gesetzt und weitergerechnet, was ja klappt. Doch wenn ich jetzt auch horizontal rechne klappt es nicht mehr..

    function getInputAsFloat(element)
     { return (element
             ? parseFloat(element.value.replace(/[^0-9 ]/g, "")) || 0
             : 0);
     }
    

    Hier geht es: https://jsfiddle.net/3gfs9cwa/2/

    Hier geht es nicht (es fehlt jeweils die erste Spalte mit den Werten Wert11, Wert21, Wert31 und Wert41 )

    https://jsfiddle.net/3gfs9cwa/3/

    da komische ist aber, das es in der gleichen Zeile trotzdem klappt nur vertikal nicht!

    Gerade habe ich geglaubt ich durchschaue es ...

    1. Lieber Franz,

      ich vermute, dass das genau davon kommt, dass Du mit den Bezeichnern programmatisch hantierst. Würdest Du Dich rein an der Dokumentstruktur orientieren, wäre das Ganze dynamisch und sicherer.

      Da Du von Zeilen und Spalten sprichst, denkst Du im Grunde in einer Tabelle, bei der jede Zeile die exakt gleiche Anzahl an Feldern ("Spalten") hat. Und selbst wenn dem nicht so wäre, könntest Du das bei einer dynamischen Herangehensweise kompensieren!

      Ich vereinfache Dein jsFiddle-Beispiel vom Markup her:

      <ol id="daten">
        <li>
          <label>Zeile 1 Wert 1 <input type="number"></label>
          <label>Zeile 1 Wert 2 <input type="number"></label>
          <label>Zeile 1 Wert 3 <input type="number"></label>
        </li>
        <li>
          <label>Zeile 2 Wert 1 <input type="number"></label>
          <label>Zeile 2 Wert 2 <input type="number"></label>
        </li>
      </ol>
      

      Ich muss die <label> im HTML haben, kann ihre Darstellung nötigenfalls mit CSS aber ausblenden. Egal. Die fehlende dritte Zahl in der zweiten Zeile ist Absicht, um diesen "Fehler" in JavaScript kompensieren zu müssen, damit das Script sauber arbeitet. Außerdem habe ich die Zeilen als Listenpunkte realisiert, damit man eine zumindest auf Zeilenebene semantische Struktur hat (deine div-Suppe will mir so gar nicht schmecken).

      So. Nun zu den Zeilen und Spalten.

      function holeWerte () {
        const liste = document.getElementById("daten");
        const zeilen = liste.getElementsByTagName("li");
        const tabelle = []; // das wird unsere Datentabelle
        var felder; // benötigen wir später
      
        for (var z=0; z < zeilen.length; z++) {
      
          // Tabellenzeile anlegen
          tabelle[z] = []; // noch leer
      
          felder = zeilen[z].querySelector('input[type="number"]');
      
          for (f = 0; f < felder.length; f++) {
            // Wert des Feldes in unserer Tabellenzeile eintragen
            tabelle[z][f] = parseFloat(
              felder[f].value.replace(/[^0-9 ]/g, "")
            ) || 0;
          }
        }
      
        return tabelle;
      }
      

      Die Variable tabelle wird ein Array, dessen Inhalte selbst wieder Arrays sind. Damit hast Du eine zweidimensionale Abbildung der Werte Deiner Eingabefelder. Man kann also mit tabelle[y][x] (y = Zeile, x = Spalte) auf eine bestimmte "Zelle" zugreifen. Damit sollte eine Berechnung von Spalten und Zeilen kein Problem mehr sein:

      function summe_spalte (x) {
        const zeilen = holeWerte();
        var summe = 0;
      
        for (var y=0; y < zeilen.length; y++) {
          // Zelle vorhanden?
          if (zeilen[y][x]) {
            summe += zeilen[y][x];
          }
        }
      
        return summe;
      }
      
      function summe_zeile (y) {
        const zeilen = holeWerte();
        var summe = 0;
      
        // Zeile vorhanden?
        if (zeilen[y]) {
      
          for (x = 0; x < zeilen[y].length; x++) {
            summe += zeilen[y][x];
          }
        }
      
        return summe;
      }
      

      Der gesamte Code hier ist ungetestet, sollte aber veranschaulichen, wie man das dynamisch lösen könnte. Außerdem kann man sehen, dass fehlende Zellen ignoriert werden, was so ähnlich ist, als stünde darin der Wert "0".

      Liebe Grüße

      Felix Riesterer