matze511: Fehler in der sel.onchange

Hallo liebe Profis,

ich hab einen Fehler in der sel.onchange und komme einfach nicht weiter😒 könnte da mal bitte jemand drüber schauen? Ohne die switch funtioniert die Berechnung wunderbar, nur wollte ich verschiedene Berechnung nach Auswahl im dropdownmenue machen und da steh ich auf der stelle. Das ist das Menue:

 <select name="wasistgegeben" value="wasistgegeben" id="wasistgegeben"> 
            <option value="Bitte wählen" selected>Bitte wählen</option>
            <option value="traufhöVordachNeigung">Grdmaß-Traufhö-Vordach-Neigung</option>
            <option value="firsthöTraufhöVordach">Grdmaß-Firsthö-Traufhö-Vordach</option> 
            <option value="vordachNeigungOKFußpf">Grdmaß-Vordach-Neigung-OKFußpf</option>
         </select>

und das dazugehörige JavaScript:

document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('wasistgegeben').addEventListener('change', function () {
    const config = {
      traufhöVordachNeigung: ["#grundmaß", "#traufhöhe", "#dachüberstand", "#dachneigung"],
      firsthöTraufhöVordach: ["#grundmaß", "#firsthöhe", "#traufhöhe", "#dachüberstand"],
      vordachNeigungOKFußpf: ["#grundmaß", "#okFußpfette", "#dachüberstand", "#dachneigung"],
      "--": [] // Default case
    };

    // Disable all fields initially
    const disableAll = ["#grundmaß", "#traufhöhe", "#firsthöhe", "#dachüberstand", "#dachneigung", "#okFußpfette", "#okFirstpfette"];
    disableAll.forEach(id => document.querySelector(id).setAttribute('disabled', 'disabled'));

    // Enable fields based on the selected value
    const selectedOption = this.value; // Get selected value
    if (config[selectedOption]) {
      config[selectedOption].forEach(id => document.querySelector(id).removeAttribute('disabled'));
    }
  });
});

das Funktioniert alles soweit gut, nur die Berechnungen wollen nicht starten nach betätigen des Button.


        function getFloatValue(id) {
            const element = document.getElementById(id);
            if (element) {
                const value = element.value.replace(",", ".");
                const floatValue = parseFloat(value);
                if (isNaN(floatValue)) {
                    console.error("Ungültiger Wert für " + id + ": " + value);
                    return 0;  // Rückgabe von 0, wenn der Wert ungültig ist
                }
                return floatValue;
            } else {
                console.error("Element nicht gefunden: " + id);
                return 0;
            }
}

function berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung) {
    return (sparrenhoehe - klauentiefe) / Math.cos(dachneigung);
}



function BerechnungderSparrenmaße () {
    console.log("Berechnung läuft...");
let sel = document.getElementById("Werte berechnen"); // Beispiel
    console.log(sel.value);
sel.onchange = function () {
    console.log("Berechnung gestartet");
    
    
    let grundmass = getFloatValue("grundmaß");
    let dachneigung = getFloatValue("dachneigung") / 180 * Math.PI;
    let dachueberstand = getFloatValue("dachüberstand");
    let traufhoehe = getFloatValue("traufhöhe");
    let fusspfettenruecksprung = getFloatValue("fußpfettenrücksprung");
    let raumhoeheRohbau = getFloatValue("raumhöheRohbau");
    let sparrenhoehe = getFloatValue("sparrenhöhe");
    let klauentiefe = getFloatValue("klauentiefe");
    let firstpfettenbreite = getFloatValue("firstpfettenbreite");
    let firsthoehe = getFloatValue("firsthöhe");
    let okFusspfette = getFloatValue("okFußpfette");

    console.log("Gewählter Wert:", this.value); // Debug-Ausgabe
    switch (this.value) {
        case "traufhöVordachNeigung":
        console.log("Fall: traufhöVordachNeigung");
            let firsthoehe = (grundmass + dachueberstand) * Math.tan(dachneigung) + traufhoehe;
            let lotrechtesObholz = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung);
            let okFusspfette = ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigung)) - lotrechtesObholz + traufhoehe;
            let okFirstpfette = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigung) - lotrechtesObholz + traufhoehe;

            document.getElementById("firsthöhe").value = firsthoehe.toPrecision(4);
            document.getElementById("okFußpfette").value = okFusspfette.toPrecision(3);
            document.getElementById("okFirstpfette").value = okFirstpfette.toPrecision(4);
            break;

        case "firsthöTraufhöVordach":
        console.log("Fall: firsthöTraufhöVordach");
            let dachneigung = Math.atan((firsthoehe - traufhoehe) / (grundmass + dachueberstand));
            let lotrechtesObholz2 = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung);
            let okFusspfette2 = ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigung2)) - lotrechtesObholz2 + traufhoehe;
            let okFirstpfette2 = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigung2) - lotrechtesObholz2 + traufhoehe;

            document.getElementById("dachneigung").value = (dachneigung2 * 180 / Math.PI).toPrecision(4);
            document.getElementById("okFußpfette").value = okFusspfette2.toPrecision(4);
            document.getElementById("okFirstpfette").value = okFirstpfette2.toPrecision(4);
            break;

        case "vordachNeigungOKFußpf":
        console.log("Fall: vordachNeigungOKFußpf");
            let okFusspfette3 = getFloatValue("okFußpfette");
            let lotrechtesObholz3 = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung);
            let firsthoehe3 = (grundmass - fusspfettenruecksprung) * Math.tan(dachneigung) + okFusspfette3 + lotrechtesObholz3;
            let traufhoehe3 = okFusspfette3 + lotrechtesObholz3 - ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigung));
            let okFirstpfette3 = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigung) - lotrechtesObholz3 + traufhoehe3;

            document.getElementById("firsthöhe").value = firsthoehe3.toPrecision(4);
            document.getElementById("traufhöhe").value = traufhoehe3.toPrecision(4);
            document.getElementById("okFirstpfette").value = okFirstpfette3.toPrecision(4);
            break;

        default:
            console.error("Ungültige Auswahl");
    }
}
}			

könnte mir da bitte jemand helfen?

LG matze

  1. ach so ich vergaß, die Konsole ergab das es bis "Berechnung läuft" geht und dann wird als Fehler angezeigt "Uncaught TypeError: Cannot read properties of null (reading 'value') at BerechnungderSparrenmaße at HTMLInputElement.onclick

    LG matze

    1. Hi,

      ach so ich vergaß, die Konsole ergab das es bis "Berechnung läuft" geht und dann wird als Fehler angezeigt "Uncaught TypeError: Cannot read properties of null (reading 'value') at BerechnungderSparrenmaße at HTMLInputElement.onclick

          let sel = document.getElementById("Werte berechnen"); // Beispiel
          console.log(sel.value);
      

      Du hast kein Element mit der ID "Werte berechnen". (Zumindest nicht im gezeigten Code)

      Abgesehen davon: Leerzeichen sind m.W. in IDs immer noch verboten.

      cu,
      Andreas a/k/a MudGuard

      1. Erstmal rechtherzlichen dank! Jetzt gibt es in der Konsole zumindest keinen Fehler, es läuft nun bis "traufhöVordachNeigung" aber die Berechnung aus dem ersten "case" geben keine werte zurück. Woran kann das nun liegen?

        lg matze

        1. Hallo matze511,

          keine weiteren FM in der Konsole?

          Hast Du auf den console.log, der "Fall: traufhöVordachNeigung" ausgibt, mal einen Breakpoint gesetzt und bist von da aus Einzelschrittweise weitergegangen?

          Breakpoints setzt man in der Quellcode-Ansicht ("Debugger" im Firefox) indem man auf die Zeilennummer der entsprechenden Stelle klickt. Über dem rechten Teilfenster des Debuggers sind Buttons für "Step over" (über Funktionsaufrufe weg), "Step out" (bis zum Rücksprung aus der aktuellen Funktion) "Step into" (genau eine Anweisung ausführen, egal ob in eine Funktion hinein oder ein anderes Statement). Da kannst Du Dir dann auch Variableninhalte anzeigen und sehen, wo genau er herläuft.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo Rolf B. also wenn ich das jetzt richtig gemacht habe, wie du es erklärt hast überspringt es die Komplette Berechnung. Der letzte Schritt hinein ist "sel.onchange = function()" und dann überspringt er alles bis zur letzten geschweiften Klammer.

            1. jetzt funktioniert es! so sieht das JavaScript jetzt aus:

              Quelltext hierdocument.addEventListener('DOMContentLoaded', function () {
                const selectElement = document.getElementById('wasistgegeben');
                const config = {
                  traufhöVordachNeigung: ["#grundmaß", "#traufhoehe", "#dachueberstand", "#dachneigung"],
                  firsthöTraufhöVordach: ["#grundmaß", "#firsthoehe", "#traufhoehe", "#dachueberstand"],
                  vordachNeigungOKFußpf: ["#grundmaß", "#okFußpfette", "#dachueberstand", "#dachneigung"],
                  "--": [] // Default case
                };
              
                selectElement.addEventListener('change', function () {
                  // Disable all fields initially
                  const allFields = ["#grundmaß", "#traufhoehe", "#firsthoehe", "#dachueberstand", "#dachneigung", "#okFußpfette", "#okFirstpfette"];
                  allFields.forEach(id => document.querySelector(id).setAttribute('disabled', 'disabled'));
              
                  // Enable relevant fields
                  const selectedOption = this.value;
                  if (config[selectedOption]) {
                    config[selectedOption].forEach(id => document.querySelector(id).removeAttribute('disabled'));
                  }
                });
              
                document.querySelector('input[type="button"]').addEventListener('click', function () {
                  BerechnungderSparrenmaße(selectElement.value);
                });
              });
              
              
                      function getFloatValue(id) {
                          const element = document.getElementById(id);
                          if (element) {
                              const value = element.value.replace(",", ".");
                              const floatValue = parseFloat(value);
                              if (isNaN(floatValue)) {
                                  console.error("Ungültiger Wert für " + id + ": " + value);
                                  return 0;  // Rückgabe von 0, wenn der Wert ungültig ist
                              }
                              return floatValue;
                          } else {
                              console.error("Element nicht gefunden: " + id);
                              return 0;
                          }
              }
              
              function berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung) {
                  return (sparrenhoehe - klauentiefe) / Math.cos(dachneigung);
              }
              
              
              
              function BerechnungderSparrenmaße(selectedValue) {
                console.log("Berechnung gestartet für:", selectedValue);
              
                // Gemeinsame Variablen einlesen
                const grundmass = getFloatValue("grundmaß");
                const dachneigung = getFloatValue("dachneigung") / 180 * Math.PI;
                const dachueberstand = getFloatValue("dachueberstand");
                const traufhoehe = getFloatValue("traufhoehe");
                const fusspfettenruecksprung = getFloatValue("fußpfettenruecksprung");
                const raumhoeheRohbau = getFloatValue("raumhoeheRohbau");
                const sparrenhoehe = getFloatValue("sparrenhoehe");
                const klauentiefe = getFloatValue("klauentiefe");
                const firstpfettenbreite = getFloatValue("firstpfettenbreite");
                const firsthoehe = getFloatValue("firsthoehe");
                const okFusspfette = getFloatValue("okFußpfette");
              
                // Berechnungen je nach Auswahl
                switch (selectedValue) {
                  case "traufhöVordachNeigung":
                    const firsthoeheCalc = (grundmass + dachueberstand) * Math.tan(dachneigung) + traufhoehe;
                    const lotrechtesObholz = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung);
                    const okFusspfetteCalc = ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigung)) - lotrechtesObholz + traufhoehe;
                    const okFirstpfetteCalc = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigung) - lotrechtesObholz + traufhoehe;
              
                    document.getElementById("firsthoehe").value = firsthoeheCalc.toFixed(3);
                    document.getElementById("okFußpfette").value = okFusspfetteCalc.toFixed(3);
                    document.getElementById("okFirstpfette").value = okFirstpfetteCalc.toFixed(3);
                    break;
              
                  case "firsthöTraufhöVordach":
                    const dachneigungCalc = Math.atan((firsthoehe - traufhoehe) / (grundmass + dachueberstand));
                    const lotrechtesObholz2 = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigungCalc);
                    const okFusspfette2 = ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigungCalc)) - lotrechtesObholz2 + traufhoehe;
                    const okFirstpfette2 = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigungCalc) - lotrechtesObholz2 + traufhoehe;
              
                    document.getElementById("dachneigung").value = (dachneigungCalc * 180 / Math.PI).toFixed(2);
                    document.getElementById("okFußpfette").value = okFusspfette2.toFixed(3);
                    document.getElementById("okFirstpfette").value = okFirstpfette2.toFixed(3);
                    break;
              
                  // Weitere Fälle können analog hinzugefügt werden
                  default:
                    console.warn("Keine Berechnung für diesen Fall implementiert.");
                }
              }
              
              1. Hallo matze511,

                okay, diese sel.onchange Zuweisung hatte mich zwar schon gewundert, aber dann hatte ich sie nicht mehr beachtet.

                Wenn Du die Berechnungsfunktion einem Eventlistener zuweist, dann läuft sie auch nur, wenn das Event eintritt. Dein neuer Code tut das nicht mehr.

                Ich hätte aber gedacht, dass Du in deinem alten Code irgendwie in den Eventhandler reingekommen bist, weil Du ja schriebst: "Jetzt gibt es in der Konsole zumindest keinen Fehler, es läuft nun bis "traufhöVordachNeigung" und das ist ja in dem onchange-Handler drin.

                Dass er im alten Code einfach über die Funktion wegspringt, ist demnach richtig gewesen, denn er weist ja nur das Funktionsobjekt zu. Wenn Du an der Stelle, wo ich das gesagt habe, einen Breakpoint gesetzt hättest, dann hätte er bei Auftreten des change-Events auf dem sel-Objekt (von dem wir nicht wissen, was es ist) dort angehalten.

                Naja, jetzt hast Du es umgebaut, die Debatte ist müßig und ich geh jetzt an der Matratze horchen.

                Rolf

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

                  eine Frage hätte ich da mal noch. Wie bekomme ich es hin, dass sofort nach Eingabe gerechnet wird? Ein Beispiel hab ich hier im Wiki gefunden Berechnung des Sundensatzes. Das müsste ja mit diesem Codeschnipsel zusammenhängen aber bei mir möchte es nicht klappen. document.getElementById("myForm") .addEventListener("input", rechne);

                  LG Matze

                  1. Hallo

                    eine Frage hätte ich da mal noch. Wie bekomme ich es hin, dass sofort nach Eingabe gerechnet wird? Ein Beispiel hab ich hier im Wiki gefunden Berechnung des Sundensatzes. Das müsste ja mit diesem Codeschnipsel zusammenhängen aber bei mir möchte es nicht klappen.

                    document.getElementById("myForm")
                    		.addEventListener("input", rechne);
                    

                    Der ID-Bezeichner myForm lässt mich vermuten, dass damit ein Formular benannt ist. Ich bezweifle, dass ein solches auf das Event input hört. Ein Eingabefeld (input) tut das hingegen.

                    Tschö, Auge

                    --
                    „Habe ich mir das nur eingebildet, oder kann der kleine Hund wirklich sprechen?“ fragte Schnapper. „Er behauptet, nicht dazu imstande zu sein“ erwiderte Victor. Schnapper zögerte (…) „Nun …“ sagte er schließlich, „ich schätze, er muss es am besten wissen.“ Terry Prattchett, Voll im Bilde
                    1. Hallo Auge,

                      Ich bezweifle, dass ein (Form) auf das Event input hört.

                      Hören eh nicht. Du meinst erzeugen?

                      MDN hat es scheinbar entfernt, aber unser Wiki verrät es noch: input blubbert. Ein input Handler auf dem Form sollte also alle input Events seiner Kinder mitbekommen, solange nicht tiefer ein weiterer Handler sitzt, der das verhindert.

                      Rolf

                      --
                      sumpsi - posui - obstruxi
                      1. Ich danke Euch! Es sieht nun so aus:

                        document.addEventListener('DOMContentLoaded', function () {
                          const selectElement = document.getElementById('wasistgegeben');
                          const config = {
                            traufhöVordachNeigung: ["#grundmaß", "#traufhoehe", "#dachueberstand", "#dachneigung"],
                            firsthöTraufhöVordach: ["#grundmaß", "#firsthoehe", "#traufhoehe", "#dachueberstand"],
                            vordachNeigungOKFußpf: ["#grundmaß", "#okFußpfette", "#dachueberstand", "#dachneigung"],
                            "--": [] // Default case
                          };
                        
                          // Aktivieren/Deaktivieren von Feldern basierend auf Auswahl
                          selectElement.addEventListener('change', function () {
                            const allFields = ["#grundmaß", "#traufhoehe", "#firsthoehe", "#dachueberstand", "#dachneigung", "#okFußpfette", "#okFirstpfette"];
                            allFields.forEach(id => document.querySelector(id).setAttribute('disabled', 'disabled'));
                        
                            const selectedOption = this.value;
                            if (config[selectedOption]) {
                              config[selectedOption].forEach(id => document.querySelector(id).removeAttribute('disabled'));
                            }
                          });
                        
                          // Berechnung auslösen bei Eingabe
                          const form = document.getElementById("myForm");
                          form.addEventListener("input", function () {
                            const selectedValue = selectElement.value;
                            BerechnungderSparrenmaße(selectedValue);
                          });
                        });
                        
                        // Helferfunktion: Float-Wert einlesen
                        function getFloatValue(id) {
                          const element = document.getElementById(id);
                          if (element) {
                            const value = element.value.replace(",", ".");
                            const floatValue = parseFloat(value);
                            if (isNaN(floatValue)) {
                              console.error("Ungültiger Wert für " + id + ": " + value);
                              return 0; // Rückgabe von 0 bei ungültigem Wert
                            }
                            return floatValue;
                          } else {
                            console.error("Element nicht gefunden: " + id);
                            return 0;
                          }
                        }
                        
                        // Berechnung: Lotrechtes Obholz
                        function berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung) {
                          return (sparrenhoehe - klauentiefe) / Math.cos(dachneigung);
                        }
                        
                        // Funktion zur Berechnung der Sparrenmaße
                        function BerechnungderSparrenmaße(selectedValue) {
                          if (!selectedValue) return;
                        
                          console.log("Berechnung gestartet für:", selectedValue);
                        
                          // Werte einlesen
                          const grundmass = getFloatValue("grundmaß");
                          const dachneigung = getFloatValue("dachneigung") / 180 * Math.PI;
                          const dachueberstand = getFloatValue("dachueberstand");
                          const traufhoehe = getFloatValue("traufhoehe");
                          const fusspfettenruecksprung = getFloatValue("fußpfettenruecksprung");
                          const sparrenhoehe = getFloatValue("sparrenhoehe");
                          const klauentiefe = getFloatValue("klauentiefe");
                          const firstpfettenbreite = getFloatValue("firstpfettenbreite");
                          const firsthoehe = getFloatValue("firsthoehe");
                          const okFusspfette = getFloatValue("okFußpfette");
                        
                          switch (selectedValue) {
                            case "traufhöVordachNeigung":
                              const firsthoeheCalc = (grundmass + dachueberstand) * Math.tan(dachneigung) + traufhoehe;
                              const lotrechtesObholz = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung);
                              const okFusspfetteCalc = ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigung)) - lotrechtesObholz + traufhoehe;
                              const okFirstpfetteCalc = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigung) - lotrechtesObholz + traufhoehe;
                        
                              updateFieldValue("firsthoehe", firsthoeheCalc);
                              updateFieldValue("okFußpfette", okFusspfetteCalc);
                              updateFieldValue("okFirstpfette", okFirstpfetteCalc);
                              break;
                        
                            case "firsthöTraufhöVordach":
                              const dachneigungCalc = Math.atan((firsthoehe - traufhoehe) / (grundmass + dachueberstand));
                              const lotrechtesObholz2 = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigungCalc);
                              const okFusspfette2 = ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigungCalc)) - lotrechtesObholz2 + traufhoehe;
                              const okFirstpfette2 = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigungCalc) - lotrechtesObholz2 + traufhoehe;
                        
                              updateFieldValue("dachneigung", dachneigungCalc * 180 / Math.PI);
                              updateFieldValue("okFußpfette", okFusspfette2);
                              updateFieldValue("okFirstpfette", okFirstpfette2);
                              break;
                        
                            case "vordachNeigungOKFußpf":
                              const lotrechtesObholz3 = berechneLotrechtesObholz(sparrenhoehe, klauentiefe, dachneigung);
                              const firsthoehe3 = (grundmass - fusspfettenruecksprung) * Math.tan(dachneigung) + okFusspfette + lotrechtesObholz3;
                              const traufhoehe3 = okFusspfette + lotrechtesObholz3 - ((dachueberstand + fusspfettenruecksprung) * Math.tan(dachneigung));
                              const okFirstpfette3 = (grundmass - 0.5 * firstpfettenbreite + dachueberstand) * Math.tan(dachneigung) - lotrechtesObholz3 + traufhoehe3;
                        
                              updateFieldValue("firsthoehe", firsthoehe3);
                              updateFieldValue("traufhoehe", traufhoehe3);
                              updateFieldValue("okFirstpfette", okFirstpfette3);
                              break;
                        
                            default:
                              alert("Keine Berechnung für diesen Fall implementiert.");
                          }
                        }
                        
                        // Helferfunktion: Werte sicher aktualisieren
                        function updateFieldValue(id, value) {
                          const field = document.getElementById(id);
                          if (field) {
                            const newValue = value.toFixed(3).replace(".", ",");
                            if (field.value !== newValue) {
                              field.value = newValue;
                            }
                          }
                        }