0

Please forgive my ignorance, as I'm pretty new to Java script. Here is what I'm trying to do. I have a form where users can enter in data to get reimbursed. It sums totals up horizontally, and then takes the final values and adds them vertically for a grand total. I have everything working horizontally, and I can add the last 5 rows vertically, but when I add in the first two rows, it doesn't work. I get NaN for the answer. Here is the code.

<script type="text/javascript">
function calcWages(){
    document.getElementById('wages').innerHTML = '';
    var num2 = new Number(document.getElementById('hours').value);
    var num3 = new Number(document.getElementById('rate').value);
    document.getElementById('wages').innerHTML = ((num3 * num2).toFixed(2));
}

function calcMilage(){
    document.getElementById('milage').innerHTML = '';
    var num4 = new Number(document.getElementById('miles').value);
    document.getElementById('milage').innerHTML = ((num4 * .555).toFixed(2));
}

function calcTotal(){
    document.getElementById('total').innerHTML = '';
    var num5 = new Number(document.getElementById('wages').value);
    var num6 = new Number(document.getElementById('milage').value);
    var num7 = new Number(document.getElementById('travel').value);
    var num8 = new Number(document.getElementById('lodging').value);
    var num9 = new Number(document.getElementById('food').value);
    var num10 = new Number(document.getElementById('office').value);
    var num11 = new Number(document.getElementById('other').value);
    document.getElementById('total').innerHTML = (( num5 + num6 + num7 + num8 + num9 + num10 + num11).toFixed(2));
}

window.onload=function(){
    document.getElementById('totalCalc').onclick = calcTotal;
}   
</script>


<table>
<tr>
<td></td>
<td></td>
<td></td>
<td>
Total:
</td>
    <td></td>
    <td>

     </td>
</tr>
<tr>
<td>Wages:</td>
<td>Hours:(8 a day Max)<input type="text" name="hours" id="hours" size="3" maxlength="3" onchange="calcWages()"></td>
<td>Rate:<input type="text" name="rate" id="rate" size="3" maxlength="5" onchange="calcWages()"></td>
<td>=</td>
<td><div id="wages"></div></td>
</tr>
<tr>
<td>Milage:</td>
<td>Miles<input type="text" name="miles" id="miles" size="3" maxlength="4" onchange="calcMilage()"></td>
<td>IRS rate ($0.555)</td>
<td>=</td>
<td><div id="milage"></div></td>
</tr> 
<tr>
<td>
   Travel:   </td>
 <td colspan="2">
   <input type="text" name="tavelitem" id="travelitem" size="36">    </td>
 <td>
      = 
     </td>
 <td><input type="text" name="travel" id="travel" size="3"> </td>
</tr>
<tr>
<td>Lodging:</td>
 <td colspan="2"><input type="text" name="lodgingitem" id="lodgingitem" size="36">   </td>
 <td>=</td>
 <td><input type="text" name="lodging" id="lodging" size="3"></td>
</tr>
<tr>
<td>Food:</td>
 <td colspan="2"><input type="text" name="fooditem" id="fooditem" size="36">         </td>
 <td>=</td>
 <td><input type="text" name="food" id="food" size="3"></td>
</tr>
<tr>
<td>Office Supplies:</td>
 <td colspan="2"><input type="text" name="officesupplies" id="officesupplies" size="36">    </td>
 <td>=</td>
 <td><input type="text" name="office" id="office" size="3"></td>
</tr>
<tr>
<td>Other:</td>
 <td colspan="2"><input type="text" name="otheritem" id="otheritem" size="36"></td>
<td>=</td>
<td><input type="text" name="other" id="other" size="3"></td>
</tr>
<tr>
<td></td>
<td><button id="totalCalc">Total</button></td>
<td>Grand Total:</td>
<td>=</td>
<td><div id="total"></div></td>
</tr>
</table>

The calcWages function and the calcMilage functions work, but I seem to be getting hung up and getting the results of those two, to work in the calcTotal function. I apologize if this doesn't make sense. Let me know, and I'll try to clarify. Thanks.

7
  • 1
    When you see yourself using variables names with a running index, using an array and/or a loop is likely to be a better solution: eloquentjavascript.net/chapter4.html. Commented Dec 13, 2013 at 1:37
  • Do you ever call calcWages and calcMilage, perhaps in the onchange handler of the elements they depend on? Commented Dec 13, 2013 at 1:38
  • @FelixKling In this case, the variables are all just temporaries, it's not really array-like. Commented Dec 13, 2013 at 1:39
  • @Barmar: Yes, but a loop would still be better :) At least inside calcTotal. Commented Dec 13, 2013 at 1:39
  • It would be more appropriate to give them meaningful names, e.g. var wages = ...; var milage = ...;. Commented Dec 13, 2013 at 1:39

3 Answers 3

1

Here you're setting the .innerHTML

document.getElementById('milage').innerHTML = ((num4 * .555).toFixed(2));
//                                   ^^^

But then you're getting the .value from the same element.

var num6 = new Number(document.getElementById('milage').value);
//                                                       ^^^

Seems like you should be using one or the other. If the .innerHTML works for the first, then you should fetch it as well, or vice versa (unless perhaps this is a textarea element).


Either that, or you intended to use the miles element instead of milage.

var num6 = new Number(document.getElementById('miles').value);
//                                              ^^^
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the help. I didn't really understand any of it, but I was able to figure it out so maybe it somehow focused my thoughts. :)
1

They functions don't return anything, so you cannot really get their results. However, you can just call them inside calcTotal:

function calcTotal(){
    calcWages();
    calcMilage();
    // ...
}

From my comment: When you see yourself using variables names with a running index, using an array and/or a loop is likely to be a better solution.

Without changing your HTML, a cleaner solution would be:

var fields = ['wages', 'milage', ...];

function calcTotal(){
    var sum = 0;
    for (var i = 0; i < fields.length; i++)  {
        sum += +document.getElementById(fields[i]).value
    }
    document.getElementById('total').innerHTML = sum.toFixed(2);
}

You can also give the elements a common class to avoid listing their IDs in an array.

4 Comments

Hear that sound? It's the sound of your answer begging you to use .reduce(). ;-) (And maybe to fix your unbalanced curly brace. )
While I absolutely love all the new array methods, I think beginners should start with something simpler first. Also I like solutions which don't necessarily require polyfills.
Yeah, you're probably right. I could just hear it screaming at me. The voices... those voices in my head... they never stop! ;-)
Sorry I don't think I was very clear in my post. I've edited the code to inclde the form that users enter, and get information displayed in. I think that will calrify what I'm doing. It's realy jsuta very basic speadsheet form. Hope that helps. Thanks again, I'm very new to Javascript.
0
<script type="text/javascript">
        function calcWages(){
            document.getElementById('wagestotal').innerHTML = '';
            var hours = new Number(document.getElementById('hours').value);
    var rate = new Number(document.getElementById('rate').value);
           document.getElementById('wagestotal').innerHTML = ((hours * rate).toFixed(2));

        }

         function calcMilage(){
            document.getElementById('milagetotal').innerHTML = '';
            var miles = new Number(document.getElementById('miles').value);
    document.getElementById('milagetotal').innerHTML = ((miles * .555).toFixed(2));
                }


        function calcTotal(){
           document.getElementById('total').innerHTML = '';
        var wages = new Number(document.getElementById('wagestotal').innerHTML);
        var milage = new Number(document.getElementById('milagetotal').innerHTML);
        var travel = new Number(document.getElementById('travel').value);
        var lodging = new Number(document.getElementById('lodging').value);
        var food = new Number(document.getElementById('food').value);
        var office = new Number(document.getElementById('office').value);
        var other = new Number(document.getElementById('other').value);
document.getElementById('total').innerHTML = ((wages + milage + travel + lodging + food + office + other).toFixed(2));
        }
        window.onload=function(){
            document.getElementById('totalCalc').onclick = calcTotal;
        }

       </script>

So this is the final script. I changes the names of the variables to things that make sense. The final hand up I was having was being able to ad the totals form the wages function, and the milage function into the the grand total. The part I had messed up was that I had:

var wages = new Number(document.getElementById('wagestotal').value);
var milage = new Number(document.getElementById('milagetotal').value);

Instead of:

var wages = new Number(document.getElementById('wagestotal').innerHTML);
var milage = new Number(document.getElementById('milagetotal').innerHTML);

in the calcTotal funciton. The user can enter stuff in to the form that this ties to, and it all gets totaled like it should. Thanks again for helping focus my thoughts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.