Jump to content
Larry Ullman's Book Forums
John B

Chapter 4 Calculator

Recommended Posts

 

 

Hi Larry Ullman, I’m new to JavaScript and I’m currently working on an assignment for my class that involves me to create a paycheck calculator based on a form I created using Html elements in Notepad++ and elements of JavaScript in a separate Notepad++ document. The form I’m creating uses many aspects presented in chapter 4 of the Modern JavaScript Develop and Design textbook. The problem I’m having with my code is (posted below), so far when creating the paycheck calculator, I’ve got the regularPay and the overtimePay to calculate correctly but my main problem is whenever I try to get the calculations for the grossPay, netPay, and totalTaxes to calculate they won’t work at all. I would appreciate it if you looked over my code and gave me feedback on how to get the values to display. Here is my code for the Html form and below it is the JavaScript code. Here is the link to the assignment I’m working on as well.

Assignment Link

https://docs.google.com/file/d/0BwDHF5mNxWWZQm1aRkpCbUFkdkE/edit

 

Html

<!doctype html>

 

<html lang="en">

 

<head>

 

    <meta charset="utf-8">

         

    <title>Paycheck Calculator</title>

         

          <link rel="stylesheet" href="css/styles.css">

         

          </head>

         

<body>

 

          <form action="#" method="post" id="form1">

         

          <fieldset>

         

          <div><label for="firstName">First Name</label><input type="text" name="firstName" id="firstName" required></div>

         

          <div><label for="lastName">Last Name</label><input type="text"  name="lastName" id="lastName" required></div>

         

          <div><label for="regularHours">Regular Hours Worked (between 0 and 40)</label><input type="text" name="regularHours" id="regularHours" value="0" required></div>

         

          <div><label for="overtimeHours">Overtime Hours Worked (between 0 and 40)</label><input type="text" name="overtimeHours" id="overtimeHours" value="0" required></div>

         

          <div><label for="hourlyRate">Hourly Rate (between 0 and 99.99)</label><input type="text" name="hourlyRate" id="hourlyRate"  value="0.00" required></div>

         

          <div><label for="ficaTax">Fica Tax Rate (ex. 5.65)</label><input type="text" name="ficaTax" id="ficaTax"  value="0.00" required></div>

         

          <div><label for="stateTax">State Tax Rate(ex. 28.00)</label><input type="text" name="stateTax" id="stateTax"  value="0.00" required></div>

         

          <div><label for="federalTax">Federal Tax Rate (ex. 5.75)</label><input type="text" name="federalTax" id="federalTax" value="0.00" required></div>

         

          <div><label for="regularPay">Regular Pay</label><input type="text" name="regularPay" id="regularPay" value="0.00"></div>

         

          <div><label for="overtimePay">Overtime Pay</label><input type="text" name="overtimePay" id="overtimePay" value="0.00"></div>

         

          <div><label for="grossPay">Gross Pay</label><input type="text" name="grossPay" id="grossPay" value="0.00"></div>

         

          <div><label for="totalTaxes">Total Taxes</label><input type="text" name="totalTaxes" id="totalTaxes" value="0.00"></div>

         

          <div><label for="employeeName">Employee Name</label><input type="text" name="employeeName" id="employeeName"></div>

         

          <div><label for="netPay">Net Pay</label><input type="text" name="netPay" id="netPay" value="0.00"></div>

         

          <div><input type="submit" value="Calculate" id="submit"></div>

         

 

          </fieldset>

         

    </form>

         

          <script src="js/paycheck.js"></script>

         

</body>

 

</html>

 

JavaScript

function calculate() {

         

    'use strict';

         

    var regularHours = document.getElementById('regularHours').value;

         

    var overtimeHours = document.getElementById('overtimeHours').value;

         

          var hourlyRate = document.getElementById('hourlyRate').value;

         

          var ficaTax = document.getElementById('ficaTax').value;

         

          var stateTax = document.getElementById('stateTax').value;

         

          var federalTax = document.getElementById('federalTax').value;

         

          var regularPay = document.getElementById('regularPay').value = (regularHours*hourlyRate).toFixed(2);

         

          var overtimePay = document.getElementById('overtimePay').value = (overtimeHours*(hourlyRate*1.5)).toFixed(2);

         

          /*var grossPay = document.getElementById('grossPay').value = (regularPay+overtimePay).toFixed(2);

         

          var totalTaxes = document.getElementById('totalTaxes').value = (ficaTax+stateTax+federalTax*grossPay/100).toFixed(2);

         

          var netPay = document.getElementById('netPay').value = (grossPay-totalTaxes).toFixed(2);

         

          */

         

          var employeeName;

         

          var firstName = document.getElementById('firstName').value;

         

          var lastName = document.getElementById('lastName').value;

         

          employeeName = lastName + ', ' + firstName;

         

          document.getElementById('employeeName').value = employeeName;

         

          return false;

         

} // End of function.

 

function init() {

         

    'use strict';

         

    document.getElementById('form1').onsubmit = calculate;

         

} // End of init() function.

 

window.onload = init;

Share this post


Link to post
Share on other sites

John, I can see where things can get a bit confusing.

When you run the toFixed method on a number, the result is a string, not a number. As an example, in your code, both the regularPay and overtimePay variables are actually strings, not numbers. As such, regularPay + overtimePay is not going to give you what you would expect. What's more, when you try to run the toFixed method on the result of regularPay + overtimePay, you will get an error because only numbers, not strings, even have the toFixed method available to them.

For the sake of your calculations, you may want to convert the result of toFixed each time back into a number. Ultimately, it's up to you how you want to handle it though.

As another note, it often helps to load your browser JS console up when you're writing JS code like this. It'll typically tell you when there's an error as well as what kind of error it is and where it's located. It makes these sorts of things easier to debug.

Hope that all makes sense and good luck. Feel free to response with any other questions. Thanks.

Share this post


Link to post
Share on other sites

Hi HartleySan, thank you for responding to my question. I think I understand what your trying to tell me based on your reply, in my code both regularPay and overtimePay are presented as strings instead of numbers but my question is how do I convert regularPay and overtimePay into a number? Also, when regularPay and overtimePay are converted into numbers will the values for regularPay and overtimePay still appear in the calculator when I test the code?

Share this post


Link to post
Share on other sites

If you do a Google search for something like "JS string to number", you'll get a multitude of good resources. Here's the first hit:

https://gomakethings.com/converting-strings-to-numbers-with-vanilla-javascript/

I generally use parseInt(str, 10), and since that gets annoying to type after a while, I have that logic bundled up until a function called toInt.

One nice thing about coding, and JavaScript in particular, is that you can Google just about anything. Just type "JS" and then whatever you're looking for, and you'll likely get a Stack Overflow hit or something else that's relevant.

As for your second question, when you ask "will the values for regularPay and overtimePay still appear in the calculator," I assume you're asking whether a number can be stored into the value property of a DOM input element. If that's the case, then yes. JS will automatically perform string interpolation for you. That is to say, if you try to stick a number into something that requires a string, JS will automatically convert it to a string for you. For example, if I do the following:

'10' + 10

I'll get the string '1010', not 20. That's because when you try to do a string "plus" a number, JS doesn't try to do the math, it converts the number to a string and then concats the two strings together.

As such, yes, you can stick a number into the value property of a DOM input element, and it'll automatically turn it into a string to be displayed on the screen.

Hope that all makes sense.

Share this post


Link to post
Share on other sites

Hi HartleySan I recently made some changes to my code in Notepad++. So far I tried using the parseFloat function that way the values for regularPay, overtimePay and the other values I had would come out as decimals instead of strings but now,  it seems like nothing is calculating when it did before and I can't get the values for grossPay, totalTaxes, and netPay to appear either. Here is my code below I have my equations set up as well the parseFloat function for each of my values but I still don't know why nothing is appearing when it should, do you think it has something to do with the way i'm writing the parseFloat function in my equations?

function calculate() {
    
    'use strict';
    
    var regularHours = document.getElementById('regularHours').value;
    
    var overtimeHours = document.getElementById('overtimeHours').value;
    
    var hourlyRate = document.getElementById('hourlyRate').value;
    
    var ficaTax = document.getElementById('ficaTax').value;
    
    var stateTax = document.getElementById('stateTax').value;
    
    var federalTax = document.getElementById('federalTax').value;
    
    var regularPay = document.getElementById ('regularPay').value = parseFloat(regularHours*hourlyRate).toFixed(2);
    
    var overtimePay = document.getElementById ('overtimePay').value = parseFloat(overtimeHours*(hourlyRate*1.5)).toFixed(2);
    
    var grossPay = document.getElementById ('grossPay').value = parseFloat(regularPay+overtimePay).toFixed(2);
    
    var totalTaxes = document.getElementById ('totalTaxes').value = parseFloat(ficaTax+stateTax+federalTax*grossPay)/100.toFixed(2);
    
    var netPay = document.getElementById ('netPay').value = parseFloat(grossPay-totalTaxes).toFixed(2);
    
    
    
    var employeeName;
    
    var firstName = document.getElementById('firstName').value;
    
    var lastName = document.getElementById('lastName').value;
    
    employeeName = lastName + ', ' + firstName;
    
    document.getElementById('employeeName').value = employeeName;
    
    return false;
    
} // End of function.

function init() {
    
    'use strict';
    
    document.getElementById('form1').onsubmit = calculate;
    
} // End of init() function.

window.onload = init;

 

Share this post


Link to post
Share on other sites

John B, the browser console is your best friend for trying to debug JS issues/errors.

I loaded up your code and instantly saw the following error:

Quote

Uncaught SyntaxError: Invalid or unexpected token (line 23)

The following is line 23:

var totalTaxes = document.getElementById ('totalTaxes').value = parseFloat(ficaTax+stateTax+federalTax*grossPay)/100.toFixed(2);

An unexpected token error basically means that there is some invalid/unknown character in your code.

This one is a bit interesting though in that the error is actually with the following expression:

100.toFixed(2)

The reason this is a problem is because the 100. is ambiguous. Specifically, when you put a period right after a number like that, the JS parser doesn't know whether to treat that like a decimal in a number (e.g., 100.00) or as a dot used to invoke a method of the Number object (e.g., toFixed(2)).

The easiest way to resolve this error is to remove the ambiguity by doing something like the following:

(100).toFixed(2)

With all that said, I still think there are some other logic errors in your code. If I were to make a recommendation, I would try to take a lot of the repetitive things you're doing and pull them out into one or more functions to decrease the likelihood of bugs in your code as well as make it simpler.

As some examples, you could turn document.getElementById(str) into a function. You could also turn document.getElementById(str).value into another function that utilizes the first function. Furthermore, you could add a flag for whether to convert to a string or a number. Lastly, I would probably write a function to then set the value of a DOM input element.

Putting all of that together, I may rewrite your code as follows:

function calculate() {
  
  'use strict';
  
  var regularHours = getVal('regularHours', true),
    overtimeHours = getVal('overtimeHours', true),
    hourlyRate = getVal('hourlyRate', true),
    ficaTax = getVal('ficaTax', true),
    stateTax = getVal('stateTax', true),
    federalTax = getVal('federalTax', true),
    
    regularPay = to2Dec(regularHours * hourlyRate, true),
    overtimePay = to2Dec(overtimeHours * hourlyRate * 1.5, true),
    grossPay = to2Dec(regularPay + overtimePay, true),
    totalTaxes = to2Dec((ficaTax + stateTax + federalTax) * grossPay / 100, true), // Not sure about the correct parens here for the math.
    netPay = to2Dec(grossPay - totalTaxes, true);
  
  setVal('regularPay', regularPay);
  setVal('overtimePay', overtimePay);
  setVal('grossPay', grossPay);
  setVal('totalTaxes', totalTaxes);
  setVal('netPay', netPay);
  setVal('employeeName', getVal('firstName') + ' ' + getVal('lastName')); // Need the comma with first name first?
  
  return false;
  
}

function getVal(id, toNum) {
  
  var elem = gI(id);
  
  if (toNum) {
    return parseFloat(elem.value);
  }
  
  return elem.value;
  
}

function setVal(id, val) {
  
  gI(id).value = val;
  
}

function gI(id) {
  
  return document.getElementById(id);
  
}

function to2Dec(num, toNum) { // To two-decimal number
  
  if (toNum) {
    return parseFloat(num.toFixed(2));
  }
  
  return num.toFixed(2);
  
}

function init() {
  
  'use strict';
  
  gI('form1').onsubmit = calculate;
  
}

window.onload = init;

In my mind, that's a lot easier to debug as well as read. Please share your thoughts and any other questions you have.

Thanks.

Edited by HartleySan

Share this post


Link to post
Share on other sites

Hi HartleySan I have another question, I think I am having an issue when it comes to the browser console I am able to pull it up through the Mozilla Firefox menu and then by going to the web developer menu but when I pull up the browser console it doesn't show me the list of errors in my code. I posted an attachment of what it looks like when I pull my browser console in Firefox.

browser console firefox.png

Share this post


Link to post
Share on other sites

Hmmm... hard to say without a bit more context. I generally use Chrome for development, as I find the dev tools to be more to my liking. As such, I haven't used FF in a while to dev.

With that said, I vaguely recall there being something in FF with the fact that if an error occurs before you load the console, then it wouldn't show the error in the console.

Maybe try loading the console in FF first, then reloading the page and seeing if the error shows up.

Beyond that, it's hard for me to assist without knowing exactly what you're doing and how.

Thanks.

Share this post


Link to post
Share on other sites

Thank you for trying I tested my paycheck.html file in Chrome and seems I got the error to appear in my browser console, here is a screenshot showing the error. I think what I will do is test my page in different browsers for errors and try to reorganize my code better, not only that but I will review how you rewrote my code and see if I can write my equations better using parseFloat in order to get the values to appear.

Share this post


Link to post
Share on other sites

Hi HartleySan, I have some good news regarding my code. Recently I have been rewriting some of my equations for grossPay, netPay, totalTaxes etc and after testing the code in my paycheck calculator in Firefox it's safe to say I have my code and the paycheck calculator working, all I had to do was observe how you rewrote my code in your previous reply and I eventually did my best to rewrite my equations as I saw fit until I got the code working. Here is my newly updated code and the paycheck calculator is working as it should, thank you for all your all help and to responding to my messages.

function calculate() {
    
    'use strict';
    
    var regularHours = document.getElementById('regularHours').value;
    
    var overtimeHours = document.getElementById('overtimeHours').value;
    
    var hourlyRate = document.getElementById('hourlyRate').value;
    
    var ficaTax = document.getElementById('ficaTax').value;
    
    var stateTax = document.getElementById('stateTax').value;
    
    var federalTax = document.getElementById('federalTax').value;
    
    var regularPay = document.getElementById ('regularPay').value = parseFloat(regularHours*hourlyRate).toFixed(2);
    
    var overtimePay = document.getElementById ('overtimePay').value = parseFloat(overtimeHours*(hourlyRate*1.5)).toFixed(2);
    
    var grossPay = document.getElementById ('grossPay').value = parseFloat(+regularPay+ +overtimePay).toFixed(2);
    
    var totalTaxes = document.getElementById ('totalTaxes').value = parseFloat(+ficaTax+ +stateTax+ +federalTax)* grossPay /100 .toFixed(2);
    
    var netPay = document.getElementById ('netPay').value = parseFloat(grossPay-totalTaxes).toFixed(2);
    
    
    
    var employeeName;
    
    var firstName = document.getElementById('firstName').value;
    
    var lastName = document.getElementById('lastName').value;
    
    employeeName = firstName + ' ' + lastName;
    
    document.getElementById('employeeName').value = employeeName;
    
    return false;
    
} // End of function.

function init() {
    
    'use strict';
    
    document.getElementById('form1').onsubmit = calculate;
    
} // End of init() function.

window.onload = init;

 

Share this post


Link to post
Share on other sites

John B, glad you got it working.

The only thing I will say in response as a critique is that I think that things like the following are a bit difficult to understand:

+regularPay+ +overtimePay

People familiar with JS will know that +numInStrFormat will convert a String number to a Number number, but it does make the code a bit difficult to understand at first glance.

In general, the easier code is to read, the better.

All the same, glad you got it working, and it seems like you learned a lot along the way, which is great.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...