Octospice
Octospice

Reputation: 3

How do you add two variables which have user input?

At the moment I am trying to program a website where when you input two variables they add themselves together. This is my code:

    function master_wood() {
        var Stone = document.getElementById("Stone").value;
        var Wood = document.getElementById("Wood").value;
        alert('This much wood: ' +  Wood);
        var Resources = +Stone.value + +Wood.value;
    }
    function master_stone() {
        var Stone = document.getElementById("Stone").value;
        var Wood = document.getElementById("Wood").value;
        alert('This much stone: ' + Stone);
        var Resources = +Stone.value + +Wood.value;
        alert(Resources);
    
    }
 <table>
  <tr>
	 <td><input type="text" name="stone" id="Stone"></td>
     <td><button onclick="master_stone()">Set stone in world</button></td>
     </tr>
     <br>
     <tr>
	 <td><input type="text" name="wood" id="Wood"></td>
      <td><button onclick="master_wood()">Set Wood in world</button>    </td>
     </tr>
 </table>

Any ideas?

Upvotes: 0

Views: 531

Answers (4)

nick zoum
nick zoum

Reputation: 7285

I would recommend doing something like this:

var resourceList = ["stone", "wood"];

function masterResources(type) {
	var container = { }, resourceTotal= 0;
	for(var item of resourceList) {
		container[item] = parseInt(document.getElementById(item).value) || 0;
	}
	alert("This much" + type + ": " + container[type]);
	for(var resource in container) {
		resourceTotal+= container[resource];
	}
	alert('Total resources:' + resourceTotal);
}
    <table>
        <tr>
            <td><input type="number" name="stone" id="stone"></td>
            <td><button onclick="masterResources('stone')">Set stone in world</button></td>
        </tr>
        <br>
        <tr>
            <td><input type="number" name="wood" id="wood"></td>
            <td><button onclick="masterResources('wood')">Set Wood in world</button> </td>
        </tr>
    </table>

Explanation & Comments

1. Camel Case

JavaScript mostly uses camel case, which means that the first letter of a variable or function should start with a lower case and you separate words by making the first letter of each word capital (except for the first). example: thisIsAnExample.

2. Functions

I also see that the functions you use are very similar, so it would be better practice to try and use on instead that accepts different input. For example, change something like this

function sayHello(){
    console.log("hello");
}

function sayWorld(){
    console.log("world");
}

into

function saySomething(text) {
    console.log(text);
}

and call saySomething("hello"); and saySomething("world");

3. About the numbers

If you are going to only use numbers then you should probably limit the user to only typing numbers, so change the input type to number. meaning this <input type="text"> should turn into this <input type="number">. There are two easy ways to convert a string to a number the first is the function parseInt and the other is forcing JavaScript to convert it by using an operation that can only be performed on numbers, for example adding a - 0 after the number, thought this is generally considered as bad technique and should only be used for quick testing. Both of the ways will either return a valid number or NaN, so it is a good idea to add || 0 after the conversion so that all invalid (NaN, 0, null, undefined) numbers will be turned to 0. So a good way to convert a text into an int is parseInt(text) || 0

4. About reading the resources

It would be a good idea to store all the resource types in a list, hence the var resourceList = ["stone", "wood"];. Now if you want to add another input all you have to do is add the string to the resourceList. So now when the function is called, the values of all the inputs are stored in an object, which is now used an associative array, so you can get the value you want by using object["propety name"], i.e. container["wood"]. Then to add all the elements you loop through all the properties of the container object (so you want to use in and not of, in is for looping through an object's properties whereas of is for looping through an iteratable's (like lists) items) and add the values of the properties to the total.

Upvotes: 0

bamtheboozle
bamtheboozle

Reputation: 6406

You were assigning var stone as the value of the input, then you were trying to add stone.value which was undefined, since you directly assigned stone the value of the input.

Next, you needed to parse as integers the text values, since if you tried to add them together as they were you would get a concatenated string of values such as "3020" instead of 50 (if you had 20 wood, 30 stone).

Your script should look like this:

<tr>
     <td><input type="text" name="stone" id="Stone"></td>
     <td><button onclick="master_stone()">Set stone in world</button></td>
     </tr>
     <br>
     <tr>
     <td><input type="text" name="wood" id="Wood"></td>
      <td><button onclick="master_wood()">Set Wood in world</button></td>
</tr>
     
<script>
 function master_wood() {
    var Stone = document.getElementById("Stone");
    var Wood = document.getElementById("Wood");
    alert('This much wood: ' +  Wood.value);
    var Resources = (parseInt(Stone.value) || 0) + (parseInt(Wood.value) || 0);
    alert('Total resources:' + Resources);
}
function master_stone() {
    var Stone = document.getElementById("Stone");
    var Wood = document.getElementById("Wood");
    alert('This much stone: ' + Stone.value);
    var Resources = (parseInt(Stone.value) || 0) + (parseInt(Wood.value) || 0);
    alert('Total resources:' + Resources);

}
</script>

The (parseInt(Stone.value) || 0) part makes sure that the value you are trying to add exists, to avoid adding undefined + value, which results in NaN. This way, you add 0 if it doesn't exist, getting rid of unwanted results.

Upvotes: 1

ADyson
ADyson

Reputation: 61783

There are a couple of errors:

Firstly: Wood.value and Stone.value don't exist - you already selected the "value" property of the textboxes, so these variables contain strings, and you don't need to drill down for the "value" property again.

Secondly, your variables are strings, not numbers, so you need to parse them as numbers before you can add them up mathematically.

Thirdly, you've got two functions doing almost identical work. You can easily combine them into a single one:

function calculateResources() {
    var stone = parseInt(document.getElementById("Stone").value) || 0;
    var wood = parseInt(document.getElementById("Wood").value) || 0;
    alert('This much stone: ' +  stone + " and this much wood: " + wood);
    var resources = wood + stone;
    alert('Total resources:' + resources);
}


<table>
  <tr>
     <td><input type="text" name="stone" id="Stone"></td>
     <td><button onclick="calculateResources()">Set stone in world</button></td>
     </tr>
     <br>
     <tr>
     <td><input type="text" name="wood" id="Wood"></td>
      <td><button onclick="calculateResources()">Set Wood in world</button>    </td>
     </tr>
 </table>

N.B. If your quantities need to support fractions, you'd need to use parseFloat() rather than parseInt().

Upvotes: 0

Craicerjack
Craicerjack

Reputation: 6332

A couple of things.
camelCase tends to be the convention in JavaScript.
Both your functions do pretty much the same thing.
The below function sets a default to 0, if one of the functions doesnt have a value.
And you dont need to call Stone.value. Youre setting the value to stone so you dont need to call its value.

function setWoodAndStone() {
    var stone = parseInt(document.getElementById("Stone").value) || 0;
    var wood = parseInt(document.getElementById("Wood").value) || 0;
    var resources =stone+wood;
    alert(resources);
}  

<td><button onclick="setWoodAndStone()">Set Wood in world</button></td>

If you want the variables accessible outside of the function you can set them on an object.

var masterVars = {
    wood: 0,
    stone: 0,
    resources: 0
}

then the function changes to:

function setWoodAndStone() {
    masterVars.stone = parseInt(document.getElementById("Stone").value);
    masterVars.wood = parseInt(document.getElementById("Wood").value);
    masterVars.resources = +masterVars.stone+masterVars.wood;
    alert(resources);
} 

This was your variables will be available to you through the masterVars function. This is similar to Global vars but doesnt pollute the global namepsace

Upvotes: 0

Related Questions