Jörg: Javascript - Validierung von Formular-Feldern

Hallo,

habe ein Problem, bei dem ich nicht weiterkomme. Habe ein per PHP generiertes Formular, in welches nummerische Eingaben getätigt werden sollen. Wird ein nicht nummerischer Wert eingegeben, soll eine kleine Meldung erscheinen.

Leider verhält sich Javascript völlig unerwartet und gibt entweder alles als Fehler aus, oder alles ist korrekt. Auch verhalten sich die Browser unterschiedlich: Opera macht nix, FF & IE erkennen jede Eingabe als Fehler.

Habe den Output mal als statisches HTML aufbereitet, damit man sich ein Bild machen kann. Vielleicht kann mir jemand sagen, wo ich hier den Denkfehler gemacht habe?

Vielen Dank schon mal im Voraus,
Jörg

  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"  
        "http://www.w3.org/TR/html4/strict.dtd">  
  
<HTML><HEAD><TITLE>Javascript-Test</TITLE>  
<SCRIPT type="text/javascript">  

  
	var footer = '\n\nVielen Dank für die Beachtung';  
	var SepChar = '+';  
  
	function sl_form_edit_check()  
	{  
		var sl_text_1 = 'In der Liste wurde ein Wert eingetragen, der nicht gespeichert werden kann.\n\nBitte den folgenden Eintrag korrigieren:\n\n   >>>';  
		  
		var data = document.helper.content.value.split(SepChar);	// Werte aus dem Helper-Formular				  
		var dmax = data.length;										// Anzahl der Helper-Werte  
		  
		with (document.liste)  
		{  
			for (i = 0; i < dmax; i++) {  
				var d = data[i];									// Ort ermitteln (Quelle: Helper)  
				var x = elements[d];								// daraus Referenz auf Element nehmen  
							  
				var res = checkNumber(x);  
				if (res == 2){							// Ist definiert, nicht Null und hat ungültigen Wert?  
					var n = document.getElementById(d);  
					var errmsg = sl_text_1 + n.innerHTML + '  (Wert: "' + x.value + '") {res: ' + res + '} <<<' + footer;  
					alert(errmsg);  
					x.focus();  
					return false;  
				}  
			}  
		}  
		return true;	  
	};  
  
	function checkNumber( /* (object: document.forms['liste'].elements[i]) */ v) {  
		try {  
			if (defined(v.innerHTML)) {  
				if (is_number(v.innerHTML)) {  
					throw 'ok';  
				}  
				if (!is_number(v.innerHTML)) {  
					throw 'error';  
				}  
			} else {  
				throw 'nothing';  
			}	  
		}  
		catch (e) {  
			switch (e) {  
				case 'ok':  
					// Ok, Feld beinhaltet einen nummerischen Wert  
					return 1;  
					break;  
					  
					// Fehler: Falsche Eingabe  
				case 'error':  
					return 2;  
					break;  
					  
				// FallBack: Wird Exception gleich am Anfang ausgelöst,  
				// ist das Feld leer und muss nicht weiter beachtet werden  
				case 'nothing':  
				default:  
					return 0;  
					break;  
			}			  
		}  
	};  
	  
	function defined(w){ return w != undefined && w != null; };  
	  
	function is_number(w){ return (typeof w == 'number') && !isNaN(w); };  

  
</SCRIPT>  
  
<BODY>  
<FORM name="liste" onsubmit="return sl_form_edit_check();">  
<TABLE>  
  <THEAD>  
  <TR>  
    <TH>Ort</TH>  
    <TH>Anzahl</TH>  
  </TR>  
  </THEAD>  
  <TBODY>  
  <TR><TD id="o1">Berlin</TD><TD><INPUT type="text" name="o1"/></TD></TR>  
  <TR><TD id="o3">Hamburg</TD><TD><INPUT type="text" name="o3"/></TD></TR>  
  <TR><TD id="o8">München</TD><TD><INPUT type="text" name="o8"/></TD></TR>  
  </TBODY>  
</TABLE>  
<BR>  
<INPUT type=hidden value="sl_save" name="mode"><INPUT class="button_save" type="submit" value="Eingaben speichern"></FORM>  
<FORM name="helper"><INPUT type="hidden" value="o1+o3+o8" name="content"></FORM>  
</BODY>  
</HTML>  

  1. Hallo,

    [...]

    function checkNumber( /* (object: document.forms['liste'].elements[i]) */ v) {
    try {
      if (defined(v.innerHTML)) {
        if (is_number(v.innerHTML)) {
          throw 'ok';
        }
      }

    [...]

    function defined(w){ return w != undefined && w != null; };

    function is_number(w){ return (typeof w == 'number') && !isNaN(w); };

    • also bei mir ist innerHTML immer ein string
    • warum überprüfst du nicht die "value" eigenschaft von deinen textfeldern?
    • woher hast du die idee mit den exceptions in checkNumber? finde ich "interessant"
    1. »» Hallo,
      »»
      [...]
      »» function checkNumber( /* (object: document.forms['liste'].elements[i]) */ v) {
      »» try {
      »»   if (defined(v.innerHTML)) {
      »»     if (is_number(v.innerHTML)) {
      »»       throw 'ok';
      »»     }
      »»   }
      [...]
      »» function defined(w){ return w != undefined && w != null; };
      »»
      »» function is_number(w){ return (typeof w == 'number') && !isNaN(w); };

      • also bei mir ist innerHTML immer ein string
      • warum überprüfst du nicht die "value" eigenschaft von deinen textfeldern?
      • woher hast du die idee mit den exceptions in checkNumber? finde ich "interessant"

      Hallo,
      danke für die Antwort.

      Klar habe ich es auch mit .value versucht. Die Variante mit try/catch war der letzte Versuch - ich weiss einfach nicht weiter.

      Habe schon ohne Probleme andere Validierungen vorgenommen, hier scheitere ich aber. Ständig bekomme ich die Meldung, das Element sei nicht definiert oder habe den Wert NULL.

      Hinzu kommt, dass die aufgebaute Liste der Orte eben variabel ist, dafür auch das Helper-Formular.

      Also, wenn jemand einen Tipp hat...

      Danke,
      Jörg

      1. hi,

        Habe schon ohne Probleme andere Validierungen vorgenommen, hier scheitere ich aber. Ständig bekomme ich die Meldung, das Element sei nicht definiert oder habe den Wert NULL.

        Hinzu kommt, dass die aufgebaute Liste der Orte eben variabel ist, dafür auch das Helper-Formular.

        Also, wenn jemand einen Tipp hat...

        also es soll erstmal nur geprüft werden, ob in den eingabefeldern zahlen stehen?

          
        function checkInput() {  
          // [ref:self812;javascript/objekte/regexp.htm@title=regulärer ausdruck]  
          var regex = /^\d+$/;  
          // [ref:self812;javascript/objekte/forms.htm@title=alle formelemente aus dem "liste" formular]  
          var formControls = document.forms["liste"].elements;  
          // einfach über alle formelemente rüber  
          for (var i = 0, len = formControls.length; i < len; i += 1) {  
            var formControl = formControls[i];  
            // wenn es ein input type=text ist ...  
            if (/^input$/i.test(formControl.tagName) && formControl.type == "text") {  
              // ... nachprüfen ob sein "value" eine zahl ist mithilfe des regulären ausdrucks von oben  
              if (!regex.test(formControl.value)) {  
                formControl.focus();  
                return false;  
              }  
            }  
          }  
          return true;  
        }  
        
        
        1. »» Habe schon ohne Probleme andere Validierungen vorgenommen, hier scheitere ich aber. Ständig bekomme ich die Meldung, das Element sei nicht definiert oder habe den Wert NULL.

          »»
          »» Hinzu kommt, dass die aufgebaute Liste der Orte eben variabel ist, dafür auch das Helper-Formular.
          »»
          also es soll erstmal nur geprüft werden, ob in den eingabefeldern zahlen stehen?

          function checkInput() {
            // [ref:self812;javascript/objekte/regexp.htm@title=regulärer ausdruck]
            var regex = /^\d+$/;
            // [ref:self812;javascript/objekte/forms.htm@title=alle formelemente aus dem "liste" formular]
            var formControls = document.forms["liste"].elements;
            // einfach über alle formelemente rüber
            for (var i = 0, len = formControls.length; i < len; i += 1) {
              var formControl = formControls[i];
            {...}
            }
            return true;
          }

          
          >   
            
          Vielen Dank für die konstruktive Antwort, das hat mich weitergebracht. Ich hatte gedacht, dass ich ein Element so ansprechen kann:  
          ~~~javascript
          var strName = 'abc';  
          var objElem = document.formname.elements[strName];
          

          Offensichtlich gibt es hier Probleme. Also durchlaufe ich jetzt die Elements und arbeite mit dem Index:
          var objElem = document.forms["liste"].elements[i];

          Kopfschüttel...

          Ok, hier mein vorerst endgültiger Code - vielen, vielen Dank für deine Hilfe,
          Gruß, Jörg

            
          function sl_form_edit_check() {  
          var sl_text_1 = 'In der Liste wurde ein Wert eingetragen, der weder gespeichert noch verarbeitet werden kann.\n\nBitte den folgenden Eintrag korrigieren:\n\n  >>> ';  
            
          // regulärer ausdruck  
          var regex = /^\d+$/;  
            
          // alle formelemente aus dem "liste" formular  
          var formControls = document.forms["liste"].elements;  
            
          // Werte aus dem Helper-Formular  
          var data = document.helper.content.value.split(SepChar);	  
          var dmax = data.length;					  
            
          // Alle Elemente des Formulars durchlaufen,  
          // Es werden nur die Elemente berücksichtigt, die in Helper aufgeführt sind:  
          for (var i = 0, len = formControls.length; i < len; i += 1) {  
            var formControl = formControls[i];  
            
            // formControl in Helper? Ginge doch bestimmt auch mit RegEx?  
            var inHelper = false;  
            for (j = 0; j < dmax; j += 1) {  
              if (formControl.name == data[j]) {  
              inHelper = true;  
              break;  
              }  
            }  
            
            if (inHelper) {			  
            
            // Wichtig: Es dürfen ausschließlich Felder mit Inhalt geprüft werden,  
            // Leere Felder müssen ignoriert werden:  
            
              var s = formControl.value;  
              if (s.length > 0) {  
                // ... nachprüfen ob sein "value" eine zahl ist mithilfe des regulären ausdrucks von oben  
                if (!regex.test(formControl.value)) {  
                  // Anzeigen, was der User nicht richtig gemacht hat:  
                  alert(sl_text_1 + document.getElementById(formControl.name).innerHTML + ' == "' + formControl.value + '" <<<' + footer);  
                  formControl.focus();  
                  return false;  
                }  
              }  
            }  
          }  
          return true;  
          }