J.Borchert: Script rechnet nicht

Hallo Forum,
ich möchte gern nach zweifacher Auswahl, das der richtige Preis erscheint:

  
<script type="text/javascript">  
function Preis()   {  
size = document.Pizza.Size1.value;  
name = document.Pizza.Sorte1.value;  
switch (size) {  
  case "18cm":  
    switch (name) {  
            case "Salami":  
                 document.Pizza.Preis1.value = '2.70';  
                 break;  
            case "Tuna":  
                 document.Pizza.Preis1.value = '3.50';  
                 break;  
            case "Hawaii":  
                 document.Pizza.Preis1.value = '3.55';  
                 break;  
                  }  
    break;  
  case "28cm":  
    switch (name) {  
            case "Salami":  
                 document.Pizza.Preis1.value = 5.40;  
                 break;  
            case "Tuna":  
                 document.Pizza.Preis1.value = 6.80;  
                 break;  
            case "Hawaii":  
                 document.Pizza.Preis1.value = 6.88;  
                 break;  
                  }  
    break;  
  default:  
    document.Pizza.Preis1.value = 0;  
    break;  
}  
                  }  
</script>  

Das funktioniert ohne Fehlermeldung, aber auch ohne Erfolg. In Preis1 tut sich nix :-(
Das Formular:

  
<form name="Pizza">  
  <table width="100%">  
    <tr><td width="25%"><select name="Sorte1" size=1 onChange="Preis();">  
                          <option>Salami<option>Tuna<option>Hawaii</select>  
        </td>  
        <td width="25%"> <select name="Size1" size=1 onChange="Preis();">  
                          <option>18cm<option>28cm</select>  
        </td>  
        <td><input name="Preis1" size=10 value="0" readonly></td>  
        <td><input name="Anz1" size=10 value="" onChange="Preis();"></td>  
    </tr>  
  </table>  
</form>  

Bitte helft mir auf die Sprünge...
mfG ürgen

  1. Hallo,

    ich möchte gern nach zweifacher Auswahl, das der richtige Preis erscheint:

    <script type="text/javascript">

    function Preis()   {
    size = document.Pizza.Size1.value;
    name = document.Pizza.Sorte1.value;

      
    hier fallen zwei Dinge unangenehm auf:  
    Erstens sind die Variablen size und name, die du hier verwendest, global. Das ist nicht schön. Mit dem Keyword var vorangestellt deklarierst du sie als lokale Variablen.  
    Zweitens bin ich nicht sicher, ob der gewählte Bezeichner 'name' hier nicht vielleicht mit der gleichnamigen Eigenschaft diverser HTML-Elementobjekte kollidiert (z.B. window.name). Ich würde dir auf jeden Fall raten, einen anderen Bezeichner zu nehmen.  
      
    Zum restlichen Code fallen mir nur noch ein paar kosmetische Dinge auf. Zum Beispiel setzt du die Preise bei der 18cm-Pizza als Strings - das ist korrekt, weil die value-Eigenschaft der inputs sowieso ein String ist. Bei der 28cm-Pizza setzt du sie aber als Zahlenwert und überlässt es Javascript, sie automatisch in Strings umzuwandeln. Dabei wird 5.40 natürlich als 5.4 angezeigt.  
      
    Im HTML-Teil gefällt mir nicht, dass die Attributnamen teils in einem Mix aus Groß- und Kleinschreibung und die Attributwerte teilweise ohne Anführungszeichen notiert sind. Beides ist in HTML erlaubt (in XHTML nicht), aber trotzdem wird empfohlen, Attributnamen konsequent kleinzuschreiben, und Attributwerte immer in Anführungszeichen zu setzen, auch da, wo es nicht unbedingt notwendig ist.  
      
    So long,  
     Martin  
    
    -- 
    Lache, und die Welt wird mit dir lachen.  
    Schnarche, und du schläfst allein.  
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    
    1. Danke Martin für deine Tipps, ich habe sie umgesetzt. Dennoch funktioniert das Script nicht.
      Hier der Code:

        
      <script type="text/javascript">  
      function Preis()   {  
      si = document.Pizza.Size1.value;  
      na = document.Pizza.Sorte1.value;  
      switch (si) {  
        case "18cm":  
          switch (na) {  
                  case "Salami":  
                       document.Pizza.Preis1.value = '2.70';  
                       break;  
                  case "Tuna":  
                       document.Pizza.Preis1.value = '3.50';  
                       break;  
                  case "Hawaii":  
                       document.Pizza.Preis1.value = '3.55';  
                       break;  
                        }  
          break;  
        case "28cm":  
          switch (na) {  
                  case "Salami":  
                       document.Pizza.Preis1.value = '5.40';  
                       break;  
                  case "Tuna":  
                       document.Pizza.Preis1.value = '6.80';  
                       break;  
                  case "Hawaii":  
                       document.Pizza.Preis1.value = '6.88';  
                       break;  
                        }  
          break;  
        default:  
          document.Pizza.Preis1.value = 0;  
          break;  
      }  
                        }  
      </script>  
      
      

      Hat noch jemand einen Rat?
      mfg Jürgen

      1. Hallo,

        Danke Martin für deine Tipps, ich habe sie umgesetzt. Dennoch funktioniert das Script nicht.

        dann solltest du anfangen, sinnvoll zu debuggen.

        Das heißt: Mach Testausgaben von Variableninhalten an strategisch wichtigen Stellen und kontrolliere, ob das herauskommt, was du erwartest. Wenn nicht, gehe in der Verarbeitungskette weiter zurück und finde den Punkt, an dem die Ungereimtheiten anfangen. Das ist langweilig bzw. manchmal auch langwierig, aber ein elementarer Prozess beim Programmieren.

        Testausgaben kannst du übrigens leicht mit alert() machen; fast genauso einfach, aber schöner (weil ohne Programmunterbrechung) geht es durch das Schreiben in ein zusätzliches input- oder textarea-Element.

        Eine andere Strategie der Fehlersuche ist, den Code schrittweise zu vereinfachen oder zu reduzieren (z.B. geschicktes Weglassen von Anweisungen oder Ersetzen von Variablenwerten durch Konstanten), bis man ein nachvollziehbares Verhalten bekommt.

        So long,
         Martin

        --
        Finanztipp:
        Leihen Sie sich Geld von einem Pessimisten.
        Er rechnet sowieso nicht damit, dass er es zurückbekommt.
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. Moin!

          dann solltest du anfangen, sinnvoll zu debuggen.

          Testausgaben kannst du übrigens leicht mit alert() machen; fast genauso einfach, aber schöner (weil ohne Programmunterbrechung) geht es durch das Schreiben in ein zusätzliches input- oder textarea-Element.

          Mit Firebug (und vermutlich auch allen anderen Debugger-Extensions in anderen Browsern als dem Firefox) kann man auch mit console.log() auf der Konsole loggen. Sogar einzelne Variablen komplett, deren Struktur (sofern vorhanden) dort dann durchsuchbar ist.

          - Sven Rautenberg

          1. Tach!

            Mit Firebug (und vermutlich auch allen anderen Debugger-Extensions in anderen Browsern als dem Firefox) kann man auch mit console.log() auf der Konsole loggen.

            Noch besser ist allerdings, "richtiges" Debugging zu machen, indem man einen Breakpoint auf die erste Zeile in der Funktion setzt, und dann schrittweise durch das Programm läuft. Die Inhalte der beteiligten Variablen etc. sieht man bereits, wenn man die Maus über den jeweiligen Delinquenten positioniert.

            dedlfix.

            1. Habe den Fall gelöst.

                
              function Preis () {  
                  var se = document.Pizza.Sorte1.value;  
                  var si = document.Pizza.Groesse1.value;  
                  if (se == "Salami" && si == "18cm") { ep = 2.70; }  
                  if (se == "Salami" && si == "28cm") { ep = 5.40; }  
                  if (se == "Tuna" && si == "18cm") { ep = 3.50; }  
                  if (se == "Tuna" && si == "28cm") { ep = 6.80; }  
                  if (se == "Hawaii" && si == "18cm") { ep = 3.55; }  
                  if (se == "Hawaii" && si == "28cm") { ep = 6.88; }  
                  document.Pizza.Einzelpreis1.value = ep.toFixed(2);  
                               }  
              
              

              Dazu muß doch im Formular das <select> oder besser <option> einen value haben:

                
              <select name="Groesse1" size=1 onChange="Preis();">  
                              <option value="18cm">18cm  
                              <option value="28cm">28cm  
                          </select>  
              
              

              Danach hat alles funktioniert. Danke für Eure Anregungen.

          2. Debuggen ist gut. Habe allerdings so gut wie noch nie mit Java zu tun gehabt, eher mit anderen Programmiersprachen...

            Ich wollte den Aufwand auch nicht so hoch haben, wollte einfach nur ein kleines Script entwerfen, daß es so komplex wird war nicht geplant.

            Ich habe den Code also auf die Array-Variante umgestellt. Es fällt mir aber sofort auf, daß die price sel size wieder Martin zuwieder laufen ;-)

            Also ich verstehe den Code auch nicht wirklich. Wie price = price[0] definiert wird z.B.
            Müßte man data nicht erst mal beibiegen, das es die drei Sachen enthält, seine Größe usw.?

              
            <script type="text/javascript">  
            function Preis () {  
                var data = {  
                    "Salami" : {  
                        "18cm" : "2.70",  
                        "28cm" : "5.40"  
                    },  
                    "Tuna" : {  
                        "18cm" : "3.50",  
                        "28cm" : "6.80"  
                    },  
                    "Hawaii" : {  
                        "18cm" : "3.55",  
                        "28cm" : "6.88"  
                    }  
                           }; // data  
              
                var price = document.getElementByName("Preis1"); // ergibt ein Array  
                var sel = document.getElementByName("Sorte1"); // ergibt ein Array  
                var si = document.getElementByName("Size1"); // ergibt ein Array  
              
                if (price.length && sel.length && si.length)  
                  {  
                    // die Arrays waren nicht leer -> jeweils erstes Element nehmen  
                    price = price[0];  
                    sel = sel[0];  
                    si = si[0];  
              
                    // Daten auswerten (prüfen, ob die gewählten Werte in den Daten stehen)  
                    if (data[sel.value] && data[sel.value][si.value])  
                       { price.value = data[sel.value][si.value]; } else  
                       { price.value = 0; }  
                  }  
            }  
            </script>  
            
            

            Bei "var price = document.getElementByName("Preis1"); // ergibt ein Array"
            kommt jetzt die Meldung "Objekt unterstützt diese Eigenschaft oder Methode nicht"

            Wahrscheinlich brauche ich doch einen Debugger...

            mfG Jürgen

            1. Om nah hoo pez nyeetz, J.Borchert!

              Debuggen ist gut. Habe allerdings so gut wie noch nie mit Java zu tun gehabt, eher mit anderen Programmiersprachen...

              Java != JavaScript ;-)

              Matthias

              --
              Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Fell und Fellatio.

            2. Bei "var price = document.getElementByName("Preis1"); // ergibt ein Array"
              kommt jetzt die Meldung "Objekt unterstützt diese Eigenschaft oder Methode nicht"

              Wahrscheinlich brauche ich doch einen Debugger...

              mfG Jürgen

              Es muss getElementsByName und nicht getElementByName heißten. elementS ...

              1. Lieber Markus**,

                keine Sorge, der kommt nimmer.

                Liebe Grüße,

                Felix Riesterer.

                --
                ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
      2. Lieber J.Borchert,

        warum notierst Du Deine Daten nicht in einem entsprechenden Format, um sie dann daraus abzuleiten?

        function Preis () {  
            var data = {  
                "Salami" : {  
                    "18cm" : "2.70",  
                    "28cm" : "5.40"  
                },  
                "Tuna" : {  
                    "18cm" : "3.50",  
                    "28cm" : "6.80"  
                },  
                "Hawaii" : {  
                    "18cm" : "3.55",  
                    "28cm" : "6.88"  
                }  
            };  
          
            var price = document.getElementByName("Preis1"); // ergibt ein Array  
            var sel = document.getElementByName("Sorte1"); // ergibt ein Array  
            var size = document.getElementByName("Size1"); // ergibt ein Array  
          
            if (price.length && sel.length && size.length) {  
                // die Arrays waren nicht leer -> jeweils erstes Element nehmen  
                price = price[0];  
                sel = sel[0];  
                size = size[0];  
          
                // Daten auswerten (prüfen, ob die gewählten Werte in den Daten stehen)  
                if (data[sel.value] && data[sel.value][size.value]) {  
                    price.value = data[sel.value][size.value];  
                } else {  
                    price.value = 0;  
                }  
            }  
        }
        

        Der Code ist nicht getestet. Aber vielleicht bringt er Dich auf Ideen...?

        Sollte die Funktion einmal mehrere Formulare bedienen, kann man die eins am Ende der Feldnamen sogar von der Funktion hinzurechnen lassen und im onchange-Attribut entsprechend übermitteln:

        <select name="Sorte7" onchange="Preis(7)">...

        function Preis (index) {  
            ...  
            var price = document.getElementsByName("Preis" + index); // ergibt ein Array  
            ...  
        }
        

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
        1. Hallo Felix,

          warum notierst Du Deine Daten nicht in einem entsprechenden Format, um sie dann daraus abzuleiten?

          guter Ansatz.

          var price = document.getElementByName("Preis1"); // ergibt ein Array
              var sel = document.getElementByName("Sorte1"); // ergibt ein Array
              var size = document.getElementByName("Size1"); // ergibt ein Array

          Und weil diese Methode Arrays (bzw. Collections) zurückgibt, steht im Methodennamen der Plural: getElement_s_ByName.

          Sollte die Funktion einmal mehrere Formulare bedienen, kann man die eins am Ende der Feldnamen sogar von der Funktion hinzurechnen lassen und im onchange-Attribut entsprechend übermitteln:

          Daran dachte ich auch schon, ich wollte aber nicht zu weit vorgreifen.

          <select name="Sorte7" onchange="Preis(7)">...

          Besser:

          <select name="Sorte7" onchange="Preis(this.form)">...

          So hat man in der Auswertefunktion das Formular direkt zur Verfügung und kann wieder über die Feldnamen zugreifen:

          function Preis(f)  
           {  
             ...  
             var price = f.Preis.value; // eine Numerierung der Formularfelder ist dann überflüssig  
             ...  
           }
          

          Ciao,
           Martin

          --
          Der Alptraum jedes Computers:
          "Mir war, als hätte ich gerade eine 2 gesehen."
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          1. Lieber Der Martin,

            Und weil diese Methode Arrays (bzw. Collections) zurückgibt, steht im Methodennamen der Plural: getElement_s_ByName.

            richtig, mein Fehler. Aber ich hatte ja darauf hingewiesen, dass der Code ungeprüft sei. :-)

            Besser:

            <select name="Sorte7" onchange="Preis(this.form)">...

            So hat man[...]
            var price = f.Preis.value; // eine Numerierung der Formularfelder ist dann überflüssig

            Das ist mir schon von je her ungeheuer gewesen. Es kann ja durchaus mehrere Elemente mit demselben Namen geben, da der Wert des name-Attributs nicht dokumentweit eindeutig sein muss (denke an Radio-Buttons). Daher ist mir diese Inkonsistenz mit f.Preis.value im Gegensatz zu f.Preis[3].value (z.B. bei vier Radio-Buttons) irgendwie suspekt.

            Seit ich aber einmal begriffen habe, wie ich mich im DOM herumhangeln kann, ist es mir persönlich egal, welche Knoten wie im Dokument miteinander verknotet sind, ich kriege sie alle! *mad-scientist-laughter*

            Wer will, kann sich in dieser Hinsicht gerne mit Sizzle (oder gleich jQuery) dopen...

            Liebe Grüße,

            Felix Riesterer.

            --
            ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
            1. Hi Felix,

              var price = f.Preis.value; // eine Numerierung der Formularfelder ist dann überflüssig
              Das ist mir schon von je her ungeheuer gewesen. Es kann ja durchaus mehrere Elemente mit demselben Namen geben, da der Wert des name-Attributs nicht dokumentweit eindeutig sein muss (denke an Radio-Buttons).

              das stimmt, aber über die Kette document.formularname.controlname greife ich ja nur auf die Elemente dieses einen Formulars zu, da können mir gleichnamige Elemente an anderer Stelle im Dokument egal sein. Wenn allerdings innerhalb _eines_ Formulars mehrere gleichnamige Elemente auftauchen (was ja z.B. bei Radiobuttons sogar sinnvoll ist), bekomme ich hier wieder ein Array und muss das noch entsprechend indizieren.
              Das sollte mir als Autor aber von der Logik und Semantik her bekannt und bewusst sein.

              Seit ich aber einmal begriffen habe, wie ich mich im DOM herumhangeln kann, ist es mir persönlich egal, welche Knoten wie im Dokument miteinander verknotet sind, ich kriege sie alle! *mad-scientist-laughter*

              Ich bevorzuge eigentlich den Zugriff über bereits vorhandene Collections (auch z.B. document.images oder document.links), anstatt mir jedes Element individuell mit irgendeinem getElement[s]By... herauszusuchen.

              Wer will, kann sich in dieser Hinsicht gerne mit Sizzle (oder gleich jQuery) dopen...

              Nun ja, wer's mag ... ;-)

              Schönen Sonntag noch,
               Martin

              --
              Elefant zum Kamel: "Sag mal, wieso hast du denn den Busen auf dem Rücken?"
              Kamel:             "Ziemlich freche Frage für einen, der den Penis im Gesicht hat."
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          2. <select name="Sorte7" onchange="Preis(7)">...

            Besser:

            <select name="Sorte7" onchange="Preis(this.form)">...

            So hat man in der Auswertefunktion das Formular direkt zur Verfügung und kann wieder über die Feldnamen zugreifen:

            So verliert man aber den Bezug zum auslösenden Feld. Warum nicht so:

            <select name="Sorte7" onchange="Preis(this)">...

            Auf den Form kommt man Bedarf ja immer noch innerhalb der Funktion...

            1. Hallo,

              nicht nur ein Mitleser, sondern auch ein Mitdenker! :-)

              <select name="Sorte7" onchange="Preis(this.form)">...
              So hat man in der Auswertefunktion das Formular direkt zur Verfügung und kann wieder über die Feldnamen zugreifen:

              So verliert man aber den Bezug zum auslösenden Feld.

              ja, stimmt. Der war aber im vorliegenden Fall gar nicht nötig, weil die in der Eventhandler-Funktion durchgeführte Neuberechnung und Aktualisierung unabhängig davon ist, welches Feld geändert wurde. Sie muss also ohnehin auf alle relevanten Felder des Formulars zugreifen.

              Warum nicht so:
              <select name="Sorte7" onchange="Preis(this)">...
              Auf den Form kommt man Bedarf ja immer noch innerhalb der Funktion...

              Kann man auch machen; muss man sogar, wenn es wichtig ist, welches Feld der Auslöser ist.
              Wenn nicht, würde ich mal sagen: Geschmackssache.

              So long,
               Martin

              --
              Noch Fragen? - Ich weiß es auch nicht.
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  2. Lieber J.Borchert,

    [code lang=html]<option>Salami<option>Tuna<option>Hawaii</select>

    was genau soll der Browser denn aus dieser Tag-Suppe herauslöffeln? Füttere den Browser mit vernünftigen Daten und er wird berechenbar darauf reagieren.

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hallo Felix,

      [code lang=html]<option>Salami<option>Tuna<option>Hawaii</select>
      was genau soll der Browser denn aus dieser Tag-Suppe herauslöffeln? Füttere den Browser mit vernünftigen Daten und er wird berechenbar darauf reagieren.

      plain old HTML 4.01 erlaubt das Weglassen einiger schließender Tags (z.B. beim option-Element), und es erlaubt auch das Weglassen des vaue-Attributs bei option. In dem Fall wird automatisch der Elementinhalt als value genommen.

      Schön ist das Gewurschtl natürlich trotzdem nicht.

      Ciao,
       Martin

      --
      Man sollte immer wissen was man sagt
       - aber auf keinen Fall alles sagen, was man weiß.
      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(