Chester Copperpott: Javascript Fehlermeldungen

Hallo!

Ich hoffe ihr könnt mir helfen. Ich sitze gerade zum ersten mal an Javascript, aber einige Grundprinzipien der Programmierung sind mir durchaus bekannt... Es geht um das checken von Formularinhalten. Das Problem ist, dass nicht Schritt für Schritt eine einzelne Fehlermeldung für jedes Feld kommen soll, sondern eine einzige Fehlerbox, die alle Fehler auf einmal ausgibt. Die Funktion checkmail soll aufgerufen werden, wenn man in das mailfeld geklickt hat und sie soll eine Fehlermeldung schon beim rausklicken aus dem Mailfeld anzeigen. Das funktioniert soweit auch. Am Ende soll beim send button nochmal alles geprüft werden. Das funktioniert allerdings nicht. Der Browser will immer abschicken und gibt keine Fehlermeldung aus. Es scheint also, als würde die Funktion checkall() gar nicht aufgerufen werden. Ich verstehe nicht woran das liegt... Ich habe folgenden Quelltext geschrieben:

<html>
<head>
<title>Formular Übung</title>
<meta name="author" content="Chester Copperpott">
<meta name="editor" content="html-editor phase 5">
<script language="JavaScript1.2" type="text/javascript">
    var a,b,c = 0;
    var fehler = "";
    function checkmail(mail)
    {
        fehler = ""
        if(mail == "" || Formular.mail.value.indexOf("@") == -1)
        {
            b = 1;
            fehler = fehler + "Bitte E-Mail-Adresse angeben!\n";
            return Fehler();
        }
    }

function checkall()
    {
        fehler = "";
        if (document.Formular.name.value == "")
        {
            a = 1;
            fehler = fehler + "Bitte geben Sie ihren Namen an!\n";
        }
        if(mail == "" || Formular.mail.value.indexOf("@") == -1)
        {
            b = 1;
            fehler = fehler + "Bitte geben sie eine korrekte E-Mail-Adresse an!\n";
        }
        if (a == 1 || b == 1)
        { return Fehler(); }
        else
        { return true }

}
    function Fehler()
    {
        if (a == 1 || b == 1)
        {
            alert(fehler);
            return false;
        }

}
</script>
</head>
<body text="#000000" bgcolor="#FFFFFF" link="#FF0000" alink="#FF0000" vlink="#FF0000">

<form name="Formular" method="post" action="http://de.selfhtml.org/cgi-bin/formview.pl" ENCTYPE="text/plain" onsubmit="return checkall()">
    <div class="formular">
           <h1>Feedback</h1>
           <p><label for="name">Name*</label><input name="name" size="34" type="text" onmouseover="showWMTT('1')" onmouseout="hideWMTT()" /></p>
           <p><label for="mail">E-Mail*</label><input name="mail" size="34" onblur="checkmail(this.value)" type="text" onmouseover="showWMTT('1')" onmouseout="hideWMTT()" /></p>
           <input type=submit value="Senden">
           <input type=reset value="Reset">
    </div>
    </form>
</body>
</html>

  1. Hallo,

    <form name="Formular" method="post" action="http://de.selfhtml.org/cgi-bin/formview.pl" ENCTYPE="text/plain" onsubmit="return checkall()">

    <input type=submit value="Senden">
               <input type=reset value="Reset">

    Was sollte den Browser aufhalten? M.E. kannst du nicht mit einem Submit-Button arbeiten. Nimm einen normalen Button, onclick->checkall() und wenn checkall ok ist, dann das Formular per Javascript senden.

    Viele Grüße
    Siri

    1. ich hab das jetzt so:

      <form name="Formular" method="post" action="http://de.selfhtml.org/cgi-bin/formview.pl" enctype="text/plain">
      <div class="formular">
      <h1>Feedback</h1>
      <p><label for="name">Name*</label><input name="name" size="34" type="text" onmouseover="showWMTT('1')" onmouseout=
      "hideWMTT()"></p>
      <p><label for="mail">E-Mail*</label><input name="mail" size="34" onblur="checkmail(this.value)" type="text" onmouseover=
      "showWMTT('1')" onmouseout="hideWMTT()"></p>
      <input type="button" onclick="return checkall()" value="Senden"> <input type="reset" value="Reset"></div>
      </form>

      jetzt weiß ich nicht wo und wie ich einbaue, dass gesendet wird...

      und eine Fehlermeldung kommt trotzdem nicht...

    2. mit diesem code funktioniert jetzt die Fehlerabfrage, allerdings wird jetzt nur die mail abgeschickt, wenn man zuerst alle Felder richtig ausgefüllt hat. Wenn man etwas falsch gemacht hat, kommt die Fehlermeldung, wenn man es dann korrigiert und abschickt geht nur eine leere Alertbox auf...

      warum der Tooltip nicht funktioniert ist mir auch schleierhaft...

      <html>
      <head>

      <title>Test</title>

      <style type="text/css" media="screen">
          .tooltip
          {
              position: absolute;
              display: none;
              background-color: red;
              color: white;
          }
                                                               s
          h1
          {
              text-align: center;
              font-size: 36px;
          }

      p
          {
              font-size: 18px;
          }

      label
          {
              display: inline-block;
              width: 5em;
          }

      .formular
          {
              background-color: #ff8c00;
              top: 20px;
              left: 20px;
              padding: 20px;
              float: left;
              margin: 5px;
          }
      </style>
      <link rel="stylesheet" type="text/css" href="FormularTest.css" media="screen">
      <script language="JavaScript1.2" type="text/javascript">
          var a,b,c = 0;
          var fehler = "";
          function checkmail(mail)
          {
              fehler = "";
              if(document.Formular.mail.value == "" || document.Formular.mail.value.indexOf("@") == -1)
              {
                  b = 1;
                  fehler = fehler + "Bitte E-Mail-Adresse angeben!\n";
                  return Fehler();
              }
          }

      function checkall()
          {
              fehler = "";
              if (document.Formular.name.value == "")
              {
                  a = 1;
                  fehler = fehler + "Bitte geben Sie ihren Namen an!\n";
              }
              if(document.Formular.mail.value == "" || document.Formular.mail.value.indexOf("@") == -1)
              {
                  b = 1;
                  fehler = fehler + "Bitte geben sie eine korrekte E-Mail-Adresse an!\n";
              }
              if (a == 1 || b == 1)
              { return Fehler(); }
              else
              { return true; }

      }
          function Fehler()
          {
              if (a == 1 || b == 1)
              {
                  alert(fehler);
                  return false;
              }

      }

      wmtt = null;
      document.onmousemove = updateWMTT;
      function updateWMTT(e) {
        if (wmtt != null && wmtt.style.display == 'block') {
          x = (e.pageX ? e.pageX : window.event.x) + wmtt.offsetParent.scrollLeft - wmtt.offsetParent.offsetLeft;
          y = (e.pageY ? e.pageY : window.event.y) + wmtt.offsetParent.scrollTop - wmtt.offsetParent.offsetTop;
          wmtt.style.left = (x + 3) + "px";
          wmtt.style.top   = (y + 3) + "px";
        }
      }
      function showWMTT(id) {
        wmtt = document.getElementById(id);
        wmtt.style.display = "block";
      }
      function hideWMTT() {
        wmtt.style.display = "none";
      }

      </script>

      </head>
      <body text="#000000" bgcolor="#FFFFFF" link="#FF0000" alink="#FF0000" vlink="#FF0000">
      <form name="Formular" method="post" action="mailto:marcel.laskus@gmail.com" enctype="text/plain" onsubmit="return checkall()">
      <div class="formular">
      <h1>Feedback</h1>
      <p><label for="name">Name*</label><input name="name" size="34" type="text" onmouseover="showWMTT('1')" onmouseout="hideWMTT()"></p>
      <p><label for="mail">E-Mail*</label><input name="mail" size="34" onblur="checkmail(this.value)" type="text" onmouseover="showWMTT('1')" onmouseout="hideWMTT()"></p>
      <input type="submit" value="Absenden">
      <input type=reset value="Reset">
      </div>
      </form>
      </body>
      </html>

      1. Lieber Chester Copperpott,

        oh je, wo soll ich anfangen?

        Lass mich die in Deinem Beispiel nicht genutzten Dinge einmal ausblenden:

        wmtt = null;
        document.onmousemove = updateWMTT;
        function updateWMTT(e) {
          if (wmtt != null && wmtt.style.display == 'block') {
            x = (e.pageX ? e.pageX : window.event.x) + wmtt.offsetParent.scrollLeft - wmtt.offsetParent.offsetLeft;
            y = (e.pageY ? e.pageY : window.event.y) + wmtt.offsetParent.scrollTop - wmtt.offsetParent.offsetTop;
            wmtt.style.left = (x + 3) + "px";
            wmtt.style.top   = (y + 3) + "px";
          }
        }
        function showWMTT(id) {
          wmtt = document.getElementById(id);
          wmtt.style.display = "block";
        }
        function hideWMTT() {
          wmtt.style.display = "none";
        }

        Diese wmtt-Sache kann bei Dir deshalb nicht funktionieren, da Du der Funktion showWMTT als ID den String '1' übergibst, der dann in der Funktion ein Element mit dieser ID finden will. Genau hier gibt es aber zwei Probleme:

        1.) Ein Element mit id="1" gibt es in Deinem Code nicht.
        2.) Eine simple Zahl ist als ID-Wert nicht erlaubt!

        Wenn nun Deine showWMTT-Funktion mit getElementById() kein Element findet, dann erhält die Variablen wmtt den Wert null. Dieses Objekt kennt keine Eigenschaft namens "style", noch viel weniger ein Unterobjekt dieses Namens, das eine Eigenschaft "display" hätte. Daher sollte jedes Mal beim Überfahren mit der Maus eine entsprechende Fehlermeldung (so in etwa "wmtt.style has no property" oder "wmtt is null") ausgeben. Und bedenke: Wer mit JavaScript hantiert, der sollte zwingend in die Fehlerkonsole seines Browsers schauen!

        warum der Tooltip nicht funktioniert ist mir auch schleierhaft...

        Das hätten wir ja jetzt gelöst.

        Nun zu den wirklich interessanten Teilen Deiner Programmiererei.

        mit diesem code funktioniert jetzt die Fehlerabfrage,

        Wie hast Du das überprüft? Doch nicht etwa nur durch die Tatsache, dass das Formular abgesandt wird?

        allerdings wird jetzt nur die mail abgeschickt, wenn man zuerst alle Felder richtig ausgefüllt hat. Wenn man etwas falsch gemacht hat, kommt die Fehlermeldung, wenn man es dann korrigiert und abschickt geht nur eine leere Alertbox auf...

        Dass da "nur eine leere Alertbox" aufgeht, liegt daran, dass Deine Funktion "Fehler" eine Variable namens "fehler" benutzt, die nicht unbedingt existieren muss. Auch hier könnte die Fehlerkonsole Deines Browsers wesentliche Hinweise liefern!

        Es wäre viel sinnvoller, die Funktion "Fehler" so umzustricken, dass sie einen Wert entgegen nimmt, um diesen dann auszugeben. Noch sinnvoller erscheint mir, die alert-Ausgabe gleich in der checkmail-Funktion vorzunehmen. Denn wenn kein Fehler da ist, warum sollte der User dann überhaupt mit einem alert belästigt werden? Also ist in Deinem konkreten Beispiel das Auslagern der Fehlermeldung nicht sinnvoll.

        <script language="JavaScript1.2" type="text/javascript">

        Streiche das language-Attribut ersatzlos. Es ist seit vielen Jahren nicht mehr sinnvoll.

        var a,b,c = 0;
            var fehler = "";

        Globale Variablen mögen für Dich im Moment sinnvoll sein, aber je weiter Du in die Materie einsteigst, desto weniger sind sie zu empfehlen. Das geht auch anders.

        function checkmail(mail)
        [...]
                if(document.Formular.mail.value == "" || document.Formular.mail.value.indexOf("@") == -1)
        [...]
            function checkall()
        [...]
                if(document.Formular.mail.value == "" || document.Formular.mail.value.indexOf("@") == -1)

        Ist da nicht etwas redundant? Wenn Du in checkall das Feld mit der Mailadresse prüfst, warum brauchst Du die Funktion checkmail überhaupt? Und wenn Du diese Funktion unabhängig von checkall verwenden möchtest, warum notierst Du dann den Code erneut, anstatt checkmail stattdessen aus checkall heraus aufzurufen?

        Eine Kleinigkeit an dieser Stelle: Die Funktion checkmail erwartet einen Parameter, den sie in der (lokalen) Variablen "mail" ablegt. Diese nutzt Du nicht, sondern greifst in checkmail direkt auf die Werte in den Eingabefeldern zu. Damit hätte sich die Werteübergabe eigentlich erledigt! Es sei denn, Du möchtest diese Funktion prinzipiell immer wieder als Prüffunktion für Mailadressen nutzen und in andere Scripte einbinden. Dann sollte aber checkall umso mehr diese Prüfung checkmail überlassen, anstatt die Prüfung selbst vorzunehmen:

        function checkall() {  
        ...  
            if (checkmail(document.Formular.mail.value)) {  
                // Adresse scheint OK  
            } else {  
                // Adresse offensichtlich nicht plausibel  
            }  
        ...  
        }  
          
        function checkmail(mail)  
            return (typeof(mail) == "string" && mail.indexOf("@") > 0);  
        }
        

        Dir ist hoffentlich klar, dass der Besucher JavaScript nicht zulassen muss, sodass Deine Prüfungen nur den Wert einer Hilfestellung haben können. Eine Überprüfung auf Gültigkeit und Plausibilität der Daten muss(!!) zwingend auf der Serverseite erfolgen.

        <form name="Formular" method="post" action="mailto:marcel.laskus@gmail.com" enctype="text/plain" onsubmit="return checkall()">

        Oh, Du sendest die Daten ja gar nicht an einen Server, sondern setzt darauf, dass der Besucher ein Mailprogramm installiert hat, welches durch das mailto-Pseudoprotokoll vom Browser aus aufgerufen werden soll. Tja, wer an einem fremden Rechner sitzt (Beruf, Internetcafé etc.) wird kaum eine Mail an Dich versenden. Da wäre ein echtes Kontaktformular, welches von einem serverseitigen Script beantwortet wird, das seinerseits eine echte Mail generiert und versendet, wesentlichst sinnvoller. Gerade Benutzer wie ich, die ihre Mails grundsätzlich über ein Webinterface verwalten, haben kein Mailprogramm in Benutzung, da sie ja im Browser auf der Website ihr Mailprogramm überall auf jedem System (PC, Smartphone, Tablet, Fremdrechner) gleich haben.

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:| n4:? de:> ss:| ch:? js:) mo:} zu:)
        1. Danke für die ausführliche Antwort Felix!

          Ich studiere gerade Medieninformatik im 1. Semester und das ist unsere 1. Aufgabe zu Javascript. Deswegen muss ich eben auch Javascript benutzen und auch die mailto methode/Befeh.

          Ich hab den den Inhalt der checkmail Funktion deshalb nochmal in die checkall Funktion hingeschrieben, weil ich einfach nicht weiß, wie ich in einer JS Funktion eine andere aufrufen kann... ;)

          Ich glaube aber um die Auftrennung in diese beiden Funktionen und eine extra Alertfunktion komme ich nicht drum herum weil, das ganze laut aufgabenstellung so funktionieren soll:

          man klickt in das mailfeld, sobald man es verläßt und etwas falsch darin ist, soll die Fehlermeldung kommen. D.h. der "senden" Button wurde noch nicht gecklickt. Deshalb brauche ich noch eine extra Prüffunktion, die aktiviert wird, wenn der "senden" button gedrückt wurde und dann aber jedes Feld prüft.
          Und nun das blöde daran: dann sollen alle Fehler in einer Alertbox erscheinen und nicht nacheinander eine Alertbox geöffnet werden. Deswegen brauche ich eine extra Funktion, die Alertbox aufruft und die Sammelvariable fehler ausgibt. Oder habe ich da einen Denkfehler? Ich denke das ist deshalb nötig, weil ja sonst zwei Fehlerboxen nacheinander erscheinen werden, erst die für die mailprüfung und dann nochmal eine für alle...

          Die Funktionen für den Tooltip hab ich einfach nur irgendwo rauskopiert und eingebastelt. Das hat merkwürdigerweise auch schon genau in dieser Form funktioniert... ?! An den entsprechenden Funktionen habe ich noch nie etwas verändert... Aber mir ist erstmal wichtiger dass die Fehlerabfrage und das senden funktionieren. Es reicht auch für die Aufgabenstellung, dass der Browser versucht ein Mailprogramm zu öffnen. Es geht nicht darum, dass man tatsächlich ein Feedback bekommt. Es geht nur darum, dass wir wissen, wie wir es programmieren können. Ich hab auch schon gelesen, dass die mailto methode ziemlich tricky ist, aber für mich gibt es keine Alternative, da die Aufgabe ja nicht online gestellt wird....

          1. Lieber Chester Copperpott,

            dann sollen alle Fehler in einer Alertbox erscheinen und nicht nacheinander eine Alertbox geöffnet werden.

            das ist sinnvoll und auch relativ einfach machbar.

            Wenn Du Deine checkmail-Funktion dahingehend erweiterst, dass sie einen zusätzlichen Parameter entgegennimmt, der dafür sorgt, dass sie selbst eine die Mailadresse betreffende Meldung ausgeben kann, dann ist es möglich, die checkall-Funktion checkmail ohne diesen Parameter aufzurufen, sodass dieser extra-Alert eben nicht kommt, sondern dass sie einfach alle ihre Fehler sammelt, bevor sie diese ausgibt.

            In etwa so:

            function checkmail (mail, giveFeedback) {  
                var ok = ([link:http://wiki.selfhtml.org/wiki/Referenz:JavaScript/Operatoren/Typenbestimmung@title=typeof] mail == "string" && mail.indexOf("@") > 0);  
              
                /* Der zweite Parameter muss irgendetwas enthalten, das als "true" gewertet werden kann.  
                   In JavaScript sind das u.a. folgende Werte:  
                   - true  
                   - eine Zahl > 0  
                   - ein String, der weder leer ist noch die Zahl null darstellt (z.b. "0.00")  
                   - ein Array, welches mindestens ein Element enthält  
                   - ein existierendes Objekt  
                */  
                if (giveFeedback) {  
                    alert("Die Mailadresse erscheint fehlerhaft! Bitte überprüfen Sie Ihre Eingabe.");  
                }  
              
                return ok;  
            }
            

            Obige Funktion kann man nun so nutzen:

                var mailOk = checkmail("test-ohne-at.example.org"); // ergibt true|false ohne alert-Fenster  
              
                checkmail("adresse@example.org", true); // ignoriert Rückgabewert, erzeugt alert-Fenster
            

            Deswegen brauche ich eine extra Funktion, die Alertbox aufruft und die Sammelvariable fehler ausgibt.

            Nein. Da Du das über window.alert tust, brauchst Du das nicht. Wolltest Du später festlegen, wie Ausgaben an den User getätigt werden, dann kannst Du eine solche extra-Funktion schreiben, um Dich später gegen alert als Ausgabemethode zu entscheiden. Aber für dieses Beispiel...?

            function checkall () {  
                var errors = []; // ein [link:http://wiki.selfhtml.org/wiki/Referenz:JavaScript/Array@title=Array] ist schöner, als ein simpler String  
              
                if (...) { // erstes Testkriterium gescheitert  
                    errors.push("Meldung zu erstem Test");  
                }  
              
                if (...) { // zweites Testkriterium gescheitert  
                    errors.push("Meldung zu zweitem Test");  
                }  
              
                // Mailadresse prüfen  
                if (!checkmail(document.Formular.mail.value)) { // ! invertiert true|false ins Gegenteil  
                    errors.push("Die Mailadresse erscheint fehlerhaft!");  
                }  
              
                // Ausgabe aller Fehler  
                outputAllErrors(errors);  
              
                return errors.length < 1;  
            }
            

            Wenn Du Fehler in Deinem Array gesammelt hast, dann hat sich seine length-Eigenschaft von null auf mindestens eins erhöht. Wenn dem so ist, dann will man ja ein "return false" haben. Das "false" aber bedeutet ja in diesem Zusammenhang nichts anderes, als dass fehler.length eben > 0 geworden ist. Daher kann ich das verkürzt wie oben notieren.

            Die Funktionen für den Tooltip hab ich einfach nur irgendwo rauskopiert und eingebastelt.

            Es ist grundsätzlich besser, wenn man genau weiß, was man tut. Ohne Tooltip hättest Du Dich mehr dem Verständnis der funktionalen Gestaltung gewidmet, aber Anfänger setzen immer einen so immensen Wert darauf, wie es aussieht...

            Liebe Grüße,

            Felix Riesterer.

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

              /* Der zweite Parameter muss irgendetwas enthalten, das als "true" gewertet werden kann.
                     In JavaScript sind das u.a. folgende Werte:
                     - true
                     - eine Zahl > 0

              nein, auch Zahlen <0 gelten als true. Das Kriterium ist x!=0.

              So long,
               Martin

              --
              Idealismus wächst mit der Entfernung zum Problem.
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              1. Lieber Der Martin,

                nein, auch Zahlen <0 gelten als true. Das Kriterium ist x!=0.

                ach, da ist mir doch glatt PHP in die Quere gekommen. Danke für Deine Richtigstellung.

                Liebe Grüße,

                Felix Riesterer.

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

                  nein, auch Zahlen <0 gelten als true. Das Kriterium ist x!=0.
                  ach, da ist mir doch glatt PHP in die Quere gekommen. Danke für Deine Richtigstellung.

                  in PHP gilt aber dasselbe.
                  Es ist ja nicht so, dass ich um jeden Preis recht haben will, aber ... ;-)

                  Ciao,
                   Martin

                  --
                  Man sollte keinen Senf von sich geben, wenn man nicht auch das Würstchen dazu liefern kann.
                  Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
            2. Die Sache mit dem Array habe ich auch zuerst versucht, weil es das nahe liegendste war. Allerdings erschien dann immer ein ungewolltes Komma zwischen den gesammelten Alertmeldungen...