Therry: 2 Felder berechnen, hin <> her, mit Javascript

Hallo,

ich habe da mal ein Frage, bei der ich nicht weiter komme.

Ich habe zwei Eingabefelder. In das eine schreibe ich eine Zahl, die dann mit 10 multipliziert wird und im zweiten Eingabefeld wieder ausgeben wird. Nun möchte ich erreichen, dass wenn ich im zweiten Eingabefeld eine Zahl eingebe, diese mit 12 dividiert wird und im ersten Ausgabefeld ausgegeben wird.

So das ich entweder in das erste oder zweite Eingabefeld schreibe.

Bis jetzt habe ich das hier erarbeitet.

<form name="rechner">
<input type="text" id="Eingabe" onkeyup="Rechner()"/  >
<input type="text" id="EingabeAusgabe" onkeyup="Rechner()"/  >
</form>	
function Rechner() {				   
	let rechnung_1 = zahl_auslesen(document.rechner.Eingabe) *10;
	document.getElementById("EingabeAusgabe").value=(rechnung_1);
	}	
	
function zahl_auslesen(element) {
	let input = parseFloat(element.value);
	return input;
	}

Therry

  1. Hallo Therry,

    • nimm <input type="number">, dann bekommst Du nur gültige Eingabem
    • nimm das input-Event, nicht keyup. Dann funktioniert es auch bei anderen Bedienverfahren als Tastatur
    • du brauchst zwei verschiedene Rechner-Funktionen. Eine für *10, eine für /12.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Erstmal, vielen Dank für die Informationen.

      https://www.w3schools.com/js/js_events_examples.asp

      Ich verstehe das so, das das onkeyup ein INPUT Event ist!

      Das mit number ist nicht schlecht, spart wahrscheinlich spätere Probleme aus.

      Ich habe zuerst die beiden Rechnungen in einer Funktion gehabt. Da gab es merkwürdige Ausgaben. Doch danke deiner Informationen, habe ich zwei funtionen daraus gemacht.

      
      function Rechner1() {				   
      	let rechnung_1 = zahl_auslesen(document.rechner.Eingabe) *12;
      	document.getElementById("EingabeAusgabe").value=(rechnung_1);
      	}	
      
      function Rechner2() {				   
      	let rechnung_2 = zahl_auslesen(document.rechner.EingabeAusgabe) /12;
      	document.getElementById("Eingabe").value=(Math.round(rechnung_2));
      	}
      	
      function zahl_auslesen(element) {
      	let input = parseFloat(element.value);
      	return input;
      	}
      
      

      Therry

      1. Hallo,

        Ich verstehe das so, das das onkeyup ein INPUT Event ist!

        nein, das ist ein Taste-hoch-Event. Teste deine Seite mal im Smartphone, dann sollte das Problem klar sein. Oder befüll das Input-Element mal per Copy & Paste.

        Gruß
        Jürgen

        1. Hallo Jürgen,

          Ich verstehe das so, das das onkeyup ein INPUT Event ist!

          ja, wenn es auftritt, tritt es im Zusammenhang mit einer Eingabe auf. Aber nicht notwendigerweise.

          nein, das ist ein Taste-hoch-Event. Teste deine Seite mal im Smartphone, dann sollte das Problem klar sein. Oder befüll das Input-Element mal per Copy & Paste.

          Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

          Live long and pros healthy,
           Martin

          --
          Versuchungen sollte man nachgeben. Wer weiß, ob sie wiederkommen.
          1. Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

            Bei mir und Millionen anderen nicht. Ich nutze zum Einfügen regelmäßig die mittlere Maustaste. Den Text hab ich zuvor durch markieren in die Zwischenablage übernommen.

            Unter Windows geht das freilich nicht - oder halt nicht ohne weiteres.

            1. Hallo,

              Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

              Bei mir und Millionen anderen nicht. Ich nutze zum Einfügen regelmäßig die mittlere Maustaste.

              das habe ich als Option auch schon mal gesehen; bei irgendeiner Linux-Distro war das sogar die Defaulteinstellung. Habe ich aber ziemlich schnell wieder abgestellt: Ich fand keinen Mehrwert darin, aber es hat hin und wieder gestört.

              Den Text hab ich zuvor durch markieren in die Zwischenablage übernommen.

              Auch davon habe ich schon gehört. Das allerdings würde mich tierisch nerven. Denn das bloße Markieren eines Textfragments heißt noch lange nicht, dass ich dieses Stück auch kopieren und damit den Inhalt der Zwischenablage überschreiben will. Vielleicht markiere ich nur ein Stück, um es zu löschen? Vielleicht nur zur momentanen visuellen Hervorhebung? Oder vielleicht, um den Text per D&D zu verschieben, ohne dabei den Inhalt der Zwischenablage plattzumachen.
              Ein automatisches Copy nach dem Markieren wäre für mich jedenfalls ein No-Go.

              Live long and pros healthy,
               Martin

              --
              Versuchungen sollte man nachgeben. Wer weiß, ob sie wiederkommen.
          2. @@Der Martin

            Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

            ?? Nicht eine Maus-Aktion? Guckst du.

            😷 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,

              Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

              ?? Nicht eine Maus-Aktion?

              dass es per Maus und Kontextmenü auch möglich ist, ist mir klar. Aber wer macht das tatsächlich in der Praxis? Das meinte ich mit "aber nicht notwendigerweise".

              Guckst du.

              Ja. Kenn ich. Schätze ich aber eher als untypisch ein. Auch die Methode mit der mittleren Maustaste, die Jörg ins Spiel gebracht hat, ist vermutlich eher exotisch.

              Live long and pros healthy,
               Martin

              --
              Versuchungen sollte man nachgeben. Wer weiß, ob sie wiederkommen.
              1. @@Der Martin

                Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

                ?? Nicht eine Maus-Aktion?

                dass es per Maus und Kontextmenü auch möglich ist, ist mir klar.

                Und auch, dass es auch per … möglich ist? Und auch per … Sowie per … Nicht zu vergessen …

                Aber wer macht das tatsächlich in der Praxis?

                Dass es verschiedenste Arten gibt, ein Eingabefeld zu füllen. Und dass es keinen Sinn macht, überhaupt darüber nachzudenken, welche das im einzelnen sind – man vergisst sowieso welche.

                Deshalb muss man auf ein Event lauschen, dass bei jeglichen Änderungen im Eingabefeld feuert – egal, wie die Änderungen nun vollzogen wurden. Inclusive design. Alle key…-Events sind falsch.

                Schätze ich aber eher als untypisch ein.

                Diese Denke ist gefährlich. Das birgt die Gefahr, bei exclusive design zu landen und etliche Nutzergruppen auszuschließen.

                😷 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. Hi,

                  Auch C&P ist üblicherweise (aber nicht notwendigerweise) eine Tastatur-Aktion.

                  ?? Nicht eine Maus-Aktion?

                  dass es per Maus und Kontextmenü auch möglich ist, ist mir klar.

                  Und auch, dass es auch per … möglich ist? Und auch per … Sowie per … Nicht zu vergessen …

                  so viele fallen mir da gar nicht ein. Aber das ist unerheblich.

                  Aber wer macht das tatsächlich in der Praxis?

                  Dass es verschiedenste Arten gibt, ein Eingabefeld zu füllen. Und dass es keinen Sinn macht, überhaupt darüber nachzudenken, welche das im einzelnen sind – man vergisst sowieso welche.

                  Keine Einwände.

                  Deshalb muss man auf ein Event lauschen, dass bei jeglichen Änderungen im Eingabefeld feuert – egal, wie die Änderungen nun vollzogen wurden. Inclusive design. Alle key…-Events sind falsch.

                  Völlig einverstanden.

                  Schätze ich aber eher als untypisch ein.

                  Diese Denke ist gefährlich.

                  Wenn man mit dieser Überlegung ins Rennen startet, ja. Aber über den Punkt waren wir ja schon längst hinaus - die Empfehlung, das input-Event zu nutzen, stand schon unwidersprochen im Raum. Es ging nur noch um statistisch-philosophische Überlegungen, welche Methoden wohl wie häufig genutzt werden.

                  Auch wenn schon die Entscheidung gefallen ist, dass man zum Essen beim Italiener einkehren will, ist es völlig unbedenklich, über das Angebot, die Preise und die Kundschaft beim Griechen, beim Inder und beim Chinesen zu diskutieren.

                  Du solltest einfach etwas aufmerksamer lesen. 😉

                  Live long and pros healthy,
                   Martin

                  --
                  Versuchungen sollte man nachgeben. Wer weiß, ob sie wiederkommen.
            2. Hallo Gunnar Bittersmann,

              ich würde auch auf üblicherweise Tastatur tippen. Dass es auch anders geht, stand wohl nicht zur Disposition.

              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 Therry,

        Ich verstehe das so, das das onkeyup ein INPUT Event ist!

        Das merkst Du Dir so besser nicht, das verwirrt nur. Es gibt ein konkretes Event namens input. Und es gibt diverse Events, die auf Grund von Benutzer-Input in einem <input> Element ausgelöst werden können. Eins davon heißt keyup und wird gefeuert, wenn Du eine Taste drückst und dann wieder loslässt. Das hast Du verwendet.

        Ein anderes heißt input und feuert dann, wenn sich der Wert im <input> Element ändert. Das ist also mehrdeutig, es gibt das input Event und das <input> Element.

        Vorteil des input Events ist, dass es auch dann feuert, wenn sich der Feldinhalt anders als durch Drücken einer Taste ändert. Z.B. durch Einfügen per Maus oder durch Klicken der Pfeil-Icons an einem Input-Element mit type=number.

        Und ganz wichtig: Das input Event feuert nicht, wenn Du dem Element per JavaScript einen Wert zuweist. Das ist sehr gut so. Denn anderfalls würden deine beiden Rechner-Funktionen dazu führen, dass die beiden Eingabefelder sich gegenseitig mit input-Events totschießen würden.

        Was ich vorhin noch zu schreiben vergaß: <input type="number"> hat eine valueAsNumber Eigenschaft. Nimm die, statt der value Eigenschaft. Das erspart Dir den parseFloat.

        Statt

        zahl_auslesen(document.rechner.Eingabe)

        einfach

        document.rechner.Eingabe.valueAsNumber

        Ein Zeichen weniger und die Funktion kann weg 😀

        Rolf

        --
        sumpsi - posui - obstruxi
        1. Schaut gut aus

          <input type="number" id="e_1" oninput="Rechner1()"/ >
          <input type="number" id="a_1" oninput="Rechner2()"/  >
          
          

          Und so habe ich esnochmal umgeschreiben

          
          function Rechner1() {	
          	document.getElementById("a_1").value=document.rechner.e_1.valueAsNumber *12;
          	}	
          
          function Rechner2() {				   
          	document.getElementById("e_1").value=Math.round(document.rechner.a_1.valueAsNumber /12);
          	}
          
          

          Aber mir ist aufgefallen, das, wenn ich das Feld mit number deklariert habe, ich z.B. keine Währungszeichen übergeben kann, da ja das das number Feld verbietet.

          Therry

          1. Hallo,

            Aber mir ist aufgefallen, das, wenn ich das Feld mit number deklariert habe, ich z.B. keine Währungszeichen übergeben kann, da ja das das number Feld verbietet.

            ja, natürlich. Aber wenn das Währungszeichen Teil der Eingabe wäre, müsstest du es für die Berechnung erst wieder rauspopeln. Schreib es einfach als festen Text vor oder hinter das input-Feld.

            Es ist sicher kein Zufall, dass bei den Onlinebanking-Portalen das Währungszeichen auch immer separat steht.

            Live long and pros healthy,
             Martin

            --
            Versuchungen sollte man nachgeben. Wer weiß, ob sie wiederkommen.
          2. Jetzt habe ich noch ein zweites Problem, für da sich keine Lösung habe! Um meine Rechenzeile nicht 20 oder mehrmals auszurufen, habe ich mir gedacht dies, mittels Schleife auszuführen. Doch ich finde keine möglichkeit einen Namen und eine Var zu verbinden.

            Statt "a_1" und .e_1. Müsste die Zählvariable eingebunden werden

            for (var i = 1; i <= 10; i++) {
            document.getElementById("a_1").value=document.rechner.e_1.valueAsNumber *12;
            }
            
            

            Therry

            1. Hallo Therry,

              du möchtest vielleicht ein Buch über JavaScript kaufen und durchlesen?

              Oder dich hier anfangen, einzulesen?

              Um auf deine Frage einzugehen:

              Du musst dir die Feld-IDs zur Laufzeit dynamisch zusammenbauen, aus einem "e_" oder "a_" und einer laufenden Nummer. Das ist kein Problem, man kann einen String und eine Zahl einfach aneinander hängen. Wenn in i der Wert 1 steht, ergibt "a_" + i die Zeichenkette "a_1". Für getElementById reicht das.

              Für die Zugriffe, die Du über die document.form.element Schreibweise machst (also document.Rechner.e_2 oder so), funktioniert das nicht. Die Punkt-Schreibweise ist nur möglich, wenn Du den Namen der Objekteigenschaft vorab kennst. Steht der Name in einer Variablen, musst Du auf die [] Schreibweise zurückgreifen, wie bei Arrays. Enthält die Variable id den String "e_2", dann würdest Du mit document.Rechner[id] auf das e_2 Input-Element zugreifen.

              Diese unterschiedliche Vorgehensweise solltest Du aber meiden. Vermutlich weißt Du gar nicht, dass document.getElementById("e_2") und document.Rechner.e_2 in deinem Fall das gleiche Ergebnis haben. Verwende eine einheitliche Zugriffsmethode. Um das Problem mit variablen Feldnummern gleich mit zu erschlagen, könntest Du den Zugriff auf die input-Elemente in einer Funktion einkapseln:

              function getField(typ, nr) {
                 let id = typ + "_" + nr;
                 return document.rechner[id];
              }
              

              Diese getField Funktion liefert Dir nun die input-Elemente, basierend auf Typ (e oder a) und Nummer. Sie setzt das einfach zu a_1 oder e_47 zusammen.

              getField("e", 1) liefert Dir das Gleiche wie document.rechner.e_1, oder auch wie document.getElementById("e_1").

              Damit könntest Du schreiben:

              getField("a", 1).value = getField("e", 1).valueAsNumber * 12;
              

              oder, wenn's eine Schleife sein soll:

              for (let i=1; i<=10; i++) {
                 getField("a", 1).value = getField("e", 1).valueAsNumber * 12;
              }
              

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Danke für deine Antwort Rolf, deine Geschwindigkeit ist nicht schlecht, ich bin aber noch ziemlich langsam, sorry.

                Aber um das ganze in eine Schleife zu packen, muss ich wohl erst die Zuordnung, bzw. die Ausgabe der einzelnen Variablen erkenne, verstehen! Ich hätte zwei Fragen, Habe ich die Möglichkeit mir die Variablen die Im Script durchlaufen anzeigen zu lassen, so ähnlich wie mit print_r ? Und die weitere

                Steht der Name in einer Variablen, musst Du auf die [] Schreibweise zurückgreifen, wie bei Arrays. Schreibst du:

                Aber bei der Übernahme des Ergebnisses von let rechnung_1 funktioniert es nicht.

                .value=("rechnung_" +test);

                Ich kann ja schlecht document.rechner hernehmen, ich möchte doch nur innerhalb der Funktion auf die Variable zugreifen.

                
                var test = 1;
                let rechnung_1 = zahl_auslesen(document.rechner['e_' + test]) *12;
                document.getElementById("a_" + test).value=("rechnung_" +test);
                
                
                1. Hallo Therry,

                  wir denken offenbar nicht entlang der gleichen Linien, denn ich erkenne deine Schwierigkeit nicht. Ich versuche nochmal, dein Problem mit meinen Worten darzustellen.

                  Wenn ich Dich richtig verstanden habe, möchtest Du dies

                  document.getElementById("a_1").value=document.rechner.e_1.valueAsNumber *12;
                  document.getElementById("a_2").value=document.rechner.e_2.valueAsNumber *12;
                  ...
                  document.getElementById("a_9").value=document.rechner.e_9.valueAsNumber *12;
                  document.getElementById("a_10").value=document.rechner.e_10.valueAsNumber *12;
                  

                  vermeiden und es mittels einer Schleife realisieren. Da, wo die Fragezeichen sind, weißt Du nicht, was Du machen sollst.

                  for (let i=1; i<=10; i++) {
                     document.getElementById(???).value = document.rechner.***.valueAsNumber * 12;
                  }
                  

                  Beim ersten Fragezeichen ist es einfach. Da wird eine Zeichenkette gebraucht, die aus "a_" und der Nummer besteht. Dafür kannst Du den + Operator verwenden, der addiert Zahlen oder hängt Zeichenketten aneinander, je nach dem, was Du ihm gibst. 2+2 ergibt 4, "2" + 2 ergibt "22" und "a_"+i ergibt beispielsweise "a_3". Achte auf die Anführungszeichen, Zahlen und Zeichenketten sind was unterschiedliches, auch wenn JavaScript eine Zahl bei Bedarf automatisch in eine Zeichenkette umwandelt.

                  Beim zweiten Fragezeichen musst Du deine Arbeitsweise ändern. document.rechner liefert Dir das HTMLFormElement-Objekt, das das <form name="rechner"> Element in JavaScript repräsentiert. In diesem Objekt gibt es für jedes Form-Element (input, button, etc), das ein id oder ein name Attribut hat, eine Eigenschaft dieses Namens. Ein <input type="number" id="e_1"> erzeugt auf dem HTMLFormElement Objekt eine Eigenschaft document.rechner.e_1.

                  Nun kennst Du aber den Namen der Eigenschaft zur Programmierzeit nicht. Du bestimmst ihn erst zur Laufzeit des Scripts und hast ihn in einer Variablen, die - sagenwirmal - id heißt. Aber: document.rechner.id sucht eine Eigenschaft mit Name "id", und nicht die Eigenschaft, deren Name in id steht. Dafür gibt es die Schreibweise mit eckigen Klammern: document.rechner[id] tut das, was Du brauchst: Es sucht in document.rechner eine Eigenschaft, deren Name in der Variablen id steht.

                  Du könntest die Fragezeichen also so füllen:

                  for (let i=1; i<=10; i++) {
                     document.getElementById("a_"+i).value = document.rechner["e_"+i].valueAsNumber * 12;
                  }
                  

                  Und dann bin ich noch einen Schritt weitergegangen und habe angemerkt, dass Du hier zwei verschiedene Wege zum gleichen Ziel gehst. document.getElementById(id) sucht auf der ganzen Seite ein HTML Element mit dieser id. document.rechner[id] tut etwas ähnliches, nur begrenzt auf das rechner-Form. Es ist - denke ich - schlechter Stil, so etwas zu mischen. Deine Ausgabe-Elemente sind ebenfalls inputs im Form, es könnte also einheitlich so aussehen

                  for (let i=1; i<=10; i++) {
                     document.rechner["a_"+i].value = document.rechner["e_"+i].valueAsNumber * 12;
                  }
                  

                  Weil Du ohnehin die Aufgabe hast, Ein- und Ausgabefelder über ihre Feldnummer anzusprechen, habe ich Dir eine Funktion vorgeschlagen, die das Heraussuchen des Feldes zentral durchführt. Das ist getField.

                  for (let i=1; i<=10; i++) {
                     getField("a", i).value = getField("e", i).valueAsNumber * 12;
                  }
                  

                  Was Du davon nun verwenden willst, sei Dir überlassen.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Ich hoffe du schlägst mich nicht gleich gegen die Wand. Aber je mehr Infos ich bekomme, desto grusliger wird es

                    Wenn ich Dich richtig verstanden habe, möchtest Du dies vermeiden und es mittels einer Schleife realisieren. Da, wo die Fragezeichen sind, weißt Du nicht, was Du machen sollst.

                    Ja

                    ABER.

                    Ich hatte es auch schon in einer Zeile zusammengefasst. Dann habe ich es aber wieder auseinander gemacht.

                    Weil wenn ich es so mache

                    document.getElementById("a_2").value=document.rechner.e_2.valueAsNumber *12;
                    

                    wie, oder in welcher Variable ist dann mein Ergebnis mit dem ich später, außerhalb z.B. der Schleife dann weiterarbeiten kann.

                    Oder habe ich womöglich schon eine Variable mit dem Inhalt aus diesem Code?

                    document.getElementById("a_2").value=document.rechner.e_2.valueAsNumber *12;
                    
                    

                    Therry

                    Boah, ich komme mir vor wie in einer Zaubershow

                    1. Hallo Therry,

                      Boah, ich komme mir vor wie in einer Zaubershow

                      Aber selbstverständlich. Das dritte Clarkesches Gesetz!

                      Jetzt verstehe ich aber gar nicht mehr, wo Du hinwillst.

                      Du kannst den ermittelten Wert natürlich noch in einer weiteren Variablen speichern.

                      let a2Wert = document.rechner.e_2.valueAsNumber * 12;
                      document.getElementById("a_2").value = a2Wert;
                      

                      allerdings ist das so eine Sache, wenn Du das in einer Schleife machst. Du berechnest da ja nicht nur einen Wert, sondern zehn. Möchtest Du nachher alle 10 Werte noch zur Verfügung haben? In dem Fall bräuchtest Du ein Array, das ist eine spezielle JavaScript-Datenstruktur, in der Du über eine Indexnummer mehr als einen Wert speichern kannst. Unser Wiki weiß mehr dazu.

                      let aWerte = [ ];     // aWerte als leeres Array anlegen
                      for (let i=1; i<=10; i++) {
                         aWerte[i] = document.rechner["e_"+i].valueAsNumber * 12;
                         document.rechner["a_"+i].value = aWerte[i];
                      }
                      

                      Suchtest Du das?

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                      1. Ja, ich denke schon..

                        Das mit dem Lockdown ist so eine Sache, da setzt man sich eigentlich nicht so ans lernen wie man soll.

                        Ich habe es nun mein Projekt zusammengefasst.
                        Ich habe pro Zeile zwei Felder.

                        <?php
                        echo'<form name="rechner">';
                        for($i=1; $i<=10; $i++) {
                        	echo'E <input type="number" id="e_'.$i.'" oninput="Rechner1()"/>';
                        	echo'A <input type="number" id="a_'.$i.'" oninput="Rechner2()"/>';
                        	echo'<hr/>';
                        	}
                        echo'<input type="text" id="ausgabe" oninput="Rechner1()">';
                        echo'</form>';		
                        ?>
                        

                        Wenn man in das linke schreibt wird es *12 genommen und im zweiten Feld das Ergebnis ausgegeben.

                        Wenn man in das rechte schreibt wir /12 genommen und das Ergebnis im linken Feld ausgegeben. Da es dann zu Kommazahlen kommt, habe ich eine Rundung eingebaut.

                        Nun werden alle rechten Ergebnisse zusammengezählt und am Ende der Eingaben in einem weiteren INPUT Feld ausgegeben.

                        Da ich dann immer eine NaN Meldung kam, habe ich in einer Schleife wenn ein Feld leer ist eine 0 gesetzt. So kommt es zu keiner Meldung und es wird auch sofort ausgegeben.

                        Jetzt habe ich aber 1 Fehler und einen kleinen Fehler die nicht hinhauen.

                        1. Es sollen ja alle rechten Wert zusammengezählt werden und automatisch am Schluss ausgegeben werden. Das klappt, solange ich in das linke Feld schreibe und das Ergebnis im rechten ausgegeben wird. Schreibe ich dagegen ins rechte Feld, kommt zwar im linken das Ergebnis, aber es wird im rechten nicht weiter addiert. Obwohl ich dachte wenn ich oninput hernehme, wird jede Änderung im Feld erkannt.

                        2. Meine Rechnung in der alle werte zusammengefasst werden, sieht mehr als bescheiden aus. Aber sie in einer Schleife zusammenzufassen, denke ich ist auch nicht der Weisheit letzter Schluss?

                        Auch stellt sich weiter die Frage für mich muss ich immer die beiden funktionen aufrufen Rechner1 Rechner2 ? Weil wäre es nicht einfach zum übergabe der Variable, es in eienr einzigen Funktion zu haben.

                        
                        
                        function Rechner1() {
                        	let aWerte = [ ]; 
                        	for (let i=1; i<=10; i++) {
                        	aWerte[i] = document.rechner["e_"+i].valueAsNumber * 12;
                        	   document.rechner["a_"+i].value = Math.round(aWerte[i]);
                        	}
                        
                        	for (let i=0; i<aWerte.length; i++) {
                        		if(isNaN(aWerte[i])){aWerte[i]=0;} 
                        		}
                        
                        document.rechner["ausgabe"].value =	aWerte[1]+aWerte[2]+aWerte[3]+aWerte[4]+aWerte[5]+aWerte[6]+aWerte[7]+aWerte[8]+aWerte[9]+aWerte[10];
                        }
                        
                        function Rechner2() {
                        	let aWerte = [ ]; 
                        	for (let i=1; i<=10; i++) {
                        	   aWerte[i] = document.rechner["a_"+i].valueAsNumber / 12;
                        	   document.rechner["e_"+i].value = Math.round(aWerte[i]);
                        	}	
                        
                        }
                        
                        1. Hi,

                          Nun werden alle rechten Ergebnisse zusammengezählt und am Ende der Eingaben in einem weiteren INPUT Feld ausgegeben. Jetzt habe ich aber 1 Fehler und einen kleinen Fehler die nicht hinhauen.

                          1. Es sollen ja alle rechten Wert zusammengezählt werden und automatisch am Schluss ausgegeben werden. Das klappt, solange ich in das linke Feld schreibe und das Ergebnis im rechten ausgegeben wird. Schreibe ich dagegen ins rechte Feld, kommt zwar im linken das Ergebnis, aber es wird im rechten nicht weiter addiert. Obwohl ich dachte wenn ich oninput hernehme, wird jede Änderung im Feld erkannt.

                          im rechten Feld wird bei oninput die Funktion Rechner2() ausgeführt.

                          Darin ist kein Berechnen der Summe enthalten. Also wird's auch nicht berechnet/ausgegeben.

                          Lagere die Berechnung der Summe in eine dritte Funktion aus, und rufe sie sowohl am Ende von Rechner1 als auch von Rechner2 auf.

                          1. Meine Rechnung in der alle werte zusammengefasst werden, sieht mehr als bescheiden aus. Aber sie in einer Schleife zusammenzufassen, denke ich ist auch nicht der Weisheit letzter Schluss?

                          Vielleicht nicht der letzte Schluß, aber m.E. sinnvoll.

                          cu,
                          Andreas a/k/a MudGuard

                        2. Hallo Therry,

                          okay. So langsam steige ich da durch 😀

                          (Edit: Als Mudgard gepostet hat, war ich gerade am Schreiben. Boah ey, so lange?!)

                          Du überlegst an

                          , es in eienr einzigen Funktion zu haben.

                          Das ist eigentlich nicht der Weg. Eine Funktion - eine Aufgabe, das ist eigentlich das Prinzip, dem man folgen sollte. Mehrere Funktionen, die klein, gemein und wiederverwendbar sind, sind besser als ein Fettsack, der nur ein Ding kann.

                          Der übliche SelfHTML Vorschlag wäre: mach's ganz anders. Hm. Ich will Dich nicht ärgern.

                          Hauptfehler ist: Wenn jemand ein A-Feld ändert, füllst Du zwar aWerte auf, aber summierst es nicht und gibst es auch nicht aus. Da fehlt Code.

                          Ein kleiner Fehler ist: Das Summenfeld sollte kein oninput haben. Es sollte auch eigentlich kein input Element, sondern ein output Element sein, da soll doch niemand was eingeben können. Wenn es einen Rahmen haben soll, kannst Du das im CSS mit border:1px solid black ändern.

                          Die "Bescheidenheit der Summierung" kann man durch Aufaddieren in einer Schleife lösen. Ganz grob geht es so:

                          let summe = 0;
                          for (let i=0; i<=10; i++) {
                             let wert = document.getElementById("a_"+i).valueAsNumber;
                             if (!isNaN(wert))
                                summe = summe + wert;
                          }
                          

                          Nicht kopieren, das geht besser. Ich muss dafür nur eben was erklären. Wenn in einem input-Feld nichts steht, liefert valueAsNumber NaN. In diesem Fall möchtest Du mit dem Wert 0 rechnen. Es gibt in JavaScript einen Trick zum Umgang mit booleschen Werten (also true und false, die bei Vergleichen entstehen). JavaScript interessiert sich nicht für true und false, sondern für "sowas wie true" oder "sowas wie false". Auf gut Englisch: truthy oder falsy. Jeder Wert in JavaScript, wirklich jeder, ist entweder truthy oder falsy, und es gibt genaue Regeln, die das festlegen. Bei Zahlen ist es so, dass NaN und 0 falsy sind, alles andere ist truthy.

                          Der zweite Trick sind die logischen Operatoren für AND und OR, in JavaScript: && und ||, die boolesche Werte entgegennehmen und mit UND oder ODER zu einem neuen booleschen Wert verknüpfen. Korrektur: sie tun das nicht. Sie erwarten boolesy-Werte, also etwas, was truthy oder falsy ist, und geben dann einen von beiden zurück. Details in unserem Wiki.

                          Bei a || b ist es so, dass a zurückgegeben wird, wenn es truthy ist, sonst b.

                          Für uns heißt das: statt mühsam mit isNaN(wert) abzufragen, kannst Du einfach (wert || 0) schreiben, um NaN zu 0 zu machen.

                          Was auch hilft, ist eine bessere Verteilung des Codes. Meinen Vorschlag einer Zugriffsfunktion für die Felder halte ich immer noch für gut. Ich zeig's Dir mal:

                          function Rechner1() {
                          	for (let i=1; i<=10; i++) {
                          		schreibeWert("a", i, leseWert("e", i) * 12);
                          	}
                          
                          	berechneSumme();
                          }
                          
                          function Rechner2() {
                          	for (let i=1; i<=10; i++) {
                          		schreibeWert("e", i, Math.round(leseWert("a", i) / 12));
                          	}	
                          
                          	berechneSumme();
                          }
                          
                          function berechneSumme() {
                          	let summe = 0;
                          	for (let i=1; i<=10; i++) {
                          		summe = summe + leseWert("a", i);     // Frage: Runden?!
                          	}
                          	document.rechner["ausgabe"].value = summe;
                          }
                          
                          function leseWert(typ, nr) {
                          	return document.rechner[typ + "_" + i].valueAsNumber || 0;
                          }
                          
                          function schreibeWert(typ, nr, wert) {
                          	document.rechner[typ + "_" + i].value = wert;
                          }
                          

                          Die Funktionen Rechner1 und Rechner2 werden aufgerufen, um vorwärts oder rückwärts zu rechnen. Bei Rechner1 habe ich round weggelassen, durch * 12 können keine Nachkommastellen entstehen.

                          Das Ermitteln eines Feldwertes und das Ersetzen eines NaN Wertes durch 0 ist in leseWert gekapselt. Dadurch musst Du Dich sonst nirgend mehr um NaN kümmern. Die Funktion bekommt als ersten Parameter ein "e" oder "a", und als zweiten Parameter die gewünschte Zeilennummer. Daraus baut sie den Feldnamen zusammen und liest den Wert aus.

                          Das Gegenstück ist schreibeWert, die bekommt typ, nummer und neuen Wert und schreibt ihn als value ins input-Element.

                          Und schließlich noch eine eigenständige Funktion berechneSumme. Die holt sich die Werte aus den a-Feldern und ist damit von den vorigen Berechnungen unabhängig. Entkopplungen dieser Art können das Leben deutlich vereinfachen.

                          Ich speichere jetzt erstmal und schreibe dann noch was zur Verbesserung der Rechnerei.

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                          1. @@Rolf B

                            Das Summenfeld sollte kein oninput haben. Es sollte auch eigentlich kein input Element, sondern ein output Element sein, da soll doch niemand was eingeben können. Wenn es einen Rahmen haben soll, kannst Du das im CSS mit border:1px solid black ändern.

                            Nicht alles, was man tun kann, sollte man tun.

                            Sollte man ein Ausgabefeld genauso aussehen lassen wie ein Eingabefeld? Nein. Unterschiedliche Funktion – unterschiedliches Aussehen.

                            😷 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,

                              der sieht nicht gleich aus. Ich bekomme mit CSS einen Rahmen, der in Chrome identisch zum input-Element aussieht, nicht gebacken. Aber hast ja recht, es sollte sich abheben.

                              Ich bin vielleicht zu sehr von alten Großrechner- und WinForms Anwendungen beeinflusst. Wenn da ein Ausgabefeld ist, erwarte ich, dass es eine visuelle Umrahmung hat.

                              Rolf

                              --
                              sumpsi - posui - obstruxi
                          2. Erstmal wieder SuperDanke.

                            Ich habe es gleich per Copy und Paste rüber geholt. Und sieh da, es funktionierte nicht. Ein Schelm wer da böses denkt. Also musste ich alles Zeile per Zeile durchgehen. Was ja die Lernfähigkeit fördert. So habe ich auch das übergeben in Funktionen kapiert, denke ich jedenfalls. Und habe es gefunden, warum das Einfache kopieren dann doch nicht einfach auch funktioniert hat.

                             
                            function leseWert(typ, nr) {
                            	return document.rechner[typ + "_" + i].valueAsNumber || 0;
                            }
                            
                            function schreibeWert(typ, nr, wert) {
                            	document.rechner[typ + "_" + i].value = wert;
                            }
                            
                            

                            Hihi Aus i sollte wohl die nr werden. Und siehe da, es funktionierte. Jedenfalls vieledank. Also machte ich gleich so weiter. Aber das javascript ist schon eine verflixte Scriptsprache. Und wenn das eine Problem zu Ende ist kommt ein neues daher.

                            So fügte ich ein neues HTML Input Feld ein, mit den Namen neu ein. Und fügte in die Funktion berechneSumme() einfach noch die Zeile ein.

                            function berechneSumme() {
                            	let summe = 0;
                            	for (let i=1; i<=10; i++) {
                            		summe = summe + leseWert("a", i);     // Frage: Runden?!
                            	}
                            
                            	document.rechner["ausgabe"].value = summe;	
                            	// Ein weiteres Feld einlesen und zur ausgabe2 editieren
                            	document.rechner["ausgabe2"].value = summe+document.rechner["neu"].valueAsNumber || 0;;	
                            		
                            }
                            

                            und sie da es funktioniert, aber?

                            Ich schreibe eine oder mehrere Zahlen in eines der LINKEN Input Felder. Die automatische Rechnung beginnt. Alles funktioniert bestens. Auch wenn ich eine Zahl in mein neues INPUT Feld NEU Schreibe wird es addiert.

                            Ich schreibe z.B. in das letzte LINKE INPUT Feld 10 und im rechten 120 in mein neues schreibe ich 5, dann steht im neuen Ausgabefeld 125

                            Alles funktioniert bestens.

                            Doch dann lade ich die Seite erneut:

                            Ich schreibe z.B. in das RECHTE INPUT Feld 1000 und in mein neues schreibe ich 5, dann steht im neuen Ausgabefeld 1001 und im RECHTE INPUT Feld 996

                            Ich weis gar nicht wie ich das erklären soll.

                            1. Eines habe ich noch vergessen:

                              Wenn ich überhaupt nichts an meinem Java Code verändere, und nur das Input Feld

                              <input type="number" id="neu" oninput="Rechner1()"/>

                              einbinde, spielt die Rechnung schon verrückt.

                              Ich habe den Code bestimmt schon 100mal durchgesehen, aber eigentlich dürfte die Variable neu in keinester Weise beachtung finden, tut sie aber irgendwie???????

                              1. Hallo,

                                Wenn ich überhaupt nichts an meinem Java Code verändere, und nur das Input Feld

                                bitte verwechsle Java nicht mit Jacascript.

                                <input type="number" id="neu" oninput="Rechner1()"/>

                                einbinde, spielt die Rechnung schon verrückt.

                                Und was heißt das genau?

                                Ich habe den Code bestimmt schon 100mal durchgesehen, aber eigentlich dürfte die Variable neu in keinester Weise beachtung finden, tut sie aber irgendwie???????

                                Welche Variable neu? Ich sehe da nur eine ID beim HTML-Element und kann dir leider nicht folgen.

                                Live long and pros healthy,
                                 Martin

                                --
                                Versuchungen sollte man nachgeben. Wer weiß, ob sie wiederkommen.
                                1. Ich denke, dachte ID ist eine Varibale in meinem Javascript.

                                  Ich habe das ganze nun bei jsfiddle hinterlegt. Ich hoffe das es funktioniert.

                                  https://jsfiddle.net/5Lmzxa7k/

                                  Da kann man es sehen, was ich meine. Wenn man beim Inputfeld 4 bei A 1000 setzt und dann beim Feld Neu 100, stimmt nichts mehr so richtig.

                                  Edit Rolf B: Link zum Link gemacht (spitze Klammern drumherum)

                                  1. Hallo Therry,

                                    ja, das hast Du richtig erkannt mit dem Test... 🐦flöt

                                    Die Werteveränderung liegt an deiner Runderei. Wenn Du in den A Feldern was einträgst, ist das Gegenstück in den E Feldern nicht unbedingt das exakte Gegenstück dazu.

                                    Auf dem neu-Feld rufst Du bei Änderungen Rechner1() auf. Der rechnet alle E-Werte neu und überschreibt alle A Werte. Deswegen kann sich da vieles verändern.

                                    Ansonsten stimmen die Ergebnisse.

                                    Du kannst das Problem begrenzen, wenn Du auf dem neu-Feld Rechner2() aufrufst, der schiebt die A-Felder in die E-Felder, das macht nichts kaputt. Aber wenn Du 19, 20, 21 in die Felder A1, A2 und A3 einträgst, und dann eine 5 in E4, werden A1 bis A3 auch überschrieben. Das ist wohl unvermeidlich, wenn Du rundest.

                                    Wenn Du nach Eingabe eines Wertes in ein A Feld sicher sein willst, dass da nur ein Vierfaches von 12 steht, musst Du in Rechner2 das Ergebnis des Abrundens gleich wieder mit 12 multiplizieren und in das A Feld zurückschreiben. Aber das ist auf dem input-Event ARG lästig, weil es bei jedem Tastendruck reagiert. Sowas kann man auf dem blur-Event machen, das geworfen wird, wenn ein Feld den Fokus verliert.

                                    Rolf

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

                                      Du kannst das Problem begrenzen, wenn Du auf dem neu-Feld Rechner2() aufrufst, der schiebt die A-Felder in die E-Felder, das macht nichts kaputt. Aber wenn Du 19, 20, 21 in die Felder A1, A2 und A3 einträgst, und dann eine 5 in E4, werden A1 bis A3 auch überschrieben. Das ist wohl unvermeidlich, wenn Du rundest.

                                      Wenn ich das Runden auf 2 Stellen begrenze, funktioniert es!

                                      schreibeWert("e", i, Math.round(((leseWert("a", i) / 12))*100)/100);
                                      

                                      Wenn Du nach Eingabe eines Wertes in ein A Feld sicher sein willst, dass da nur ein Vierfaches von 12 steht, musst Du in Rechner2 das Ergebnis des Abrundens gleich wieder mit 12 multiplizieren und in das A Feld zurückschreiben

                                      function Rechner2() {
                                      for (let i=1; i<=10; i++) {
                                      	let runden = Math.round(leseWert("a", i)/12);
                                      	schreibeWert("e", i, runden);
                                      	schreibeWert("a", i, runden*12);
                                      	}	
                                      	berechneSumme();
                                      }
                                      

                                      Meinst du in diese Richtung?

                                      1. Hallo Therry,

                                        Wenn ich das Runden auf 2 Stellen begrenze, funktioniert es!

                                        Ja ok, weil Du das Ergebnis der Multiplikation mit 12 ebenfalls rundest. Wenn zwei Nachkommastellen in den e-Feldern für Dich ok sind, ist das die beste Lösung. Eine Nachkommastelle ist zu wenig (ein Zehntel Auflösung ist zu grob wenn Du mit zwölfteln hantierst)

                                        Andernfalls - ja, genau so hatte ich das gedacht.

                                        Was für Dich jetzt das Beste ist, musst Du wissen.

                                        Rolf

                                        --
                                        sumpsi - posui - obstruxi
                                        1. Aber beim sofortigen wiederbeschreiben, gibt es ein Problem

                                          https://jsfiddle.net/dscbfeyk/ (ist irgenwie lustig)

                                          ich denke das liegt daran, das die Rechnung sofort ausgeführt wird und ich nicht die Zeit habe eine Zahl reinzuschrieben die grösser ist als 9. Ich nehme eine Zahl z.b. 120 kopiere sie und setze sie dann mit ctrl v ins Formular, dann geht es 😀😀. Aber wer ist den so schnell

                                          Therry

                                          1. Hallo Therry,

                                            wie ich vor 3 Tagen schrub:

                                            Aber das ist auf dem input-Event ARG lästig, weil es bei jedem Tastendruck reagiert. Sowas kann man auf dem blur-Event machen, das geworfen wird, wenn ein Feld den Fokus verliert.

                                            Einfachste Implementierung wäre

                                            A <input type="number" id="a_1" oninput="Rechner2()" onblur="Rechner1()"/>
                                            

                                            Der Aufruf von Rechner1 bei onblur (=Eingabefeld verliert den Focus) rechnet nochmal alle A Felder basierend auf den E Feldern.

                                            Rolf

                                            --
                                            sumpsi - posui - obstruxi
                        3. Hallo Therry,

                          eine kleine Anmerkung: Deine input Elemente brauchen Labels, sonst ist die Seite nicht benutzbar. Für's Basteln ist es egal, wenn Du was publizierst, nicht.

                          Die Frage, wie man die Rechnung ordentlich anstößt, hatten wir neulich noch in einem anderen Thread. Man kann entweder an jedem input-Feld ein oninput Attribut notieren, oder man tut es am Form, und verwendet ein Feature des Browsers, das sich Event Bubbling nennt.

                          Die HTML Elemente, die Du verwendest, sind hierarchisch geordnet. Der Body enthält das Form, das Form die Inputs, und so weiter. Die Datenstruktur, die das abbildet, ist ein Baum - der Dokumentbaum. Das kannst Du mit einem Stammbaum vergleichen, der die Abkömmlinge von irgendeinem König zeigst. Der Body ist der König, das Form ein Kind und das input ein Enkel.

                          Wenn ein Ereignis wie input ausgelöst wird, dann passiert das zuerst auf dem Element, für das es gilt. Danach wird es in der Elternkette bis ganz oben durchgereicht und dort ebenfalls ausgelöst. Ein Tastendruck in einem input-Feld löst also erstmal ein input-Event auf dem Eingabefeld aus, dann eins auf dem Form, dann eins auf dem Body (oder an noch mehr Stellen, wenn dein HTML umfangreicher ist). Wenn Du es genau wissen willst: hier steht mehr, als Du jemals wissen möchtest 😉.

                          Ein zentraler Rechner könnte also auf dem Form registriert sein und alle inputs einsammeln. Um zu wissen, was er damit tun muss, braucht er natürlich Informationen. Dafür gibt es das event-Objekt, da steckt eine Eigenschaft target drin, die das Element enthält, für das das Ereignis ausgelöst wurde. Das event-Objekt bekommst Du auf zwei mögliche Arten:

                          Wenn Du mit oninput arbeitest, musst Du es als Parameter übergeben. Das ist die "klassische" Version, und der Name "event" ist an dieser Stelle festgelegt.

                          <form id="rechner" oninput="berechne(event)">
                          

                          Alternativ kannst Du die Registrierung des input Handlers im JavaScript durchführen. Dafür lässt Du oninput im HTML weg und schreibst in deinem Script:

                          document.getElementById("rechner").addEventListener("input", berechne);
                          

                          Wichtig ist dabei nur, dass dieses Script erst ausgeführt wird, wenn das form schon angelegt ist (also am Ende des body steht), sonst findet getElementById das Form nicht.

                          Egal, wie Du es machst, deine Berechnungsfunktion wird dann für alle Eingaben in allen input-Feldern des Form aufgerufen. Sie muss also als erstes schauen, was das event.target war, und dementsprechend weitermachen.

                          function berechne(event) {
                             let wert = event.target.valueAsNumber || 0;
                             let id = event.target.id;
                             if (id.startsWith("e_")) {
                                schreibeWert("a", id.substr(2), wert * 12;
                             }
                             else if (id.startsWith("a_")) {
                                schreibeWert("e", id.substr(2), Math.round(wert / 12);
                             }
                             berechneSumme();
                          }
                          

                          Rechner1 und Rechner2 entfallen dann.

                          id.startsWith(...) liefert true, wenn die ID mit dem String beginnt, der in den Klammern steht. id.substr(2) liefert den Teil der ID ab Index 2, also der 3. Stelle.

                          Rolf

                          --
                          sumpsi - posui - obstruxi
                          1. @@Rolf B

                            eine kleine Anmerkung: Deine input Elemente brauchen Labels, sonst ist die Seite nicht benutzbar. Für's Basteln ist es egal, wenn Du was publizierst, nicht.

                            Das würd ich so nicht sagen. Was Hänschen nicht lernt, lernt Hans nimmermehr. Also auch beim Basteln richtig machen.

                            Der Body ist der König

                            Das html-Element ist Queen Mum.

                            😷 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!“
                  2. @@Rolf B

                    for (let i=1; i<=10; i++) {
                       document.getElementById(???).value = document.rechner.***.valueAsNumber * 12;
                    }
                    

                    Beim ersten Fragezeichen ist es einfach. Da wird eine Zeichenkette gebraucht, die aus "a_" und der Nummer besteht. Dafür kannst Du den + Operator verwenden, der addiert Zahlen oder hängt Zeichenketten aneinander, je nach dem, was Du ihm gibst.

                    Eben. Und das macht die Sache unnötig kompliziert. Den +-Operator für Strings kann man wunderbar vermeiden: Nicht "a_"+i, sondern `a_${i}` verwenden. Besser lesbarer Code.

                    (Ich gehe nicht davon aus, dass Therry eine Spezialanwendung für eine Firma schreibt, die noch Browser aus dem letzten Jahrtausend einsetzt.)

                    Beim zweiten Fragezeichen musst Du deine Arbeitsweise ändern.

                    Beim zweiten der drei ????

                    Ach so du meinst dieses – ähm – Fragezeichen: ***. 🤣

                    Auch dort dann document.rechner[`e_${i}`].

                    😷 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,

                      danke für den Hinweis auf Template-Strings.

                      Die Historie des Wiki-Artikels dazu offenbart zwar, dass ich da maßgeblich aktiv war, aber ich muss zugeben, dass sich mir die Stringtheorie von JavaScript nicht recht eingeprägt hat...

                      Rolf

                      --
                      sumpsi - posui - obstruxi