dcsimg
www.webdeveloper.com
Results 1 to 13 of 13

Thread: making values from forms into global JS variables

  1. #1
    Join Date
    Jan 2008
    Location
    UK
    Posts
    12

    making values from forms into global JS variables

    Hey,

    I have very basic code that I am tinkering with as I learn new JS functions or techniques etc. So far I have:

    Code:
    <html>
    <head>
    <script type="text/javascript">
    function validate() //validate the form1 values
    {
    if (isNaN(document.form1.x.value) || isNaN(document.form1.y.value) || isNaN(document.form1.z.value))
    	{
    	alert("Please enter a value for x, y and z");
    	}
    else {
    radio_selection() //call the function
    }
    }
    </script>
    
    <script type="text/javascript">
    function radio_selection()
    {
    
    chosen = ""
    len = document.form1.r1.length
    
    //determine which radi button was checked
    for (i = 0; i <len; i++) {
    if (document.form1.r1[i].checked) {
    chosen = document.form1.r1[i].value
    }
    }
    
    if (chosen == "smallest number") {
    math_smallest()
    }
    else if (chosen== "largest number")  {
    math_largest() 
    }
    else if (chosen == "mean") {
    math_mean()
    }
    }
    
    </script>
    
    <script type="text/javascript">
    function math_largest()
    {
    a = Math.max(Number(document.form1.x.value),Number(document.form1.y.value))
    b = Math.max(Number(a),Number(document.form1.z.value))
    alert("The largest number of " + document.form1.x.value + ", " + document.form1.y.value + " and "+ document.form1.z.value + " is " + b);
    }
    
    </script>
    
    <script type="text/javascript">
    function math_smallest()
    {
    a = Math.min(Number(document.form1.x.value),Number(document.form1.y.value))
    b = Math.min(Number(a),Number(document.form1.z.value))
    alert("The smallest number of " + document.form1.x.value + ", " + document.form1.y.value + " and "+ document.form1.z.value + " is " + b);
    
    }
    </script>
    
    <script type="text/javascript">
    function math_mean()
    {
    	a = (Number(document.form1.x.value) + Number(document.form1.y.value) + Number(document.form1.z.value)); // find the sum of the values
    	b = Number(a/3);
    	c = Math.round(Number(b)*100)/100; //number rounded to the two decimal places
    	alert("The mean of " + document.form1.x.value + ", " + document.form1.y.value + " and "+ document.form1.z.value + " is " + c);
    }
    
    </script>
    </head>
    
    
    <body>
    
    <h3>Please Enter three numbers</h3>
    <form name="form1">
    <font>Number 1 &nbsp</font><input type="text" name="x" value="x" size="5"><br />
    <font>Number 2 &nbsp</font><input type="text" name="y" value="y" size="5""><br />
    <font>Number 3 &nbsp</font><input type="text" name="z" value="z"size="5"><br /><br />
    <input type="radio" name="r1" value="smallest number" onclick="validate()">Smallest Number
    <input type="radio" name="r1" value="largest number" onclick="validate()">Largest Number
    <input type="radio" name="r1" value="mean" onclick="validate()">The Mean
    </form>
    
    
    </body>
    </html>
    It is pretty basic. The user enters three numbers, x, y and z then clicks a radio button. That calls the validate function which checks the values are not null and are not numbers. If true an alert is displayed, else it calls the radio_selection function(). This works out which radio button was chosen then calls the appropriate function. The functions perform the calculations it is supposed too and then displays an alert. Easy, basic, simple!

    Now, I wanted to make document.form1.x.value a global variable that would be used in all the functions, rather than having to type it out long. So document.form1.x.value become x.

    I tried having all the functions within one script, and then adding x = document.form1.x.value for x, y and z, then followed by the functions. However, this didn't work, I just got no response when selecting a radio button.

    Does anyone have any ideas or helpful links to help me solve this?

  2. #2
    Join Date
    Nov 2003
    Location
    Worthington, OH, USA
    Posts
    3,636
    Just need to define it early and set the value afterward:
    HTML Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <script type="text/javascript">
    var x, y, z;
    
    function validate() //validate the form1 values
    {
    if (isNaN(document.form1.x.value) || isNaN(document.form1.y.value) || isNaN(document.form1.z.value))
    	{
    	alert("Please enter a value for x, y and z");
    	}
    else {
    	x = document.form1.x.value;
    	y = document.form1.y.value
    	z = document.form1.z.value;
    	radio_selection() //call the function
    }
    }
    
    function radio_selection()
    {
    
    chosen = ""
    len = document.form1.r1.length
    
    //determine which radi button was checked
    for (i = 0; i <len; i++) {
    if (document.form1.r1[i].checked) {
    chosen = document.form1.r1[i].value
    }
    }
    
    if (chosen == "smallest number") {
    math_smallest()
    }
    else if (chosen== "largest number")  {
    math_largest() 
    }
    else if (chosen == "mean") {
    math_mean()
    }
    }
    
    function math_largest()
    {
    a = Math.max(Number(x),Number(y))
    b = Math.max(Number(a),Number(z))
    alert("The largest number of " + x+ ", " + y + " and "+ z + " is " + b);
    }
    
    function math_smallest()
    {
    a = Math.min(Number(x),Number(y))
    b = Math.min(Number(a),Number(z))
    alert("The smallest number of " + x + ", " + y + " and "+ z + " is " + b);
    
    }
    
    function math_mean()
    {
    	a = (Number(x) + Number(y) + Number(z)); // find the sum of the values
    	b = Number(a/3);
    	c = Math.round(Number(b)*100)/100; //number rounded to the two decimal places
    	alert("The mean of " + x + ", " + y + " and "+ z + " is " + c);
    }
    
    </script>
    </head>
    
    
    <body>
    
    <h3>Please Enter three numbers</h3>
    <form name="form1">
    <font>Number 1 &nbsp</font><input type="text" name="x" value="x" size="5"><br />
    <font>Number 2 &nbsp</font><input type="text" name="y" value="y" size="5""><br />
    <font>Number 3 &nbsp</font><input type="text" name="z" value="z"size="5"><br /><br />
    <input type="radio" name="r1" value="smallest number" onclick="validate()">Smallest Number
    <input type="radio" name="r1" value="largest number" onclick="validate()">Largest Number
    <input type="radio" name="r1" value="mean" onclick="validate()">The Mean
    </form>
    
    
    </body>
    </html>
    54 68 65 42 65 61 72 4D 61 79

  3. #3
    Join Date
    Jan 2008
    Location
    UK
    Posts
    12
    Cheers, Bearmay, works a treat.

    I did the same thing except I had the variables before the function. so

    var x
    var y
    var z

    function validate ()

    can see why it didn't work now lol.

    Thanks!!

  4. #4
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Here's a function that creates global variables with a given name:
    Code:
    function set_var(name, value) {
      window[name] = value;
    }
    Then in your code for the FORM validation:
    Code:
    //validate the form1 values
    function validate() {
      var formEls = document.form1.elements;
      if (isNaN(formEls.x.value) || isNaN(formEls.y.value) || isNaN(formEls.z.value)) {
        alert("Please enter a value for x, y and z");
      } else {
        set_var( formEls.x.name, parseFloat(formEls.x.value) );
        set_var( formEls.y.name, parseFloat(formEls.y.value) );
        set_var( formEls.z.name, parseFloat(formEls.z.value) );
        radio_selection() //call the function
      }
    }
    I also added function calls to parseFloat to convert the form field values from strings to numbers. I assume they are numbers since isNaN is used to test them.

  5. #5
    Join Date
    Jan 2008
    Location
    UK
    Posts
    12
    Thanks toicontien, or is it toicantien? lol. I will keep hold of that script for future use if you don't mind.

    the variables were numbers, I used Number() to make sure they were handled as such.

    thanks, Mike

  6. #6
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774

  7. #7
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,527
    Um... sorry, toicontien, but I disagree with basically everything in your post here and the basic assumptions in your blog post.

    First, let's get an odd little monkey off our backs: All numbers in JavaScript are an object.
    This is wrong. A number is a primitive value in JavaScript. You can check the ECMA-262 standard, and you can also check right in JavaScript. typeof 4 returns "number", while typeof new Number(4) returns "object". So while there does exist a wrapper class called Number, there also exists a primitive number type.

    Actually, you really need to use the parseFloat function.
    I don't think it's a need at all. In fact, I think using the Number() function to do the conversion is better. If a user types in "1q234tryh", should we say they typed a numeric value of 1? Or should we say it isn't a number? Users sometimes try to type all sorts of things: "one hundred dollars", "$100", "100 dollars and 12 cents". parseInt and parseFloat will reject the first two, but they'll accept a value -- the wrong value -- from the third.

    Computers require very specific input, and if the user doesn't do that, then, rather than fudging it, I think it's better to just alert the user that they made a mistake, remind them how to do it correctly, and have them try again.
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  8. #8
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Quote Originally Posted by Jeff Mott
    This is wrong. A number is a primitive value in JavaScript. You can check the ECMA-262 standard, and you can also check right in JavaScript. typeof 4 returns "number", while typeof new Number(4) returns "object". So while there does exist a wrapper class called Number, there also exists a primitive number type.
    I'll need to ammend my blog post. I actually should have said all number variables are objects. A number literal is a primitive data type.

    Quote Originally Posted by Jeff Mott
    I don't think it's a need at all. In fact, I think using the Number() function to do the conversion is better. If a user types in "1q234tryh", should we say they typed a numeric value of 1? Or should we say it isn't a number? Users sometimes try to type all sorts of things: "one hundred dollars", "$100", "100 dollars and 12 cents". parseInt and parseFloat will reject the first two, but they'll accept a value -- the wrong value -- from the third.

    Computers require very specific input, and if the user doesn't do that, then, rather than fudging it, I think it's better to just alert the user that they made a mistake, remind them how to do it correctly, and have them try again.
    The Number, parseFloat, and parseInt functions provide varying levels of error correction. The parseFloat and parseInt functions strip non numeric characters after the numeric ones, assuming no non-numeric characters appear before the numeric ones. If the user accidentally types "4./7" (hitting both the "." and "/" keys on accident) the parseFloat function could recover from that user error. The Number function would not. It comes down to programmer preference, but I can see your point about requiring specific input.

    I also originally thought the isNaN function was the compliment to parseFloat and parseInt, but now realize it isn't. It is, in fact, the complimentary function to Number.

    So a couple things to ammend on my blog post:

    1) A number literal is a primitive data type.

    2) A number variable is an object, whose constructor is Number

    3) The isNaN function is the compliment of Number, not parseFloat and parseInt.

  9. #9
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,527
    I'll need to ammend my blog post. I actually should have said all number variables are objects. A number literal is a primitive data type.
    Even as a variable, a number literal is still a number literal.

    var x = 4;
    var y = new Number(4);

    alert(typeof x); // number
    alert(typeof y); // object


    If the user accidentally types "4./7" (hitting both the "." and "/" keys on accident) the parseFloat function could recover from that user error. The Number function would not.
    If the user intended to type 47 but mistakenly typed 4./7, then parseFloat would return 4, not 47. So the difference here between parseFloat and Number is that Number will alert you that something is wrong while parseFloat will silently let your program use the wrong value.

    I also originally thought the isNaN function was the compliment to parseFloat and parseInt, but now realize it isn't. It is, in fact, the complimentary function to Number.
    Since parseInt, parseFloat, and Number can all return NaN, I think I'd say that isNaN complements all three.
    Last edited by Jeff Mott; 01-16-2008 at 01:44 PM.
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  10. #10
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Quote Originally Posted by Jeff Mott
    Even as a variable, a number literal is still a number literal.
    And that's a hazy area of JavaScript:
    Code:
    var x = 4.546851;
    alert(x.toFixed(3));
    The ".toFixed" part is a function call of the Number class, therefore the variable x is an object. The typeof function is kind of a hack. Pretty much everything in JavaScript is an object based on a class of some sort. Even functions are objects. I think of the typeof function not determining what data type a variable is, but determining the object classification that variable falls into. Arrays return "object" when passed to typeof, and not "array". If you really wanted a strict detection of data type, you would need to test the constructor property of a variable:
    Code:
    function getType(x) {
      var type = "unknown";
      if (x.constructor) {
        switch (x.constructor) {
          
          case Number:    type = "number"; break;
          case String:    type = "string"; break;
          case Array:     type = "array"; break;
          case Object:    type = "object"; break;
          case Function:  type = "function"; break;
          default:        type = typeof(x); break;
          
        }
      } else {
        type = typeof(x);
      }
      return type;
    }
    And I'm assuming everything in JavaScript is an object based on some experience with C++. I don't remember integer variables in C++ having any properties or methods with them, as ints are truly primitive data types. They point to a memory address that contains a swath of data interpreted by the computer as an integer number.

    Quote Originally Posted by Jeff Mott
    If the user intended to type 47 but mistakenly typed 4./7, then parseFloat would return 4, not 47. So the difference here between parseFloat and Number is that Number will alert you that something is wrong while parseFloat will silently let your program use the wrong value.
    Correct. If that's a problem for your program and is something the user can't correct, then Number is the function to use.

    Quote Originally Posted by Jeff Mott
    Since parseInt, parseFloat, and Number can all return NaN, I think I'd say that isNaN complements all three.
    While all three functions can return a NaN value, they will return a NaN value under different circumstances. The same input that results in a NaN value from the Number function returns true when passed to the isNaN function, while there are cases where parseFloat and parseInt will return a number from a string when passing that string to isNaN will return true, meaning that string is not numeric.
    Code:
    var x = "4.7a";
    var y = "3.2";
    
    alert(isNaN(x) + "\n" + isNaN(y)); // Alerts true and false
    
    alert(Number(x) + "\n" + parseFloat(x)) // Alerts NaN and 4.7
    The string "4.7a" returns true when passed to isNaN even though passing "4.7a" to parseFloat returns a number. Passing "4.7a" to Number returns a NaN value, which makes me think isNaN is a direct compliment to Number. You could have a string tested against isNaN that returns true (it is not a number) when passing that string to parseFloat could return a number. Really it seems there are two main paths we can take when dealing with incorrect user numeric input:

    1) Use a strict test like isNaN and convert strings to numbers using the Number function.

    2) Strip out non numeric characters from the string, then pass it to the Number, parseFloat or parseInt functions to convert the string to a number.

    Method 1 is the strictest, and any non numeric input would generate an error, and it would force the user to only enter valid numeric characters. This is the programmer friendly method.

    Method 2 is the least strict and offers some error correction. This error correction, as Jeff mentioned earlier, could introduce an incorrect value to your program, but not an incorrect data type. If using method 2, which is the most user friendly, make sure your program checks the input to make sure it's a valid value. This is the user friendly method, as it provides some simple error correction.

    In either case, you've got to check for a valid value, then alert the user and give them a chance to correct their mistake. For instance, if your script requires a number 10 or less, you still need to check that value regardless of whether or not use use Number, parseFloat or parseInt to convert the string to a number.

    When converting strings to numbers, you can use two basic work flows:

    A) Test first, then convert

    A.1) Test the string with isNaN. If true is returned, alert the user to correct the error.

    A.2) If isNaN returns false, convert the string to a number using the Number function.

    B) Convert, then test

    B.1) Convert the string to a number using Number, parseFloat or parseInt.

    B.2) Test the resulting value with isNaN. If true is returned, alert the user and allow them to correct their error.

    Just out of curiosity Jeff, which method do you use? And I realize the two methods above are pretty generalized. I use both methods intermittently.

    Good discussion, however off topic it may have become. I'm learning more with each post.

  11. #11
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,527
    The ".toFixed" part is a function call of the Number class, therefore the variable x is an object.
    Not necessarily. Like you said, it's a hazy area. JavaScript lets Number class methods be available to number literals as well. What happens is JS creates a new temporary object from the literal and calls the method on that temp object.

    I tried to find the docs for you where I read it. So far I've found the behavior described for strings but not yet for numbers (http://developer.mozilla.org/en/docs...tring_Objects). I'll keep looking. In the mean time, here's the described behavior of calling String methods on a string literal:
    You can call any of the methods of the String object on a string literal value—JavaScript automatically converts the string literal to a temporary String object, calls the method, then discards the temporary String object. You can also use the String.length property with a string literal.

    The typeof function is kind of a hack.
    I can see how it'd be hard to make sense of if you didn't realize that numbers and strings could be literals. Maybe it'll make more sense now. This link has lots of examples: http://developer.mozilla.org/en/docs...ypeof_Operator

    Arrays return "object" when passed to typeof, and not "array".
    That's because JS doesn't have an array primitive value. All arrays in JS are objects.

    And I'm assuming everything in JavaScript is an object based on some experience with C++. I don't remember integer variables in C++ having any properties or methods with them, as ints are truly primitive data types.
    C++ and JavaScript are very different. Drawing conclusions about JS because of some behavior in C++ doesn't work out very well.

    Method 1 is the strictest, and any non numeric input would generate an error, and it would force the user to only enter valid numeric characters. This is the programmer friendly method.

    Method 2 is the least strict and offers some error correction. This error correction, as Jeff mentioned earlier, could introduce an incorrect value to your program, but not an incorrect data type. If using method 2, which is the most user friendly, make sure your program checks the input to make sure it's a valid value. This is the user friendly method, as it provides some simple error correction.
    I suppose this is a difference of perspective. Like in your example before where the user intends to enter 47 but parseFloat returns 4 -- I don't see that as error correction (the error isn't actually corrected), I see that as fudging the data so we can move forward without fixing the mistake.

    I also prefer method 1 not just as a programmer but also as a user. I've used software before where my typos are silently ignored and changed to something else. And then when the program doesn't work like it's supposed to, I don't have any idea why because I'm not even aware that I made a mistake. I end up wasting time double and triple checking my settings until I finally spot the bad value.

    So however you approach it, I think method 2 is just bad practice.

    When converting strings to numbers, you can use two basic work flows:

    Just out of curiosity Jeff, which method do you use?
    I use method B, convert then test, except I don't ever use parseInt or parseFloat. It's typically something like:
    Code:
    var someNumberEntry = Number( document.getElementById("someFormCtrl").value );
    if (isNaN(someNumberEntry )) {
    	// some kind of alert, perhaps jump to the form control and highlight in red
    	// might stop processing here also if further calculations depend on someNumberEntry
    }
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

  12. #12
    Join Date
    Feb 2003
    Location
    Michigan, USA
    Posts
    5,774
    Quote Originally Posted by Jeff Mott
    Not necessarily. Like you said, it's a hazy area. JavaScript lets Number class methods be available to number literals as well. What happens is JS creates a new temporary object from the literal and calls the method on that temp object.

    I tried to find the docs for you where I read it. So far I've found the behavior described for strings but not yet for numbers (http://developer.mozilla.org/en/docs...tring_Objects).
    I just gave it a quick read-through. Good stuff. Thanks for the link. I can only assume numbers would behave the same, but we know how good assuming is.

    The article you linked to described some functional differences between string literals and string objects. I wonder if we can find anything like that with numbers.



    Quote Originally Posted by Jeff Mott
    C++ and JavaScript are very different. Drawing conclusions about JS because of some behavior in C++ doesn't work out very well.
    True, but I was going off of syntax differences:
    Code:
    /* In C++ */
    int x = 10;
    
    /* I don't believe you can do x.anything. The variable x is simply a variable. */
    Code:
    /* In JavaScript */
    var x = 10;
    
    y = x.toString();
    If x is truly a primitive data type, then it must behave the same way as strings, where JavaScript temporarily converts the number literal to a number object. Since assigning a literal to a variable allows you to call methods of the Number object, I assumed the variable was an object, and not that JavaScript was temporarily converting the literal to an object. Sounds like a lot of extra work for JavaScript.

    Quote Originally Posted by Jeff Mott
    I suppose this is a difference of perspective. Like in your example before where the user intends to enter 47 but parseFloat returns 4 -- I don't see that as error correction (the error isn't actually corrected), I see that as fudging the data so we can move forward without fixing the mistake.

    I also prefer method 1 not just as a programmer but also as a user. I've used software before where my typos are silently ignored and changed to something else. And then when the program doesn't work like it's supposed to, I don't have any idea why because I'm not even aware that I made a mistake. I end up wasting time double and triple checking my settings until I finally spot the bad value.

    So however you approach it, I think method 2 is just bad practice.
    I can see where you're coming from. I like to allow users a little fudge room, where one keystroke won't throw a big error in their face. Perhaps the best method is to remove non numeric characters from a text box, for instance, while the user is typing them in using the onchange event. That way the user can see exactly what they are typing.

    Quote Originally Posted by Jeff Mott
    I use method B, convert then test, except I don't ever use parseInt or parseFloat. It's typically something like:
    Code:
    var someNumberEntry = Number( document.getElementById("someFormCtrl").value );
    if (isNaN(someNumberEntry )) {
    	// some kind of alert, perhaps jump to the form control and highlight in red
    	// might stop processing here also if further calculations depend on someNumberEntry
    }
    Looking back at how isNaN truly works, there doesn't seem to be much of a need for parseFloat or parseInt. I'm sure there are places where they are very useful, but not so much when gathering free-form text input from a user. In hindsight it seems isNaN and Number are enough.

    I wonder if there are any performance differences between number literals and number objects? It'd be cool to know if using new Number() over assigning a number to a variable has any benefits. If you were going to call a Number class method repeatedly on a variable, I wonder if you'd get better performance by creating a number object to begin with, rather than relying on JavaScript to temporarily convert a number literal to an object repeatedly.

  13. #13
    Join Date
    Jul 2003
    Location
    The City of Roses
    Posts
    2,527
    Since assigning a literal to a variable allows you to call methods of the Number object, I assumed the variable was an object, and not that JavaScript was temporarily converting the literal to an object.
    I agree, it's very unintuitive. It's good these things come with manuals, otherwise we'd never make sense out of them.
    for(split(//,'))*))91:+9.*4:1A1+9,1))2*:..)))2*:31.-1)4131)1))2*:3)"'))
    {for(ord){$i+=$_&7;grep(vec($s,$i++,1)=1,1..($_>>3)-4);}}print"$s\n";

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