www.webdeveloper.com
Results 1 to 7 of 7

Thread: Loop through form.elements array validating with custom event handlers

  1. #1
    Join Date
    Jul 2009
    Location
    UK
    Posts
    174

    Loop through form.elements array validating with custom event handlers

    hi

    Nice module, but I can't get it too work.

    Code:
    /**
    * validate.js: unobtrusive HTML form validation.
    *
    *
    *
    *
    *
    *
    *
    */
    (function(){ // Do everything in this one anonymous function:
    		// When the doument finishes loading, call init()
     if(window.addEventListener) window.addEventListener("load", init, false); // FF (W3C)
     else if(window.attachEvent) window.attachEvent("onload", init); // IE
    
     // Define event handlers for any forms and form elements that need them.
     function init(){
    	// Loop through all forms in the document:
    	for(var i = 0; i < document.forms.length; i++) {
    		
    
    		var f = document.forms[i]; // The form we're currently working on
    
    		// Assume for now, that this form does not need any validation:
    		var needsValidation = false;
    
    		// Now loop through the elements in our form:
    		for(var j = 0; j < f.elements.length; j++){
    			
    			var e = f.elements[j]; // The element we're currently working on
    
    			// We're only interested in <input type="text"> textfields
    			if(e.type != "text") continue;
    
    			// See if it has attributes that require validation:
    			var pattern = e.getAttribute("pattern");
    			// We could use e.hasAttribute(), but IE doesn't support it!
    			var required = e.getAttribute("required") != null;
    			
    			// Required is just a short-cut for a simple pattern
    			if(required && !pattern){
    				pattern = "\\S";
    				e.setAttribute("pattern", pattern);
    				 
    			}
    			
    			// If this element requires validation,
    			if(pattern){
    				//Validate the element each time it changes
    				e.onchange = validateOnChange;
    				// Remember to add an onsubmit handler to this form
    				needsValidation = true;
    
    			}
    		}
    
    		// If at least one of the form elements needed valdation,
    		// we also need an onsubmit event handler for the form
    		if(needsValidation) f.onsubmit = validateOnSubmit;
    
    	}
     }
    
     // This function is the onchange event handler for textfields that
     // require validation. Remember that we converted the required attribute
     // to a pattern attribute in init().
     function validateOnChange(){
    	var textfield = this;				// the textfield
    	var pattern = textfield.getAttribute("pattern"); // the pattern
    	var value = this.value;				// the users input
    	
    	// If the value does not match the pattern, set the class to "invalid"
    	if(value.search(pattern) == -1) textfield.className = "invalid";
    	else textfield.className = "valid";
     }
    
     // This function is the onsubmit event handler for any form that requires validation.
     function validateOnSubmit(){
    	// When the form is submitted, we revalidate all the fields in the 
    	// form and then check their classNames to see if they are invalid.
    	// If any of those fields are invalid, display an alert and prevent
    	// the form submisssion.
    	var invalid = false; // Start by assuming everything is valid.
    	
    	// Loop through all form elements
    	for(var i = 0; i < this.elements.length; i++){
    		
    		var e = this.elements[i];
    
    		// If the element is a text field and has our onchange handler
    		if(e.type == "text" && e.onchange = validateOnChange){
    			e.onchange(); // Invoke the handler to re-validate
    
    			// If validation fails for the element, it fails for the form
    			if(e.className = "invalid") invalid = true;
    		}	
    	}
     	// If the form is invalid, alert user and block submission
    	if(invalid){
    		alert("The form is incorrectly or incompletely filled out.\n" + "Please correct	the highlighted fields and try again.");
    		return false;	
    	}
     }
    
    })();
    Code:
    <!doctype html>
    <html>
    <head>
    <script type="text/javascript" src="validate.js"></script>
    
    <style type="text/css">
    
    input.valid {background: #99FF66;}
    input.invalid {background: #FF3333; }
    </style>
    
    
    <title>JavaScript form validation</title>
    </head>
    <body>
    
     <form action="index.htm">
      <!-- A value (anything other than whitespace) is required in this field -->
      Name: <input type="text" name="name" required /><br />
      <!-- \s* means optional space. \w+ means one or more alphnumeric chars -->
      email: <input type="text" name="email" pattern="^\s*\w+@\w+\.\w+\s*$" /><br />
      <!-- \d{5} means exactly five digits -->
      postcode: <input type="text" name="zip" pattern="^\s*\d{5}\s*$" /><br />
      <!-- no validation on this field -->
      unvalidated: <input type="text" /><br />
     <input type="submit" />
    
    </form>
    
    </body>
    </html>
    The script should be searching against the regex's or patterns hard coded into the form.

    This line:
    Code:
    if(value.search(pattern) == -1) textfield.className = "invalid";
    should be setting the
    Code:
    if(e.className = "invalid") invalid = true;
    invalid flag to true??


    The script doesn't alert the user to empty or invalid data?

    tried a debug at:

    Code:
    // debug
    alert(e.className);
    
    // If validation fails for the element, it fails for the form
    			if(e.className = "invalid") invalid = true;
    		}	
    	}
     	// If the form is invalid, alert user and block submission
    	if(invalid){
    		alert("The form is incorrectly or incompletely filled out.\n" + "Please correct	the highlighted fields and try again.");
    		return false;	
    	}
     }
    
    })();
    but the script alerts me nothing?
    Success is the ablility to go from one failure to another without loss of enthusiasm.
    -- Sir Winston Churchill.

  2. #2
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    you need to convert pattern to a RX.
    i like to simply use eval eval("0||"+pattern), but you can escape the string and use new RegExp(pattern) as well...
    EDIT;

    to use eval, turn it into a literal first:

    Code:
    var pattern="^\s*\d{5}\s*$";
    rx=eval("0||/"+pattern+"/")

  3. #3
    Join Date
    Jul 2009
    Location
    UK
    Posts
    174
    Quote Originally Posted by rnd me View Post
    you need to convert pattern to a RX.
    i like to simply use eval eval("0||"+pattern), but you can escape the string and use new RegExp(pattern) as well...
    EDIT;

    to use eval, turn it into a literal first:

    Code:
    var pattern="^\s*\d{5}\s*$";
    rx=eval("0||/"+pattern+"/")
    So, um, er...

    Code:
    alert(textfield.getAttribute("pattern"));
    prints out: ^\s*\w+@\w+\.\w+\s*$ when i change the email field - as you'd expect.

    So pattern is a regex and the program sees it as one upon reaching this point in the code.

    Also, I tried:

    Code:
    // This function is the onchange event handler for textfields that
     // require validation. Remember that we converted the required attribute
     // to a pattern attribute in init().
     function validateOnChange(){
    	var textfield = this;				// the textfield
    	var pattern = eval(textfield.getAttribute("pattern")); // the pattern modified
    	var value = this.value;				// the users input
    	
    	// If the value does not match the pattern, set the class to "invalid"
    	if(value.search(pattern) == -1) textfield.className = "invalid";
    	else textfield.className = "valid";
     }
    but no joy?
    Success is the ablility to go from one failure to another without loss of enthusiasm.
    -- Sir Winston Churchill.

  4. #4
    Join Date
    Jul 2008
    Location
    urbana, il
    Posts
    2,787
    without a call to RegExp or eval, pattern is just a string, even if it looks like a regexp.
    when you alert a true regexp, it always has "/" as the first char and ends with "/" (plus any of "igm").

    you eval the text of pattern, but you didn't add the slashes to make it a RX literal like my example shows.

    re-read my response more carefully and keep trying; you are circling in...

  5. #5
    Join Date
    Jul 2009
    Location
    UK
    Posts
    174
    Quote Originally Posted by rnd me View Post
    you need to convert pattern to a RX.
    i like to simply use eval eval("0||"+pattern), but you can escape the string and use new RegExp(pattern) as well...
    EDIT;

    to use eval, turn it into a literal first:

    Code:
    var pattern="^\s*\d{5}\s*$";
    rx=eval("0||/"+pattern+"/")
    Things I've tried:

    Code:
     function validateOnChange(){
    	var textfield = this;				// the textfield
    	var pattern = eval(("0||/"+ textfield.getAttribute("pattern") +"/"); // the pattern
    	var value = this.value;				// the users input
    	
    	// If the value does not match the pattern, set the class to "invalid"
    	if(value.search(pattern) == -1) textfield.className = "invalid";
    	else textfield.className = "valid";
     }
    and:
    Code:
    function validateOnChange(){
    	var textfield = this;				// the textfield
    	var pattern = textfield.getAttribute("pattern"); // the pattern
    	var rx = eval("0||/"+ pattern +"/");
    	var value = this.value;				// the users input
    	// If the value does not match the pattern, set the class to "invalid"
    	if(value.search(rx) == -1) textfield.className = "invalid";
    	else textfield.className = "valid";
     }
    Quote Originally Posted by rnd me View Post

    to use eval, turn it into a literal first:
    The program should be doing this dynamically with one of the methods above?
    Success is the ablility to go from one failure to another without loss of enthusiasm.
    -- Sir Winston Churchill.

  6. #6
    Join Date
    Jul 2009
    Location
    UK
    Posts
    174

    re:

    bump...
    Success is the ablility to go from one failure to another without loss of enthusiasm.
    -- Sir Winston Churchill.

  7. #7
    Join Date
    Jul 2009
    Location
    UK
    Posts
    174

    forget bout it!

    sod that, this rocks...

    http://sbpoley.home.xs4all.nl/webmatters/formval.html

    and you don't have to use a big clunky jquery library..loads in milliseconds..nice..

    Success is the ablility to go from one failure to another without loss of enthusiasm.
    -- Sir Winston Churchill.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles