SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 36
  1. #1
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)

    JavaScript Addition Calculator Help

    Good evening guys and girls! (At least it's evening time where I am in the world.)

    I'm pretty good at creating JS scripts that use inline JS however, this is totally wrong, evil and can sometimes bring about an apocalypse! I don't want any of this

    I've been learning Unobtrusive DOM Scripting and all that lovely stuff But I still sometimes struggle with creating unobtrusive scripts!

    I want a simple (and I know how simple it is because I know a fair bit of beginners JS and this is super simple stuff, especially for you masters of the language!) script that adds two numeric values together which provide a total. So simply put: 1 + 1 = 2.

    Here is the working, evil script I currently have (and feel free to give it the evil eye, I do!):

    Code HTML4Strict:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    		<title>JavaScript Calculator: Addition</title>
    		<link rel="stylesheet" type="text/css" media="screen" href="stylesheet.css">
    		<script type="text/javascript">
    			function fnTotal(a,b) {
    				alert(fnAdd(a,b));
    			}
     
    			function fnAdd(c,d) {
    				return(parseInt(c)+parseInt(d));
    			}
    		</script>
    	</head>
     
    	<body>
    		<div id="wrapper">
    			<h1>JavaScript Calculator: Addition</h1>
     
    			<p>Use the JavaScript calculator below to add two numbers together from the two text boxes.</p>
     
    			<input type="text" name="firstNum">
    			<input type="text" name="secondNum">
    			<input type=button value="Add" onClick="fnTotal(firstNum.value,secondNum.value)">
    		</div>
    	</body>
    </html>

    That works (at least in IE8 and FF3, so I assume, although I shouldn't, that it works in most other modern browsers) but it isn't what I want. It's totally wrong and bad and -whacks it-

    This is the new and lovely addition.html I have:

    Code HTML4Strict:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    		<title>JavaScript Calculator: Addition</title>
    		<link rel="stylesheet" type="text/css" media="screen" href="stylesheet.css">
    		<script type="text/javascript" src="addition.js"></script>
    	</head>
     
    	<body>
    		<div id="wrapper">
    			<h1>JavaScript Calculator: Addition</h1>
     
    			<p>Use the JavaScript calculator below to add two numbers together from the two text boxes.</p>
     
    				<input type="text" id="firstNum" name="firstNum">
    				<input type="text" id="secondNum" name="secondNum">
    				<input type="button" value="Add" id="add">
    		</div>
    	</body>
    </html>

    And this is the weird external addition.js JavaScript file that seems to be giving me some problems!

    Code JavaScript:
    function addLoadEvent(func) {
    	var oldonload = window.onload;
    	if (typeof window.onload != 'function') {
    		window.onload = func;
    	} else {
    		window.onload = function() {
    			oldonload();
    			func();
    		}
    	}
    }
     
    function addition() {
    	if (!document.getElementById) return false;
     
    	var c = document.getElementById("firstNum");
    	var d = document.getElementById("secondNum");
    	var add = document.getElementById("add");
     
    	add.onclick = function() {
    		// return (parseInt(c) + parseInt(d));
    		// alert(parseInt(c) + parseInt(d));
    		// Your Solution Here? Pretty Please! :D
    	}
    }
     
    addLoadEvent(addition);

    I've checked in Dreamweaver CS3 to see if there are any problems - Nope. I don't get any errors in IE8 or in FF3 Error Console. When I type in 1 in the first text box and 1 in the second text box and then click on the Add button I just receive NaN. I know NaN = Not a Number but I can't figure out what to do to fix it.

    I've commented out the first two statements that begin with return and alert. And below that you can see a place where I'd love to fit your working solution in I'd like an explanation please too! Or if I'm very close to a solution, I obviously need help in seeing where I've made an error

    Help, pretty please?

    Andrew Cooper

  2. #2
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,037
    Mentioned
    152 Post(s)
    Tagged
    2 Thread(s)
    You need to do a parseInt on c.value and d.value, not on c and d

    So:

    Code JavaScript:
    add.onclick = function() {
       alert(parseInt(c.value) + parseInt(d.value));
       return (parseInt(c.value) + parseInt(d.value));
    }

    Also, if you use return in a function, the rest of that function is not executed. So you first need to do alert()s and then return, not the other way around, because that way you'll never actually see your alerts

  3. #3
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    You need to do a parseInt on c.value and d.value, not on c and d

    So:

    Code JavaScript:
    add.onclick = function() {
       alert(parseInt(c.value) + parseInt(d.value));
       return (parseInt(c.value) + parseInt(d.value));
    }

    Also, if you use return in a function, the rest of that function is not executed. So you first need to do alert()s and then return, not the other way around, because that way you'll never actually see your alerts
    Oh god...I was actually thinking it might have something to do with needing a .value somewhere! But I just didn't do it... But thank you so much! That has been wracking my brain for so damn long!

    And thanks for the information on using return and alert in a function together. It was just for testing because it's what we use to do in college. I've changed the script to the following.

    Code HTML4Strict:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    		<title>JavaScript Calculator: Addition</title>
    		<link rel="stylesheet" type="text/css" media="screen" href="stylesheet.css">
    		<script type="text/javascript" src="addition.js"></script>
    	</head>
     
    	<body>
    		<div id="wrapper">
    			<h1>JavaScript Calculator: Addition</h1>
     
    			<p>Use the JavaScript calculator below to add two numbers together from the two text boxes.</p>
     
    				<input type="text" id="firstNum" name="firstNum">
    				<input type="text" id="secondNum" name="secondNum">
    				<input type="button" value="Add" id="add">
     
    			<p id="answer"></p>
    		</div>
    	</body>
    </html>

    And the amended external JavaScript file:

    Code JavaScript:
    function addLoadEvent(func) {
    	var oldonload = window.onload;
    	if (typeof window.onload != 'function') {
    		window.onload = func;
    	} else {
    		window.onload = function() {
    			oldonload();
    			func();
    		}
    	}
    }
     
    function addition() {
    	if (!document.getElementById) return false;
     
    	var c = document.getElementById("firstNum");
    	var d = document.getElementById("secondNum");
    	var add = document.getElementById("add");
    	var answer = document.getElementById("answer");
     
    	add.onclick = function() {
    		answer.innerHTML = (parseInt(c.value) + parseInt(d.value));
    	}
    }
     
    addLoadEvent(addition);

    Any suggestions or ideas on how to improve any of the HTML or JS code at all (to make it cleaner or more efficient or something)? I'd like to expand on this by eventually creating a JS Calculator performing simple mathematical functions like addition, subtraction, multiplication, and division at first and then perhaps create some functions for it to do some scientific and statistical calculations. So we'll see where that goes.

    Thanks for the prompt reply with the great explanation and solution! I can't thank you enough!

    Andrew Cooper

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Move the "var c" and "var d" and "var answer" lines into the onclick event, and use the radix parameter with parseInt as well, and you should be right.

    Code javascript:
    add.onclick = function() {
        var c = document.getElementById("firstNum");
        var d = document.getElementById("secondNum");
        var answer = document.getElementById("answer");
        answer.innerHTML = (parseInt(c.value, 10) + parseInt(d.value, 10));
    }

    Alternatively, you can use the Number object instead.

    Code javascript:
    ...
    answer.innerHTML = (Number(c.value) + Number(d.value));
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    Move the "var c" and "var d" and "var answer" lines into the onclick event, and use the radix parameter with parseInt as well, and you should be right.

    Code javascript:
    add.onclick = function() {
        var c = document.getElementById("firstNum");
        var d = document.getElementById("secondNum");
        var answer = document.getElementById("answer");
        answer.innerHTML = (parseInt(c.value, 10) + parseInt(d.value, 10));
    }
    But what if I'm adding a function for subtraction, multiplication, and division? Couldn't I do the following?

    Code JavaScript:
    function calculator() {
    	if (!document.getElementById) return false;
     
    	var c = document.getElementById("firstNum");
    	var d = document.getElementById("secondNum");
    	var add = document.getElementById("add");
    	var subtract = document.getElementById("subtract");
    	var multiply = document.getElementById("multiply");
    	var divide = document.getElementById("divide");
    	var answer = document.getElementById("answer");
     
    	add.onclick = function() {
    		answer.innerHTML = (parseInt(c.value, 10) + parseInt(d.value, 10));
    	}
     
    	subtract.onclick = function() {
    		answer.innerHTML = (parseInt(c.value, 10) - parseInt(d.value, 10));
    	}
     
    	multiply.onclick = function() {
    		answer.innerHTML = (parseInt(c.value, 10) * parseInt(d.value, 10));
    	}
     
    	divide.onclick = function() {
    		answer.innerHTML = (parseInt(c.value, 10) / parseInt(d.value, 10));
    	}
    }

    Wouldn't that be more efficient by not repeating all of the variable declarations? Or is there a particular reason as to why you suggested placing all the variable declarations inside the add.onclick function? Otherwise it's an awful lot of repetition isn't it?

    I understand why you suggested to place the radix parameter too! Thanks! I should have thought about that but I'll be honest and say I didn't really know about it until you suggested it. Thanks for teaching me something new though!

    Quote Originally Posted by pmw57 View Post
    Alternatively, you can use the Number object instead.

    Code javascript:
    ...
    answer.innerHTML = (Number(c.value) + Number(d.value));
    Heh, didn't know about this either! What's the difference between parseInt and Number then? I mean, I can see that by using the Number object you don't need to include the radix parameter? Or is that wrong? What would you suggest / prefer? Number or parseInt? Or are they both as good as each other?

    Thanks a lot to both of you ScallioXTX and pmw57

    Andrew Cooper

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    Or is there a particular reason as to why you suggested placing all the variable declarations inside the add.onclick function?
    Then you could either pass them to the function, or perhaps more appropriately here, have the function reach out to a global register. The intention is to limit the function's reliance in large numbers of global variables.

    Quote Originally Posted by AndrewCooper View Post
    What's the difference between parseInt and Number then? I mean, I can see that by using the Number object you don't need to include the radix parameter? Or is that wrong? What would you suggest / prefer? Number or parseInt? Or are they both as good as each other?
    parseInt is the only function that uses the radix parameter. The parseInt function converts the value to an integer, which ends up rounding down 2.56 to 2

    The Number constructor converts whatever is entered in to a valid number. It can accept any valid number, whether that be 2.56, or even 256e-2

    You may want to check though that the values of c and d are valid numbers (using isNaN) before using them.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    parseInt converts the string to an integer (any base between 2 and 36) discarding any trailing non-numerics

    parseFloat does the same but also allows for fractions after the point (still any base between 2 and 36)

    in both of the above not specifying the second parameter will result in the number being assumed to be base 16 if it starts with 0x, base 8 if it starts with 0 or base 10 if it starts with anything else.

    Number() converts a string to a number but will return NaN if the entire field isn't a number.

    other ways to convert to a number inclide:

    num-0
    num*1
    num/1
    +num
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  8. #8
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    Then you could either pass them to the function, or perhaps more appropriately here, have the function reach out to a global register. The intention is to limit the function's reliance in large numbers of global variables.
    Sorry but I've read this around 8 times or so and I still don't understand what you're saying here. Could you rephrase what you said or make it simpler please?

    Quote Originally Posted by pmw57 View Post
    parseInt is the only function that uses the radix parameter. The parseInt function converts the value to an integer, which ends up rounding down 2.56 to 2

    The Number constructor converts whatever is entered in to a valid number. It can accept any valid number, whether that be 2.56, or even 256e-2
    I understand what you're saying here though and this is crucial information! I obviously want to be able to use decimal numbers in my calculator and not have it round up / down! I've decided to change to the Number constructor so I can do calculations such as 1.5 + 1.5 = 3

    Code JavaScript:
    	add.onclick = function() {
    		answer.innerHTML = (Number(c.value) + Number(d.value));
    	}

    It's also less code too which I would imagine makes it better because it saves more bytes?

    Quote Originally Posted by pmw57 View Post
    You may want to check though that the values of c and d are valid numbers (using isNaN) before using them.
    Don't understand this. How would I do this?

    Quote Originally Posted by felgall View Post
    parseInt converts the string to an integer (any base between 2 and 36) discarding any trailing non-numerics

    parseFloat does the same but also allows for fractions after the point (still any base between 2 and 36)

    in both of the above not specifying the second parameter will result in the number being assumed to be base 16 if it starts with 0x, base 8 if it starts with 0 or base 10 if it starts with anything else.

    Number() converts a string to a number but will return NaN if the entire field isn't a number.

    other ways to convert to a number inclide:

    num-0
    num*1
    num/1
    +num
    Thanks for the extra information felgall

    Andrew Cooper

    PS: I know I said this was a simple script...But I guess really I'm not qualified to say such a thing. On a scale of 1 - 10, what would you rate this calculator script? 1 being a simple alert message and 10 being something super-advanced and complicated like a game or animation (or is there more complicated / advanced JS scripts out there?)

  9. #9
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    PS: I know I said this was a simple script...But I guess really I'm not qualified to say such a thing. On a scale of 1 - 10, what would you rate this calculator script? 1 being a simple alert message and 10 being something super-advanced and complicated like a game or animation (or is there more complicated / advanced JS scripts out there?)
    It is a simple script. It would have to be either a 1 or at most a 2.

    Those complicated game and animation scripts you mention would probably rate about a 6 or 7 to leave room for the more complicated JavaScripts.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  10. #10
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by felgall View Post
    It is a simple script. It would have to be either a 1 or at most a 2.

    Those complicated game and animation scripts you mention would probably rate about a 6 or 7 to leave room for the more complicated JavaScripts.
    Heh, I feel so terribly newbie! But we all must start somewhere!

    What type of script would you rate as a solid 10?

    Also, when I try 1.5 + 1.5 I get 3 as the answer, which is correct. On the other hand when I try 1.5 * 2.5 I get 4 as the answer, which is wrong, as I should receive 3.75 as the answer, shouldn't I? Yet if I try 1.5 * 3 I receive 4.5 as the answer, which is correct.

    Help please?

    Andrew Cooper

  11. #11
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    Also, when I try 1.5 + 1.5 I get 3 as the answer, which is correct. On the other hand when I try 1.5 * 2.5 I get 4 as the answer, which is wrong, as I should receive 3.75 as the answer, shouldn't I? Yet if I try 1.5 * 3 I receive 4.5 as the answer, which is correct.
    Try 6 * 1 and you should get 7, which indicates that the add operation is being performed instead.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  12. #12
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    On the other hand when I try 1.5 * 2.5 I get 4 as the answer, which is wrong, as I should receive 3.75 as the answer, shouldn't I? Yet if I try 1.5 * 3 I receive 4.5 as the answer, which is correct.
    Exactly what does your code look like that is doing the multiplication.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  13. #13
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    Try 6 * 1 and you should get 7, which indicates that the add operation is being performed instead.
    Quote Originally Posted by felgall View Post
    Exactly what does your code look like that is doing the multiplication.
    Oh deary me! I knew something wasn't quite right...I'm so stupid...I didn't even check my code! All of the operators were + rather than +, -, *, / which is what they are now and everything is running smoothly when I get the answer

    I've just had a glass of wine though, is that a good enough excuse for the carelessness?

    What about the issue with the rephrasing of your statement pmw57, and help with understanding what you mean about wanting to check that the values of c and d are valid numbers (using isNaN) before using them?

    Thanks for the help guys! Really appreciated!

    Andrew Cooper

  14. #14
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    Sorry but I've read this around 8 times or so and I still don't understand what you're saying here. Could you rephrase what you said or make it simpler please?
    Functions are at their most stable when their proper working relies on as few assumptions as possible. That is achieved by the function relying on values that are passed to them, or on well known assumptions such as other functions, or object such as the document object.

    With the calculator project, the add() function makes assumptions that answer, c, and d exist in some manner.

    A more stable solution could be to call an update function, and pass it a function that performs the calculations.

    Code add:
    function add() {
        var add = function (c, d) {
            return c + d;
        };
        update(add);
    }
    function update(func) {
        var cInput = ...,
            dInput = ...,
            answer = ...,
            c = Number(cInput.value) || 0,
            d = Number(dInput.value) || 0;
        answer.innerHTML = func(c, d);
    }

    Quote Originally Posted by AndrewCooper View Post
    Don't understand this. How would I do this?
    You can use isNaN(c) to check if the value of c is a number. If it's not, you can assign a replacement number, such as 0 instead.

    Code javascript:
    c = Number(cInput.value);
    if (isNaN(c)) {
        c = 0;
    }

    You can also use what is known of as a "default operator" to do the same job.

    Code javascript:
    c = Number(cInput.value) || 0;

    You'll see that technique used in the earlier script example.

    Edit:

    Quote Originally Posted by AndrewCooper View Post
    What about the issue with the rephrasing of your statement pmw57, and help with understanding what you mean about wanting to check that the values of c and d are valid numbers (using isNaN) before using them?
    Working on it as you speak.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  15. #15
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    What type of script would you rate as a solid 10?
    The jQuery library is perhaps getting up toward the 10 end of the range.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  16. #16
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by felgall View Post
    The jQuery library is perhaps getting up toward the 10 end of the range.
    How about Yahoo's YUI library. I know that it's not as popular here as jQuery, but would YUI be in advance of jQuery by a point or two?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  17. #17
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,789
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    Quote Originally Posted by pmw57 View Post
    How about Yahoo's YUI library. I know that it's not as popular here as jQuery, but would YUI be in advance of jQuery by a point or two?
    I haven't really looked at either library all that closely but the libraries are definitely the types of scripts at the top end of the range with the ones closest to being a 10 being the ones that can do the most with the least amount of code (while being totally unobtrusive).

    Most of the actual scripts you see in web pages would only use a small fraction of the code that those libraries make available and so would be far simpler than a library if you only include the actual code that is needed.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  18. #18
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    Functions are at their most stable when their proper working relies on as few assumptions as possible. That is achieved by the function relying on values that are passed to them, or on well known assumptions such as other functions, or object such as the document object.
    Ok, I think I understand this. It makes it easier for functions to work more reliably if they can find things more easily. Or something along the lines.

    Quote Originally Posted by pmw57 View Post
    A more stable solution could be to call an update function, and pass it a function that performs the calculations.

    Code add:
    function add() {
        var add = function (c, d) {
            return c + d;
        };
        update(add);
    }
    function update(func) {
        var cInput = ...,
            dInput = ...,
            answer = ...,
            c = Number(cInput.value) || 0,
            d = Number(dInput.value) || 0;
        answer.innerHTML = func(c, d);
    }
    Ok, I tried editing my JS code to reflect this solution and this is the JS code I now have and it doesn't work for addition or any others:

    Code JavaScript:
    function addLoadEvent(func) {
    	var oldonload = window.onload;
    	if (typeof window.onload != 'function') {
    		window.onload = func;
    	} else {
    		window.onload = function() {
    			oldonload();
    			func();
    		}
    	}
    }
     
    function calculator() {
    	if (!document.getElementById) return false;
     
    	function update(func) {
    		var firstNum = document.getElementById("firstNum"),
    		    secondNum = document.getElementById("secondNum"),
    		    answer = document.getElementById("answer"),
    		    a = Number(firstNum.value) || 0,
    		    b = Number(secondNum.value) || 0;
     
    		answer.innerHTML = function(a, b);
    	}
     
    	add.onlick = function() {
    		var add = function(a, b) {
    			return a + b;
    		};
    		update(add);
    	}
     
    	// function add() {
    	//	var add = function(a, b) {
    	//		return a + b;
    	//	};
    	//	update(add);
    	// }
     
    	function subtract() {
    		var subtract = function(a, b) {
    			return a - b;
    		};
    		update(subtract);
    	}
     
    	function multiply() {
    		var multiply = function(a, b) {
    			return a * b;
    		};
    		update(multiply);
    	}
     
    	function divide() {
    		var divide = function(a, b) {
    			return a / b;
    		};
    		update(divide);
    	}
     
    }
     
    addLoadEvent(calculator);

    Any help here please?

    Quote Originally Posted by pmw57 View Post
    You can use isNaN(c) to check if the value of c is a number. If it's not, you can assign a replacement number, such as 0 instead.

    Code javascript:
    c = Number(cInput.value);
    if (isNaN(c)) {
        c = 0;
    }

    You can also use what is known of as a "default operator" to do the same job.

    Code javascript:
    c = Number(cInput.value) || 0;

    You'll see that technique used in the earlier script example.
    I'll use the default operator method. I'll assume that the default operator method is the better method to use because it is less typing (meaning less bytes)?

    Thanks for the help on this Paul and Stephen, it's really appreciated. A lot of the JavaScript books I have don't cover numbers. I figured that creating a simple calculator script would be a good beginners project but it seems there is more to it than the basic beginners knowledge, despite this being a newbie / beginnger script.

    Andrew Cooper

  19. #19
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    There are a couple of issues, one that you introduced, and one from me too.

    When the answer is calculated, it should call the func object that was passed in to the update function. Where you renamed func(a, b) to function(a, b), please change it back to func(a, b)

    Code javascript:
    function update(func) {
        ...
        answer.innerHTML = func(a, b);
    }

    The other issue is my fault. Please change onlick to onclick. Sorry
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  20. #20
    SitePoint Guru bronze trophy AndrewCooper's Avatar
    Join Date
    Sep 2008
    Location
    Manchester, UK
    Posts
    631
    Mentioned
    10 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    There are a couple of issues, one that you introduced, and one from me too.
    Heh. I changed func(a, b) to function(a, b) because I didn't see anywhere where this was referenced. It was referenced as a parameter to the update function, right?

    Quote Originally Posted by pmw57 View Post
    When the answer is calculated, it should call the func object that was passed in to the update function.
    Paul, I can bet you're probably calling me all sorts of names right now (or maybe not, I probably would be) but I kind of don't understand. I think it's because you used the word object and I don't know anything about objects right now, or maybe I do but I don't realise what objects are. I understand that answer.innerHTML = func(a, b); is a reference to the parameter function update(func) here and that's about it. But I don't understand what this is doing and how it is doing it. Could you explain this please?

    Quote Originally Posted by pmw57 View Post
    The other issue is my fault. Please change onlick to onclick. Sorry
    Actually, that was my fault, so don't apologise! The code you gave me was:

    Code JavaScript:
    function add() {
        var add = function (c, d) {
            return c + d;
        };
        update(add);
    }
    function update(func) {
        var cInput = ...,
            dInput = ...,
            answer = ...,
            c = Number(cInput.value) || 0,
            d = Number(dInput.value) || 0;
        answer.innerHTML = func(c, d);
    }

    I amended that to include the add.onclick but it turned out to be add.onlick - Clearly a typo from me because if there is at least one thing I know about JavaScript it's that it doesn't lick anything!

    Thanks again for the code help and explanations, I really appreciate it.

    Andrew Cooper

  21. #21
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by AndrewCooper View Post
    but I kind of don't understand. I think it's because you used the word object and I don't know anything about objects right now, or maybe I do but I don't realise what objects are. I understand that answer.innerHTML = func(a, b); is a reference to the parameter function update(func) here and that's about it. But I don't understand what this is doing and how it is doing it. Could you explain this please?
    Here is the code that creates the add variable and passes it to the update function.

    Code javascript:
    var add = function (c, d) {
        return c + d;
    };
    update(add);

    That could also be done without creating the add variable, by passing the function directly to the update function.

    Code javascript:
    update(function (c, d) {
        return c + d;
    });

    In both cases, the function that does the adding is an anonymous function.
    The anonymous function is created by using a function expression, which is different from the typical functions that you normally deal with which are created by using a function statement.

    Here is a function created using the function statement, and one created using the function expression.

    Code javascript:
    // function statement
    function foo(bar) {
        ...
    }
     
    // function expression
    var baz = function (bat) {
        ...
    };

    When I used the term "object" before, that is only because everything in javascript is an object. The window object and the document object you already know about, but strings, numbers, and functions are also treated as objects.

    When I referred to the func object that's in the update function, it's was purely to refer to the variable called func, which contains the anonymous function that we created to add numbers.

    The reason why the func object contains a function to add numbers, is so that you can pass different functions in to the update function to perform subject, divide, multiply, square roots, x to the power of y, and so on.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  22. #22
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,272
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    I'm wondering again about parsInt vs Number. I cant find it anymore but didn't I read somewhere that as far as penalties etc go, we want to avoid using Boolean changes like that?

  23. #23
    Utopia, Inc. silver trophy
    ScallioXTX's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    9,037
    Mentioned
    152 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    I'm wondering again about parsInt vs Number. I cant find it anymore but didn't I read somewhere that as far as penalties etc go, we want to avoid using Boolean changes like that?
    Correct. Number() return 0 for the boolean "false", 1 for the boolean "true" and the number of seconds since the epoch for Date objects.
    parseInt returns NaN for all these cases and would therefore be more semantically correct for this script.

  24. #24
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    you want to avoid using default operators when anything falsy might be considered a valid value.

    For example:

    Code javascript:
    // default to -1 on an invalid value
    var x = parseInt(someValue, 10) || -1;
    // but what if someValue is 0 ?

    The above will incorrectly default to -1 when you use the value 0, which may not be what you intend.

    In situations like that where you don't want a falsy value to be considered false, you need to become more explicit about your conditions.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  25. #25
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,684
    Mentioned
    99 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by ScallioXTX View Post
    parseInt returns NaN for all these cases and would therefore be more semantically correct for this script.
    Are you suggesting that he will be more appropriately served by his calculator script by using parseFloat(value, 10) and checking it through isNaN ?
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

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