- How can this simple savings calculator help? This personal finance tool helps you simulate the growth of your account no matter of its type (retirement, college or simple savings account) in case you analyze the opportunity to place a deposit with monthly compound interest and with regular contributions at the end of each month.
- Enter a website URL. Find out how much turning on modern JS could save.
Because you have an interface for this to be defined, I would suggest not splitting the string, but having your input create an array of 'operands' and 'operators' that can then build a string from, with the result being easily consumable for calculating the result, for instance. Simple example: `22, 'x', 15, '.', 2. Jun 23, 2021 Create a Simple calculator using vanilla JavaScript: This is a simple calculator created only with HTML, CSS and JS. It will enhance your basics of JavaScript which is more important than learning new technologies. Prerequisite KnowledgeBasics of HTML, CSS, JavaScript and desire to create something new.
The calculator app we’ll develop in this tutorial is a very simple one. It ismore or less in the manner of those calculators found at grocery stores. The layoutof the app was crafted with CSSgrid. If you’d like to learn how it was achieved, be sure to check out thistutorial as this one focuses onlyon the JavaScript logic employed to make the calculator work.
Here’s a live demo of the completedproject. You can play around with it to get a feel of what you’ll be buildingbefore diving in.
Prerequisites
This tutorial assumes that you have a basic knowledge of JavaScript. Itil v3 process model pdf. I’m goingto break down each step as best as I can so it should be easy to follow even ifyou have no prior experience with building applications in the browser.
Before you begin
You can find the starting pointfor this tutorial on JSFiddle. It contains all the necessary markup and stylesused to build the calculator layout. The markup is almost identical to thefinal state of the previoustutorial in which I discussed howthe calculator layout was crafted, but I made a few minor changes so make sureto use this one instead.
Start by forking the code to a new fiddle, and follow along by typing each stepout till the end. Feel free to do this tutorial on other online code playgroundsor on your local machine if you prefer.
Getting started
Anyone should be able to perform the four most common arithmetic operations(addition, subtraction, multiplication and division) on our calculator app byconstructing a valid expression using the input buttons, and have the resultdisplayed on the screen. An example of a valid expression is shown below:
To construct a valid arithmetic expression, we need to keep track of a fewthings: the first operand (12
), the operator (+
) and the second operand(10
).
Let’s start by creating an object to help us keep track of these values. Add thefollowing code at top of the JavaScript pane in JSFiddle:
The calculator
object above consists of everything that we need to constructa valid expression:
displayValue
holds a string value that represents the input of the user orthe result of an operation. It’s how we keep track of what should be displayedon the screen.firstOperand
will store the first operand for any expression. It’s set tonull
for now.- The
operator
key will store the operator for an expression. Its initial valueis alsonull
. waitingForSecondOperand
essentially serves as a way to check if both the firstoperand and the operator have been inputted. If it’strue
, the next numbers thatthe user enters will constitute the second operand.
Update the display
At the moment, the calculator screen is blank. We need the contents of thedisplayValue
property to be shown on the screen at all times. We will create afunction for this purpose so that anytime an operation is performed in the app,we can always invoke it to update the screen with the contents ofdisplayValue
.
Go ahead and type this below the calculator
object:
If you look at the HTML code forthe app, you’ll see that the “screen” is really just a disabled text input:
We can’t type into it directly with the keyboard, but we can change its valuewith JavaScript. Mars mips. And that’s what the updateDisplay
function does. Now youshould see zero displayed on the screen of the calculator.
Take a breather, and see thecomplete codeat the end of this step.
Handle key presses
We have four sets of keys on the calculator: digits (0-9), operators (+, −, ⨉,÷, =), a decimal point (.) and a reset key (AC). In this section, we’ll listenfor clicks on the calculator keys and determine what type of key was clicked.
Add this code snippet at the bottom of the JavaScript tab:
In the above snippet, we’re listening for a click
event on the element with aclass of calculator-keys
. Since all the keys on the calculator are childrenof this element, the click
event filters down to them too. This is known asevent delegation.
Inside the callback function of the event listener, we extract the target
property of the click event using destructuringassignmentwhich makes it easy to unpack object properties into distinct variables.
The target
variable is an object that represents the element that was clicked.If this element is not a button (such as if you click the spaces between thebuttons), we will exit the function by returning early. Otherwise, the type ofbutton that was clicked is logged to the console along with its value.
Be sure to try this out before proceeding to the next step. Open up your browser console andclick any of the buttons. The key’s type and value should be logged to theconsole accordingly.
Take a breather, and see thecomplete codeat the end of this step.
Input the digits
In this step, we’ll make the digit buttons work so that when any of them isclicked, the corresponding value is displayed on the screen.
Since the displayValue
property of the calculator
object represents theinput of the user, we need to modify it when any of the digits is clicked.Create a new function called inputDigit
below the calculator
object:
Next, replace the following line in the click
event listener callback function:
with the following code:
In the inputDigit
function, the ternaryoperator(?
) is used to check if the current value displayed on the calculator is zero.If so, calculator.displayValue
is overwritten with whatever digit was clicked.Otherwise, if displayValue
is a non-zero number, the digit is appended to itthrough string concatenation.
Finally, the updateDisplay()
function is invoked so that the new contents ofthe displayValue
property is reflected on the screen after each button isclicked. Try it out by clicking any of the digit buttons. The display should beupdated with whatever digit you clicked.
Take a breather, and see thecomplete codeat the end of this step.
Input a decimal point
When the decimal point key is clicked, we need to append a decimal point towhatever is displayed on the screen except if it already contains a decimalpoint.
Here’s how we can achieve that. Create a new function called inputDecimal
below inputDigit
:
Within the inputDecimal
function, theincludes()method is used to check if displayValue
does not already contain a decimalpoint. If so, a dot is appended to the number. Otherwise, the function exits.
Following that, replace the following line in the keys' event listener callbackfunction:
with the following lines of code:
At this point, you should be able to add input a decimal point successfully andhave it display on the screen.
Take a breather, and see thecomplete codeat the end of this step.
Handling operators
The next step is to get the operators (+, −, ⨉, ÷, =) on the calculator working.There are three scenarios to account for:
1. When a user hits an operator after entering the first operand
At this point, the contents of displayValue
should be stored under thefirstOperand
property and the operator
property should be updated withwhatever operator was clicked.
Create a new function called handleOperator
below inputDecimal
:
When an operator key is pressed, the contents of displayValue
is converted toa floating-point number (meaning a number with a decimal point) and the resultis stored in the firstOperand
property.
The operator
property is also set to whatever operator key was clicked whilewaitingForSecondOperand
is set to true
which indicates that the firstoperand has been entered and whatever digits the user enters next willconstitute the second operand.
At this point, it is useful to see how the properties of the calculator
objectare being updated on each button press. Add the following line to the end ofboth the inputDigit
and handleOperator
functions:
Then replace the following line in the keys' click
event listener callbackfunction:
with the following code:
At this point, try to construct a valid arithmetic operation by clicking thefollowing keys in turn: 12 +
. Notice that when the +
key is pressed, thevalues of firstOperand
and operator
properties are updated to 12
and +
respectively while waitingForSecondOperand
is set to true indicating that thecalculator is now waiting for the second operand to be entered.
If you try to enter the second operand, you will notice that it is appended tothe first instead of overwriting it.
Let’s fix that by updating the inputDigit
function as shown below:
If the waitingForSecondOperand
property is set to true
, the displayValue
property is overwritten with the digit that was clicked. Otherwise, the samecheck is performed as before, overwriting or appending to displayValue
asappropriate.
Take a breather, and see thecomplete codeat the end of this step.
2. When the user hits an operator after entering the second operand
The second scenario we need to handle occurs when the user has entered thesecond operand and an operator key is clicked. At that point, all theingredients to evaluate the expression is present so we need to do so anddisplay the result on the screen. The firstOperand
also needs to be updated sothat the result can be reused in the next calculation.
Create a new function called calculate
below handleOperator
as shown below:
This function takes the first operand, second operand and operator as argumentsand checks the value of the operator to determine how the expression should beevaluated. If the operator is =
, the second operand will be returned as is.
Next, update the handleOperator
function as shown below:
The else if
block added to handleOperator
checks if the operator
propertyhas been assigned an operator. If so, the calculate
function is invoked andthe result is saved in the result
variable.
This result is subsequently displayed to the user by updating the displayValue
property. Also, the value of firstOperand
is updated to the result so that itmay be used in the next calculator.
Try it out. Enter 12 + 10 =
in the calculator and notice that the correctresult is displayed on the screen. It also works when you chain a string ofoperations. So 5 * 20 - 14 =
should give 86
as the result.
This is because hitting the minus key triggers the calculation of the firstoperation (5 * 20
) whose result (100
) is subsequently set as thefirstOperand
for the next calculation so by the time we enter 14
as thesecond operand and hit the =
key, the calculate
function is executed againgiving 86
as the result which is also set as the firstOperand
for the nextoperation, and so on.
Take a breather, and see thecomplete codeat the end of this step.
3. When two or more operators are entered consecutively
It’s quite common to change one’s mind about the type of operation one wants toperform so the calculator must handle this properly.
Let’s say you want to add seven and two together, you will click 7 + 2 =
whichwill produce the correct result. But let’s assume after hitting 7 +
, youchange your mind and decide to subtract 2 from 7. Instead of clearing thecalculator and starting all over, you should be able to hit -
to override the+
that was previously entered.
Remember that at the point the operator is entered, waitingForSecondOperand
will be set to true
since the calculator expects a second operand to beentered after the operator key. We can use this quality to update the operatorkey and prevent any calculations until the second operand has been inputted.
Modify the handleOperator
function to look like this:
The relevant change is highlighted above. The if
statement checks if anoperator
already exists and if waitingForSecondOperand
is set to true
. Ifso, the value of the operator
property is replaced with the new operator andthe function exits so that no calculations are performed.
Try it out. Click multiple operators after entering some digits and monitor thecalculator object in the console. Notice that the operator
property is updatedeach time and no calculations are performed until you provide the secondoperand.
Take a breather, and see thecomplete codeat the end of this step.
Reset the calculator
The final task is to make sure the user can reset the calculator to its initialstate by pressing a key. In most calculators, the AC
button is used to resetthe calculator to its default state, so that’s what we’re going to do here.
Go ahead and create a new function below calculate
as shown below:
Then replace the following line in the keys' event listener callback function:
with the following code:
The resetCalculator
function sets all the properties of the calculator
object to their original values. Clicking the AC
key on the calculator shouldnow work as expected. You can check the calculator
object in the console toconfirm.
Take a breather, and see thecomplete codeat the end of this step.
Fix decimal bug
If you enter a decimal point after clicking on an operator, it gets appended tothe first operand instead of being a part of the second.
We can fix this bug by making the following modification to the inputDecimal
function:
If waitingForSecondOperand
is set to true
and a decimal point is entered,displayValue
becomes 0.
and waitingForSecondOperand
is set to false sothat any additional digits are appended as part of the second operand.
Take a breather, and see thecomplete codeat the end of this step. Fundamentals of anatomy and physiology frederic martini pdf.
Refactor the event listener
Update the keys' event listener as shown below. All the if
blocks havebeen replaced with a single switch
block, and updateDisplay()
is called onlyonce at the end of the function.
This way, it’s a lot easier to add new functions to the calculator and you nolonger need to invoke the updateDisplay()
function after each operation.
Take a breather, and see thecomplete codeat the end of this step.
Floating-point precision
I’d like to bring your attention to a problem that occurs when the result of anoperation is a floating number. For example, 0.1 + 0.2
produces0.30000000000000004
instead of 0.3
as you’d probably expect.
In other cases, you get the expected result. 0.1 + 0.4
yields 0.5
forexample. A detailed explaination for why this happens can be foundhere. Make sure you read it.
One of the potential solutions to this problem suggested in the above linkedpage is to format the result to a fixed number of decimal places so that theothers are discarded. We can combine the JavaScriptparseFloatfunction with theNumber.toFixed method to implement this solution in our calculator app.
In the handleOperator
function, replace the following line:
with the following code:
The toFixed()
method accepts a value between 0 and 20, and ensures that thenumber of digits after the decimal point is restricted to that value. Thereturn value may be rounded or padded with zeros if necessary.
In the earlier example, 0.1 + 0.2
yielded 0.30000000000000004
. UsingtoFixed(7)
on the result will restrict the digits after the decimal point toseven digits:
Those extra zeros are not important, so we can use parseFloat
to get rid ofthem:
And that’s how we’re able to fix this problem in our application. I chose thenumber 7 in this case because it’s a good enough precision for this calculatorapp. A greater amount of precision may be required in other situations.
Take a breather, and see thecomplete codeat the end of this step.
Bonus content
I have prepared some further enhancements to this calculator app for my Patreonsupporters. The following functions were added to the app: sin, cos, tan, log,square, square root, factorial, percent, plus/minus, π and ce.
If you’d like to gain access to all my bonus content (including this one),consider supporting Freshman on Patreon.Your support will help me create more tutorials at a faster rate.
Conclusion
That concludes my tutorial, I hope you learnt a lot from it. Feel free to leavea comment if a section of the article is not clear enough for you, andsubscribe to my newsletter to get more awesome tutorials likethis one in your inbox.
Thanks for reading, and happy coding!
BACK |
Contents |
Planning
Okay, so we want to write a JavaScript calculator. Let's not (initially) be too ambitious. All our calculator will do is basic arithmetic: add, subtract, multiply and divide. Hmm, what about negative numbers - so we also need to be able to change the sign of a number. What else? Well, we're going to allow rather big numbers, so it's a good idea to have a button that easily allows us to enter an exponent (the number times 10something). We need a decimal point. And we need to be able to clear the display (a CLEAR button), and to clear everything (ALL CLEAR). Let's list out requirements up to now:- A display area for numbers
- Buttons for 0,1,2, up to 9
- A decimal point button
- A button to change the sign (+/-)
- Clear and all clear (C, AC buttons)
- Function buttons (* / + -)
- An exponent button (EXP)
- A 'calculate' button (The = button)
Let's group our different buttons and boxes into three classes:
- The display area
- The numeric buttons (0 to 9, +/-, .)
- Function buttons together with AC, C, = and EXP
Why not position these in a table, thus:
Display Area | |
Numeric Buttons | Function Buttons |
Even at this early stage, we also need to think about what can go wrong. Hmm. Here are a few possibilities:
- Too many digits are entered
- The result of a calculation is too 'big' to show (too large and positive, or too large and negative)
- The result of a calculation is too small to show (for example, 1*10-1000)
- We divide something by zero
- JavaScript bombs out because of internal calculation problems, for example if we divide 101000 by 101000 - we know that the answer is 1, but does JavaScript?
We therefore must trap numbers that appear too long (although this is to a certain extent a matter of taste); we must show appropriate error messages with divide by zero and numbers that are out of range (most JavaScript implementations seem happy up to about 10±320); tiny tiny tiny numbers can be represented as zero; and we also need a way to alert the user to JavaScript's occasional troubles with large numbers.
Writing the HTML
As our basic calculator, we'll use the following table:Which implements the layout we discussed in 'Planning' above. We need to put all of the above inside a <FORM> . </FORM> pair of tags, and then we need to create buttons for each of the numbers and functions we talked about when we planned things.
How do we create buttons? Well, we could do what we did on the first page of our JavaScript tutorial, and hijack a <input type='reset'> button, but there is a better way. All recent and respectable variants of JavaScript (but not, for example, some earlier releases of IE 3) have the following type of input:
<input type='button'>
Which gives us a general-purpose button. To each of these buttons we'll attach a:
OnClick='DoSomething()'
'event handler', so that when we click on the button, we can expect a response. We'll discuss each of these responses in the Calculator Functions section below. For now, let's draw our calculator:
More detailed HTML for basic calculator |
We've colour-coded things to make them a bit easier. FORM elements are in red, the outer table is bold, and tables inside tables are in blue. You can see that we've preserved our basic structure that we talked about previously - the top panel takes up two columns and contains a text input that we'll use for displaying results; the bottom left panel will contain the numbers (three examples are given), and the bottom right will contain function buttons. Note several other things:
- The form has a name. We've called it Calculator.
- Each input button has a value - this is what will be displayed on the button, for example '7' will be displayed on the button that you push to generate a '7' on the display.
- The display area is unsurprisingly named Display (with a capital D), and we've defined a width (size='30') and a maximum length of the input string (maxlength='40').
- Each of the buttons has its own <td> . </td> - this keeps them nicely spaced out and regular.
Now if you take the above code and simply paste it into your web-page, (adding in a few <td>'s and stuff), you'll get something like the following:
. So clearly we need to do a bit of work. We need to:
- Pretty up fonts and alignment
- Widen the buttons a lot
- Perhaps give the calculator a background colour
If you're adequate at HTML, all of this should be reasonably straightforward. Perhaps widening the buttons needs a bit of explanation. We've given our buttons values of '7', '8' and so on. What happens if we say:
<input type='button' value=' 7 ' >
This is a good way of widening our buttons. Note that even when we do this, all of the buttons are not quite the same width (at least, on most browsers)! This is because the chances are your browser is using a proportional font to write the 'value' on the button. Now in Netscape, the font can be changed for each button to a fixed-width font (although the resulting code looks like hell) - in IE, you don't seem to have that option (I wonder, can you do this using style sheets?). Oh well.
Hmm, just for clarity, why don't we also name our buttons. For example:
<input type='button' value=' 7 ' name='seven' >
Play around a bit. Try the 'finished' calculator using both Netscape and IE - you'll find that despite your fine-tuning, the darn thing looks quite different. When you're happy, we're ready to move on to actually making the thing work!
Calculator Functions- Writing the JavaScript
We know how to attach event handlers to each button. We simply put:OnClick='DoEvent()'
where DoEvent is the event handler for the relevant button. For example, for button number seven, we might say:
<input type='button' name='seven' value=' 7 '>
where AddDigit is the event handler. Let's now decide what events we need. Here they are:
- Add a digit to the display
- Put a decimal point on the display (if not there already)
- Put an exponent ('e') on the display
- Change the sign to + if - and minus if plus
- Clear and All Clear (C and AC)
- Perform operations * / + and -
- Calculate (on pressing the = button)
- Hmm, what if a user types something into the tempting display box. It seems cruel to simply discard this, so we have to enter this (unless it's rubbish)!
Well. Let's think up names for each of these 'event handlers' and then implement each of them in turn. While we're about it, how are we going to react when a user types something in the display box? Fortunately, there's an event handler tailored to this need. It's called OnChange. Here are our names for the event handlers:
Name | Event | What it does |
AddDigit | OnClick | Add a digit to the display |
Dot | OnClick | Put a decimal point on the display (if not there already) |
DoExponent | OnClick | Put an exponent ('e') on the display |
PlusMinus | OnClick | Change the sign to + if - and minus if plus |
Clear, AllClear | OnClick | Clear and All Clear (C and AC) |
Operate | OnClick | Perform operations * / + and - |
Calculate | OnClick | Calculate (on pressing the = button) |
FixCurrent | OnChange | Process user input |
But before we implement these event handlers, we need to sort out a few more things. First we must define the variables we will use in doing our calculations. Here they are:
Variable | What it stores | |
Memory | The previous number you entered | |
Current | The number currently being entered | |
Operation | The function button you pushed, for example,
|
Finally, we need to define our constants. There is only one:
Constant | What it means |
MAXLENGTH | The maximum number of digits we'll allow a user to input. Let's make it (say) 30. |
Let's get cracking:
1. First, define our constant and global variables
Simple Payout Calculator
The only thing that needs explanation in the above is that we used a numeric code for the Operation. Hmm, perhaps this is a bit over the top. We could just keep the '*' or whatever here as a string. But let's stick with this for the time being!
2. Define individual event handlers
2.1 AddDigit - Adding a digit to the display
JavaScript for AddDigit |
Here we see how we use the variable Current. If Current has exceeded the allowable length, then we replace it with an error message. Otherwise, we append the digit.
See how we use eval to check to see if Current is zero - if it is, then we replace the zero value with the new digit. This is to prevent a leading zero in numbers - pretty important, as in JavaScript, a leading zero is rather peculiarly used to indicate that we're using OCTAL, that is, base eight.
But wait a bit! What if we are busy entering 0.000 and we press say '7'. Unless we check for a decimal, this will replace the 0.000 with 7, which is not what we intended. So we check, using the above code! If Current.indexOf is minus one, this means that there is no decimal point, so we can go on and replace the zero with dig. Otherwise, we simply append the digit to the string in Current.
Then, when everything is over, we store the value in Current into our display area. Note how we do this. We say
document.Calculator.Display.value = Current
(In fact, under Internet Explorer, it's quite okay to leave out the document. portion, as IE works things out for itself. But Netscape will crash and burn if you try this trick). Remember that we called our FORM Calculator, so that's where we got this from, and that we called the <input type='text' > box Display.
The above code can be criticised for several reasons:
- Perhaps we should first do all the processing, and then check the string length;
- What if Current is occupied by an error message - should we not test for this? Hmm;
- We need to handle the case where we are entering the digits for an exponent.
2.2 Dot - Putting in a decimal point
2.3 DoExponent - handling 'times 10an integer'
JavaScript for DoExponent |
2.4 PlusMinus - Changing the sign
2.5 Clear and Clear Entry
JavaScript for the Clear Buttons |
2.6 Respond to pressing * / - + buttons
Create Simple Savings Calculator Javascript Online
JavaScript to respond to press of arithmetic function |
2.7 Calculate!
JavaScript for Calculating results (On pressing the = button) |
2.8 Dealing with stuff typed into the display area
Create Simple Savings Calculator Javascript Tutorial
Putting it all together
Clearly the above functions are only rough drafts. It is however easy to see the actual code that resulted in our simple calculator. Just click View and then Page Source (or the equivalent) on your browser!401k Savings Calculator
This calculator is by no means perfect. See how many errors you can find! (There are no prizes, but we'd appreciate an email if you find something gross). You can have even more fun (if this is the sort of thing that turns you on) by trying to crash the numerous JavaScript Calculators you'll find on the web.
You can now Continue your lesson |
Webpage author jvs@anaesthetist.com | Last update: 2000-10-18 |