Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 14 of 14
  1. #1
    New Coder
    Join Date
    Aug 2010
    Posts
    39
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Help to Wannabe JS Programmer... Please

    Hey,

    I am self-learning Javascript. I am going through an online course right now and I am roadblocked. I wish I had a teacher by my side at times. Despite viewing and reviewing the material, I just cannot get a good enough grasp to keep going with the course.

    The code below is aimed at forcing the user to enter valid valid information in input fields. Here are my questions in orange:

    Code:
    window.onload = initForms;
    
    function initForms() {
    	
    	for (var i=0; i< document.forms.length; i++) {
    		document.forms[i].onsubmit = function() {return validForm();}// I don't understant the syntax on the right side the the '='... Why do we need 'function ()'... why not '= validForm() instead?	
    	
    
    	}
    }
    
    
    function validForm() {
    	var allGood = true;
    	var allTags = document.getElementsByTagName("*");
    	
    
    	for (var i=0; i<allTags.length; i++) {
    		
    		if (!validTag(allTags[i])) {
    			allGood = false;
    		
    		}
    	}
    	return allGood;
    
    
    // from that point on, I am having a difficult time understanding the relations between the 2 functions	
    
    	function validTag(thisTag) {
    		var outClass = "";
    		var allClasses = thisTag.className.split(" ");
    	
    		for (var j=0; j<allClasses.length; j++) {
    			outClass += validBasedOnClass(allClasses[j]) + " ";
    			
    		}
    	
    		thisTag.className = outClass;
    	
    		if (outClass.indexOf("invalid") > -1) {
    			thisTag.focus();
    			if (thisTag.nodeName == "INPUT") {
    				thisTag.select();
    			}
    			return false;
    		}
    		return true;
    		
    		function validBasedOnClass(thisClass) {
    			var classBack = "";
    		
    			switch(thisClass) {
    				case "":
    				case "invalid":
    					break;
    				case "reqd":
    					if (allGood && thisTag.value == "") {
    						classBack = "invalid ";
    					}
    					classBack += thisClass;
    					break;
    				case "radio":				
    				case "email":
    					classBack += thisClass;
    					break;
    				default:
    					if (allGood && !crossCheck(thisTag,thisClass)) {
    						classBack = "invalid ";
    					}
    					classBack += thisClass;
    			}
    			return classBack;
    		}
    				
    		function crossCheck(inTag,otherFieldID) {
    			if (!document.getElementById(otherFieldID)) {
    				return false;
    			}
    			return (inTag.value == document.getElementById(otherFieldID).value);
    		}
    	}
    }
    Can someone out there put a smile on my face?

  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,620
    Thanks
    78
    Thanked 4,388 Times in 4,353 Posts
    document.forms[i].onsubmit = function() {return validForm();}
    // I don't understant the syntax on the right side the the '='
    ... Why do we need 'function ()'... why not '= validForm() instead?
    Well, if you did
    Code:
    	
        document.forms[i].onsubmit = validForm();
    That would *CALL* the validForm function *RIGHT THEN AND THERE* and store the RESULT of calling that function (presumably either true or false) into the onsubmit handler for the form. Which of course (a) doesn't do at all what you wanted and (b) would be invalid, because onsubmit needs a function *REFERENCE*.

    What you *COULD* do is this:
    Code:
        document.forms[i].onsubmit = validForm;
    The name of a function, alone, *IS* a reference to that function.

    But mainly it would work here because the rest of that code is brain-dead.

    If you truly *had* a page that had more than one form on it, that code would invoke validForm and have it check *ALL* the fields in *ALL* the forms on the page!!!

    SILLY! Useless! If you had a form for people to enter their username and password and a separate form for them to register (e.g, name, email, etc.), this idiotic code would make them fill in *BOTH* forms fully no matter which thing they wanted to do!

    Quite frankly, I don't understand how that code does any reasonable validation of user input, at all. For email, for example, it doesn't even *ATTEMPT* to see if the format of the input is a valid email address.

    If this code came from your online course materials, I'd have to seriously question the value of that course.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #3
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,620
    Thanks
    78
    Thanked 4,388 Times in 4,353 Posts
    What I would have expected, assuming a function that validates the fields in a *single* form, would have been something like this:
    Code:
    function initForms() {
    	for (var i=0; i< document.forms.length; i++) {
    		document.forms[i].onsubmit = function() {return validForm(this);}
    	}
    }
    function validForm( form )
    {
        for( var f = 0; f < form.fields.length; ++f )
        {
            var field = form.fields[f];
            ... and now code that looks at the type of field and/or the className ...
            ... and performs intelligent validation of the user's entry ...
        }
        return whatever;
    }
    Now, you see, (a) the validForm function really does work on a single form and (b) the syntax shown is needed in order to pass a reference (the this in the anonymous function) to the form whose onsubmit in turn invokes the validForm function.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #4
    New to the CF scene
    Join Date
    Dec 2010
    Posts
    8
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I like your explanation Old Pedant. I think all his worries must have been answered. Now not related to the post, what is that signature you have there? I laugh out my lungs after reading it. Do you really think old age and cunning do wins out over enthusiasm? Well nice one.

  • #5
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    18,037
    Thanks
    203
    Thanked 2,539 Times in 2,517 Posts
    Quote Originally Posted by JSJobs.us View Post
    Do you really think old age and cunning do wins out over enthusiasm? Well nice one.
    The correct quotation is “Old age and treachery will overcome youth and skill”

    A wealthy old lady decides to go on a photo safari in Africa, taking her faithful aged poodle named Cuddles, along for the company.

    One day the poodle starts chasing butterflies and before long, Cuddles discovers that she's lost. Wandering about, she notices a young leopard heading rapidly in her direction with the intention of having lunch. The old poodle thinks, "Oh, oh! I'm in deep trouble now!" Noticing some bones on the ground close by, she immediately settles down to chew on the bones with her back to the approaching cat. Just as the leopard is about to leap, the old poodle exclaims loudly, "Boy, that was one delicious leopard! I wonder if there are any more around here?"

    Hearing this, the young leopard halts his attack in mid-strike, a look of terror comes over him and he slinks away into the trees. "Whew!", says the leopard, "That was close! That old poodle nearly had me!"

    Meanwhile, a monkey who had been watching the whole scene from a nearby tree, figures he can put this knowledge to good use and trade it for protection from the leopard. So off he goes, but the old poodle sees him heading after the leopard with great speed, and figures that something must be up. The monkey soon catches up with the leopard, spills the beans and strikes a deal for himself with the leopard.

    The young leopard is furious at being made a fool of and says, "Here, monkey, hop on my back and see what's going to happen to that conniving canine!" Now, the old poodle sees the leopard coming with the monkey on his back and thinks, "What am I going to do now?", but instead of running, the dog sits down with her back to her attackers, pretending she hasn't seen them yet, and just when they get close enough to hear, the old poodle says: "Where's that damn monkey? I sent him off an hour ago to bring me another leopard!"

    Moral of this story..

    Don't mess with old farts...age and treachery will always overcome youth and skill! Bull**** and brilliance only come with age and experience!
    Last edited by Philip M; 12-23-2010 at 01:57 PM.

  • #6
    New Coder
    Join Date
    Aug 2010
    Posts
    39
    Thanks
    6
    Thanked 0 Times in 0 Posts
    Old Pedant,

    Thanks, I feel suddenly less lonely... You helped me in the past with my bilingual site which has turned out great.

    About the silliness of this code, I want to warn you that this code is just an introduction to a string of other course modules to show you form validation. Email validation comes up later.

    I have 1 more question for now:

    1) In that context:

    Code:
    function initForms() {
    	
    	for (var i=0; i< document.forms.length; i++) {
    		document.forms[i].onsubmit = function() {return validForm();}// I don't understant the syntax on the right side the the '='... Why do we need 'function ()'... why not '= validForm() instead?	
    	}
    Can you elaborate on passing a REFERENCE vs. passing a RESULT?

    I understand that passing a reference means assigning a temporary value to the onsubmit handler whereas passing a result means my onsubmit handler is 'changing or becoming' that value (which is not what I want). Is that correct?

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,620
    Thanks
    78
    Thanked 4,388 Times in 4,353 Posts
    Well, in other languages, you might say you are passing "pointer to the function". Hmmm...

    Okay, maybe an illustration will help:
    Code:
    <script type="text/javascript">
    function foo( from )
    {
        if ( from == null ) from = "unknown";
        document.write("foo was invoked from " + from);
        return 3.14159265;
    }
    var x = foo("x");
    document.write("<hr>after assigning foo() to x");
    
    var y = foo;
    document.write("<hr>after assigning foo() to y");
    
    var z = function() { foo("z"); }
    document.write("<hr>after assigning functon that in turn calls foo() to z");
    
    document.write("<hr>call y():"); y();
    
    document.write("<hr>call z():"); z();
    
    document.write("<hr>value of x is " + x);
    document.write("<hr>value of y is " + y);
    document.write("<hr>value of z is " + z);
    </script>
    I could have added in a line that did
    Code:
    x();
    but it would simply produce an error.

    Can you see the difference in all three of those assignments? Note how flexible JS is. You can even get it to tell you what the *contents* of a function are by simply writing out that function (which actually converts the function to a string, of course, for use by document.write).


    *********
    I understand that passing a reference means assigning a temporary value to the onsubmit handler
    I'm not clear why you think that the value is temporary. It's no more temporary than any other assignment. It stays in place until and unless changed. Assigning a reference of any kind to a variable (function reference, object reference, array reference) means that you just have one more way to reach the thing referred to. It's really no different than doing this:
    Code:
    <script type="text/javascript">
    var now = new Date();
    var then = now;
    now.setMonth(0);
    document.write( "<hr>now is " + now );
    document.write( "<hr>then is " + then );
    </script>
    Did you try that? Were you surprised? Just remember an object reference (and functions *ARE* objects in JavaScript!) is *NOT* the object itself. It's just a "handle" to the object. And you can have many, many handles to the same object.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    TheApprentice (12-23-2010)

  • #8
    New Coder
    Join Date
    Aug 2010
    Posts
    39
    Thanks
    6
    Thanked 0 Times in 0 Posts
    Old Pedant,

    I have studied your last reply for over an hour and admittingly, I am not quite finished... It's getting clearer but I feel that once it becomes perfectly clear to me, I will have gain some more insight into the workings of JavaScript.

    So thank you very much for that!

  • #9
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,620
    Thanks
    78
    Thanked 4,388 Times in 4,353 Posts
    I maybe should have added that in JavaScript you can *NOT* assign an *OBJECT* to a variable. You can never assign more than a reference to an object to a variable.

    Objects live out in object space, and you can have *references* to them, and you can make changes to the object BY WAY OF the references, but you can't "touch" an object directly.

    Note that JavaScript is not the only language with this restriction. Java and C# and VB.NET all share this. C++, on the other hand, *CAN* have a variable that holds an object. And believe it or not, that is the source of more errors than the capability is worth!
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    TheApprentice (12-29-2010)

  • #10
    New Coder
    Join Date
    Aug 2010
    Posts
    39
    Thanks
    6
    Thanked 0 Times in 0 Posts
    Now THAT was a very valuable input Old Pedant. Thank you very much and Happy New Year!

  • #11
    New Coder
    Join Date
    Aug 2010
    Posts
    39
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Help with that part would be appreciated

    Old Pedant, or anyone else as brilliant as him,

    I have been trying to better understand the way forms work in connection with JavaScript for a while and I am almost there... I am struggling to understand the bottom part

    Can someone answer my comments next to some of the code below? Cheers
    For more code connected to this see the beginning of this thread.

    Code:
    function validBasedOnClass(thisClass) {
    			var classBack = "";
    		
    			switch(thisClass) {
    				case "": // Does that   mean nothing was entered in the form field so the class is empty?
    
    case "invalid":  
    // How can the class be invalid before we set it to be so? Examples?					break;
    				case "reqd":
    					if (allGood && thisTag.value == "") {
    						classBack = "invalid "; // Does this mean that JavaScript will set a form field class to 'invalid' if a particular tag is valid BUT nothing is entered in the field?					}
    					classBack += thisClass;
    					break;
    				case "radio":				
    				case "email":
    					classBack += thisClass;
    					break;
    				default:
    					if (allGood && !crossCheck(thisTag,thisClass)) {
    						classBack = "invalid ";
    					}
    					classBack += thisClass;
    			}
    			return classBack;
    		}

  • #12
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,620
    Thanks
    78
    Thanked 4,388 Times in 4,353 Posts
    > case "": // Does that mean nothing was entered in the form field so the class is empty?

    Ummm...what is entered into the form field does not *DIRECTLY* affect the className of the field. Only this (ugly) code that inspects the contents of the form field will *THEN* (possibly) change the className.

    So that simply means that the field was not initially assigned any className and/or it was changed from having a className to not having one by previous JS code.

    > case "invalid": // How can the class be invalid before we set it to be so?

    Easy: I coded <input class="invalid" name="foo">.

    But that's pretty unlikely. Much more likely we are simply coming *BACK* to this validation code (the validation failed the first time so now the user has hit SUBMIT *again* and we have to check again) and *THIS VERY CODE* set it to "invalid" the first time through. (Or this is the 5th time and it was set on the 4th time, or...)

    > classBack = "invalid "; // Does this mean that JavaScript will set a form field class to 'invalid'
    > // if a particular tag is valid BUT nothing is entered in the field?

    Or if there is something else wrong with the data entry, presumably. Maybe the user entered "xyz" as an email address? Or "123" as a phone number? The code you showed isn't testing that kind of stuff, YET, but of course any validator worth bothering with would.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • Users who have thanked Old Pedant for this post:

    TheApprentice (12-30-2010)

  • #13
    New Coder
    Join Date
    Aug 2010
    Posts
    39
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Last Question Old Pedant

    Old Pedant, see the question in yellow and red within the code below...

    Code:
    window.onload = initForms;
    
    function initForms() {
    	
    	for (var i=0; i< document.forms.length; i++) {
    		document.forms[i].onsubmit = function() {return validForm();}// I don't understant the syntax on the right side the the '='... Why do we need 'function ()'... why not '= validForm() instead?	
    	
    
    	}
    }
    
    
    function validForm() {
    	var allGood = true;
    	var allTags = document.getElementsByTagName("*");
    	
    
    	for (var i=0; i<allTags.length; i++) {
    		
    		if (!validTag(allTags[i])) {
    			allGood = false;
    		
    		}
    	}
    	return allGood;
    
    
    // from that point on, I am having a difficult time understanding the relations between the 2 functions	
    
    	function validTag(thisTag) {
    		var outClass = "";
    		var allClasses = thisTag.className.split(" ");
    	
    		for (var j=0; j<allClasses.length; j++) {
    			outClass += validBasedOnClass(allClasses[j]) + " ";
    			
    		}
    	
    		thisTag.className = outClass;
    	
    		if (outClass.indexOf("invalid") > -1) {
    			thisTag.focus();
    			if (thisTag.nodeName == "INPUT") {
    				thisTag.select();
    			}
    			return false;
    		}
    		return true;
    		
    		function validBasedOnClass(thisClass) {
    			var classBack = "";
    		
    			switch(thisClass) {
    				case "":
    				case "invalid":
    					break;
    				case "reqd":
    					if (allGood && thisTag.value == "") // why do we need to test allGood to be true? Just making sure that this.Tag.value is empty isn't enough? How can the thisTag.value be empty and allGood false at the same time? Please illustrate...{
    						classBack = "invalid ";
    					}
    					classBack += thisClass;
    					break;
    				case "radio":				
    				case "email":
    					classBack += thisClass;
    					break;
    				default:
    					if (allGood && !crossCheck(thisTag,thisClass)) {
    						classBack = "invalid ";
    					}
    					classBack += thisClass;
    			}
    			return classBack;
    		}
    				
    		function crossCheck(inTag,otherFieldID) {
    			if (!document.getElementById(otherFieldID)) {
    				return false;
    			}
    			return (inTag.value == document.getElementById(otherFieldID).value);
    		}
    	}
    }

  • #14
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,620
    Thanks
    78
    Thanked 4,388 Times in 4,353 Posts
    First of all, PLEASE never use yellow again. I had to copy/paste your code into notepad to get rid of the color in order to see it.

    Secondly, please understand that I don't *LIKE* this code, so you are asking me to explain why the doofus who wrote it did what he did. Hell, for all you (or I) know, it's total trash and there isn't any explanation.

    But having said that...

    if (allGood && thisTag.value == "")
    // why do we need to test allGood to be true?
    Just making sure that this.Tag.value is empty isn't enough?
    How can the thisTag.value be empty and allGood false at the same time?
    Please illustrate...

    I think you have the concept backwards: You need to read that again.

    If allGood is false, then it DOES NOT MATTER what thisTag.value is! The code following this if will *NOT* be executed when allGood is false. Period.

    In other words, the code is saying "don't bother to check thisTag.value *unless* allGood is still true".

    To me, that entire function was written in the most confusing way possible.

    Here's one way to rewrite it:
    Code:
        function validBasedOnClass(thisClass) 
        {
            switch(thisClass) 
            {
                case "":
                case "invalid":
                    return "";
    			
                case "reqd":
                    if (allGood && thisTag.value == "") return "invalid " + thisClass;
                    else                                return thisClass;
    
                case "radio":				
                case "email":
                    return thisClass;
    
                default:
                    if (allGood && !crossCheck(thisTag,thisClass)) return "invalid " + thisClass;
                    else                                           return thisClass;
            }
        }
    I'm not sure what you are supposed to be learning from this code, unless it is "How to write obscure code!"

    EDIT: Make that "How to write obscure code that doesn't do anything worthwhile!"
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.


  •  

    Posting Permissions

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