Creating a form validation script

Discussion in 'Software' started by Roy Mustang, Nov 23, 2007.

  1. Roy Mustang

    Roy Mustang Private E-2

    First off, I should let it be known that I am pretty much a newbie when it comes to javascript. I've only recently begun learning HTML and CSS and javascript. My HTML and CSS skills are adequate to create the site the I need to. It's my javascripting skills that need work and I am certain that that is the core problem here.

    I have a few different things I need my form validation script to do. I want it to check my zip code field to make sure the zip code is in the proper format. I eventually want to extend that to validate the phone and fax number fields as well but I'm starting small. I need it to also validate the email address field to make sure a properly formatted email address is present. I then need it to check all the required fields to make sure they are not empty.

    I have found scripts on the internet to do all three of those, my problem is I don't know how to string them all together. I have the overall validation script working(the one that checks the fields to make sure they are not empty). I was just wondering if I could get some help incorporating the number and email address validation scripts into that.

    I completely realize that my very limited understanding of javascript at this point is the problem. I'm still learning it and I know I need to understand that I'm not going to learn it overnight. HTML and CSS was fairly easy and quick to learn for me. Javascript is proving a bit more difficult. It's probably because it's closer to actual computer programming, which I've never been able to get the hang of in the past. Anyhow, I'm attaching a file that contains all the javascript I have at this point. Again, the form field validation script works at this point, I just want to incorporate the number and email address scripts into it.

    I completely understand if I get replies saying I need to learn more about javascript before undertaking something like this.
     

    Attached Files:

  2. PC-XT

    PC-XT Master Sergeant

    I would try updating the validate function like this first:
    Code:
    function validate() {
    if(document.contactform.Contact_name.value=='' ||
    document.contactform.Company_name.value=='' ||
    document.contactform.Address.value=='' ||
    document.contactform.Address_type.value=='' ||
    document.contactform.City.value=='' ||
    document.contactform.State.value=='' ||
    document.contactform.Email_address.value=='' ||
    [COLOR="Red"]valzip(document.contactform.[I]zipcode[/I].value)==false||
    echeck(document.contactform.Email_address.value)==false||[/COLOR]
    document.contactform.Phone_number.value=='' ||
    document.contactform.Contact_method.value=='' ||
    document.contactform.How.value=='' ||
    document.contactform.Your_project.value==''){
    alert('Please fill out the fields marked with a red asterik before submitting this form.');
    } else {
    document.contactform.submit()
    }
    That way, the validate function would take care of everything. (Replace zipcode with the name of the form element to contain the zipcode. I wasn't sure if it was given.)

    I would also remove the HTML script tag from the end of the valzip function.
     
  3. Roy Mustang

    Roy Mustang Private E-2

    After making the changes you specified, this is what happens. When you enter some text into the zip code field and try to submit the form, the script does check to make sure it is 5 or 10 characters long. If it is not, it will pop up the alert. It does not seem to check to make sure they are all numbers or that the zip code is in the proper format(xxxxx-xxxx).

    Even if you have 5 or 10 characters in the zip code field, it will not complete the form submission. Clicking the submit button does nothing. I am attaching another text file of the updated javascript as well as the form information.

    Thanks for your help, I really do appreciate it.
     

    Attached Files:

  4. timduk

    timduk Private E-2

    Perhaps your script is failing...

    if ((hyphencount > 1) || ((field.length==10) && ""+field.charAt(5)!="-")) {

    "field" doesn't exist? - should that be "goodzip"?...
     
  5. Roy Mustang

    Roy Mustang Private E-2

    Thank you. The script will now check to make sure that only numbers are present in the zip code field as well. It will also submit the form if all fields are correct now as well. I just need to try and get the email validation script to work. Also, if an invalid zip code is entered, it displays the zip code error message but will also display the "make sure you fill out all fields..." message as well. Not a super issue there though.

    Again, thank you very much for your help. I really do appreciate you taking the time to help a novice like myself.
     
  6. timduk

    timduk Private E-2

    No problem :)

    Here's one way to do error checking to prevent incorrect error messages..

    (pseudo-code)

    if( any-asterisked-field == blank ) alert( "please fill in blah...." )
    else if( validate-field-1() == ok and validate-field-2() == ok ) submit-form
     
  7. Kodo

    Kodo SNATCHSQUATCH

    No offense, but this is awful. What you should do is write a set of Validation classes..

    ..I spent some time putting this together for a demo I was working on. Figured it would benefit you so I finished it (sort of).

    Code:
    
    function Validator(ele,eleid,text,textEle){
        this._element=null;
        this._isValid=true;
        this._errorText=null;
        this._textEle=null;
        this.get_textEle=function(){return this._textEle;};
        this.set_textEle=function(textEle){
                            this._textEle=document.getElementById(textEle);
                         }
        this.get_errorText=function(){return this._errorText;};
        this.set_errorText=function(text){
                            this._errorText=text;
                           };
        this.get_isValid=function(){ return this._isValid;};
        this.get_element=function(){ return this._element;};
        this.set_element=function(ele,eleid){
                         if(eleid){
                             this._element=document.getElementById(eleid);
                             return;
                         }
                         this._element=ele;
    
        };
        
        this.set_element(ele,eleid);
        this.set_textEle(textEle);
        this.set_errorText(text);
    }
    
    Validator.prototype.Validate=function(){
        throw ("Method not implemented")};
    
    function RequiredFieldValidator(ele,eleid,text,textEle,bgcolor){
      Validator.apply(this,arguments);
      this.Validate=function(){
            var ele=this.get_element();
            var textEle=this.get_textEle();
            
            this._isValid=!(ele.value.isNullOrEmpty());
            ele.style.backgroundColor=this._isValid===false?bgcolor:"#fff";
            if(textEle){
                textEle.innerText=this.get_errorText();
                textEle.style.color="#ff0000";
                textEle.style.display=this._isValid===false?"block":"none";
                }
        } 
      this._element.onblur=Function.delegate(this,this.Validate);
    }
    
    String.prototype.isNullOrEmpty=function(){
       return (this.length===0||this===null||this==="")?true:false;
    }
    
    Function.prototype.delegate=function(instance,method){
        return function() {
                return method.apply(instance, arguments);
            }
        }
    
    usage:

    Code:
    var tb1val=null;
    window.onload=function(){
         tb1val=new RequiredFieldValidator(null,"TextBox1","*","tb1err","#ffe6e6");
        //tb1val=new RequiredFieldValidator(elementObject,elementId,ErrorText,ErrorTextDisplayElement,TextBoxBgColor);
     }
    
    
    Just incase some of you ASP.NET guys go "that looks like asp.net".. no, I just used the same variable names. This class isn't a rip from the framework.


    Now you can reference these two classes to provide validation for a set of text boxes. 1 script file and x number of HTML element references is all you need; and you instantiate them as in the usage section

    This script does empty text box validation but it would be easy to write one that used a regular expression.
     
  8. timduk

    timduk Private E-2

    None taken... :) ... what you should do is stop trying to give it...:p

    Thanks for your advice, which will probably come in handy when I reach level-47-major-nerd-javascript-developer in a couple of years or so....

    Any chance of some comments in the code to see what's happening and how it works? Or are these eschewed as a frivolous luxury in the heady world of function-prototype-delegation-abstraction?

    It's probably all very clever in a technical sort of way, but I'm sorry, it's all Geek to me at the moment... :confused
     
  9. Kodo

    Kodo SNATCHSQUATCH

    I live by the motto: "if you're offended, it's because you wanted to be" ;)

    Aside from that, I have to give you props for the "level-47-major-nerd-javascript-developer"..that was pretty damned funny! lol :D

    ...So you wanted comments?
    Code:
    //base class validator
    //params: DOM Element Object, ElementID,ErrorMessage,Element where the error message is inserted into
    function Validator(ele,eleid,text,textEle){
        this._element=null; //private field to hold DOM element object
        this._isValid=true; //private field to hold true/false for validation
        this._errorText=null;// private field to hold the error message
        this._textEle=null;//private field to hold the DOM element where the error message goes
        this.get_textEle=function(){return this._textEle;}; //public method to return the error text DOM element
    
        //public set method of the text error DOM element
        this.set_textEle=function(textEle){
                            this._textEle=document.getElementById(textEle);
                         }
        this.get_errorText=function(){return this._errorText;};//public method that returns the actual error text
    
        //public set method to set the error text
        this.set_errorText=function(text){
                            this._errorText=text;
                           };
    
        this.get_isValid=function(){ return this._isValid;};// public method that returns whether the validation was true/false
        this.get_element=function(){ return this._element;};//public method that returns the DOM element that is being validated
    
        //public set method that sets the validation DOM element based off of the element reference itself or its' ID
        this.set_element=function(ele,eleid){
                         if(eleid){
                             this._element=document.getElementById(eleid);
                             return;
                         }
                         this._element=ele;
    
        };
        
        this.set_element(ele,eleid); //call the set_element method
        this.set_textEle(textEle); // call the set_textElee method
        this.set_errorText(text); // call the set_errorText method
    }
    
    //virtual method for base class Validator [override in every implementation]
    Validator.prototype.Validate=function(){
        throw ("Method not implemented")};
    
    //Sub class of Validator
    //params: DOM Element Object, ElementID,ErrorMessage,Element where the error message is inserted into,DOM element background color on invalid value
    function RequiredFieldValidator(ele,eleid,text,textEle,bgcolor){
      Validator.apply(this,arguments); //"inherits the base class"
    
      //override the base class validation method
      this.Validate=function(){
            var ele=this.get_element(); //gain ref to the validation DOM element
            var textEle=this.get_textEle(); //gain ref to the error text DOM element
            
            //for the required field, the value cannot be empty
            //check for "nothing"
            this._isValid=!(ele.value.isNullOrEmpty());
    
            //set the background color of the element using a ternary conditional
            ele.style.backgroundColor=this._isValid===false?bgcolor:"#fff";
    
            //make sure the text element is not null
            if(textEle){
                textEle.innerText=this.get_errorText(); //set the inner text to the error text value
                textEle.style.color="#ff0000"; //set the error text to red
    
                //ternary to determine the text elements visibility based off of the isValid private field
                textEle.style.display=this._isValid===false?"block":"none";
                }
        } 
    
      // set the onblur event for the text element
      this._element.onblur=Function.delegate(this,this.Validate);
    }
    
    //extend the string object to support checking for no values
    String.prototype.isNullOrEmpty=function(){
       return (this.length===0||this===null||this==="")?true:false;
    }
    
    //extend the function object to allow events to have references to the
    //class in which the event handler resides. i.e. maintain the "this" reference
    Function.prototype.delegate=function(instance,method){
        return function() {
                return method.apply(instance, arguments);
            }
        }
    
    Does that help? :D
     
  10. timduk

    timduk Private E-2

    Similar personal ethos - "Offence can only be taken, not given" - much like responsibility!

    Some of your comments were very helpful, thank you. Some were a little like my early attempts, which I call uber-comment-obfuscation, or "stbo" in short:

    // set the variable x to 10
    x = 10;
    // x now holds the value 10, add 1 to it
    x++;
    // x is now 11.

    Some pretty basic questions:

    Does this method check input dynamically field-by-field?
    What is the purpose of "Function-prototype-delegate"? - I know what you said, but I didn't understand it!

    The actual code is easy enough to understand, it's the concept of what you are doing and how you are accomplishing it which is difficult for me to grasp. :crybaby
     
  11. Kodo

    Kodo SNATCHSQUATCH

    well, somethings were self explanatory ;)

    Ok, so you declare an instance of the RequiredFieldValidator object for each text box that needs to be validated.
    eg:
    Code:
    var tb1val=null;
    window.onload=function(){
         tb1val=new RequiredFieldValidator(null,"TextBox1","*","tb1err","#ffe6e6");
        //tb1val=new RequiredFieldValidator(elementObject,elementId,ErrorText,ErrorTextDisplayElement,TextBoxBgColor);
     }
    
    I declared mine in the page load event. I could easily just tack on N number of declarations of the requiredFieldValidator object that "hook" up to a text box. The RequiredFieldValidator class is only referenced once by its inclusion into the page. So you can think of it as just kind of hanging above your application waiting for a new instance of it to be declared. I've tied it into the onblur event of the textbox so when you tab out of the textbox, it fires the Validate event on the validator object. Which brings me to your next question.

    in the requiredFieldValidator class I have this:
    Code:
     this._element.onblur=Function.delegate(this,this.Validate);
    typically you might do something like this:
    Code:
     this._element.onblur=this.Validate; 
    This attaches the event to the function Validate in the class, but not the class itself or rather, not the instance of the class. Because the function Validate is a first class object itself, the "THIS" reference in Validate function refers to the Validate function as the object and not the required field validator. I know that sounds confusing but basically I have the wrong reference to THIS and so I need to fix that so that I have the proper THIS reference. This is where the Function.delegate method comes into place.

    Code:
    Function.prototype.delegate=function(instance,method){
        return function() {
                return method.apply(instance, arguments);
            }
        }
    
    it takes an instance of the current object (RequireFieldValidator instance) and the method that is to be called (Validate) and "re-references" this to the RequiredFieldValidator instance by using the Apply() method (native JavaScript method) to combine the two in sort of a circular "THIS" reference. This is just one of those areas in javascript that will just "click" one day and the light will go on. It took me a LONG time to get the concept of how that worked no matter how many times it was explained to me. It only clicked after I was working with javascript on a large, 4 month, ajax adventure.
     
  12. PC-XT

    PC-XT Master Sergeant

    I like both ways. It depends on the circumstances which method I use. I often use different methods. The benefits of the objects are ok if you have good objects and resources to work with, but the old way still works, and can sometimes be better if you know what you're doing. These validation objects look very thought out. I like finding objects like that. Good job.
     
  13. Kodo

    Kodo SNATCHSQUATCH

    Works and done properly are different things to me. If I have 50 different form fields, and yes, that does happen, I am NOT going to use ||'s to figure out which one was invalid.
    With a little modification to my class, I can reduce the constructor code A LOT and make it even easier to use. i.e. passing in a JSON object for the parameters instead a list of params. I can base class this object too so I can make diff objects for the differing text values.
     
  14. timduk

    timduk Private E-2

    Agreed. Your elegant solution has obvious advantages for small and large scale projects, and any high maintenance project where different people are called to alter other peoples code.

    Thanks for your last but one post, which did help in understanding the concept, although the light is not fully on yet... :)

    Having said that, there are many such objects and functions in Java which I use naturally and repeatedly without worrying about HOW they work. All that's needed is the relevant class library and JavaDocs explaining what I need to know in order to implement it, together with a few examples of use in pseudo real-life situations.
     
  15. Kodo

    Kodo SNATCHSQUATCH

    that's what creating classes is all about; Abstraction and "black boxing".. right?

    the implementation is simple. You don't need to know how it works unless you want to change it. ;)

    if you know the textbox Id use this
    tb1val=new RequiredFieldValidator(null,"TextBox1","*","tb1err","#ffe6e6");

    if you have the DOM reference use this

    var tb1=document.getElementById("TextBox1");//textbox DOM reference
    tb1val=new RequiredFieldValidator(tb1,null,"*","tb1err","#ffe6e6");
     

MajorGeeks.Com Menu

Downloads All In One Tweaks \ Android \ Anti-Malware \ Anti-Virus \ Appearance \ Backup \ Browsers \ CD\DVD\Blu-Ray \ Covert Ops \ Drive Utilities \ Drivers \ Graphics \ Internet Tools \ Multimedia \ Networking \ Office Tools \ PC Games \ System Tools \ Mac/Apple/Ipad Downloads

Other News: Top Downloads \ News (Tech) \ Off Base (Other Websites News) \ Way Off Base (Offbeat Stories and Pics)

Social: Facebook \ YouTube \ Twitter \ Tumblr \ Pintrest \ RSS Feeds