The video shown here is a part of our Web Dev with Music Playlist, where we code examples, such as this, in real-time and view the results as we go.
Demo the Live Example
The live example can be viewed in action on this page.
We're going to create a simple calculator which behaves like the Windows calculator app. Let's explicitly outline the behavioral requirements for our app:
- Calculator should evaluate in entry order. In other words: we don't need to wory about PEMDAS.
- For example: 6 + 2 * 3 should be evaluated as 6+2=8, then 8*3 = 24.
- This is how normal "basic" calculators work.
- We must not use
evalto calculate the answer.
- This could potentially pose a security vulnerability, so we will avoid it.
- It should support decimal numbers.
- It should support the following operations:
- User should be able to use the mouse or keyboard to input numbers and operations.
For this analysis, we'll split up our concerns into two categories: ui presentation and calculator logic. In terms of ui presentation, our app will need to:
- Receive user input in the form of buttons clicks and keyboard strokes.
- Present an interface with buttons corresponding to each number and operation.
- Display the number the user is currently typing.
- Display the result when the user hits calculate.
In terms of calculator logic, we will need to:
- Perform a mathematical operation based on a string or token such as "+".
- Keep some type of running history in one of the following ways:
- Keep a list of numbers and operations so far, then calculate everything when the user hits calculate.
- Perform operations each time the user enters a number and operation, then carry over the result.
- Reset the state properly when the user hits Clear.
For this example, we will take approach #2 above, where we perform partial operations and carry the result as we go.
Creating the UI
The first step we will take is to create the HTML elements which will receive input. We will define multiple rows of buttons, each with 4 buttons, except the bottom row which will only have two. Each button will correspond to a number, an operation, or the command to calculate or clear the input. Above the buttons, we will have two display containers, one to display the current number being entered, and the other to display the previous number.
Responding to User Input
onButtonInvokation. The constructor creates event listeners for the buttons and the keystrokes, and in the callback, forwards the data to
onButtonInvokation. We will define that method, and other logic, in the following sections.
Coding the Number Input Logic
With the HTML and event listeners in place, the last thing we'll need to do is implement the core calculator functionality. In order to do so, we will need to handle certain scenarios and states. In terms of number inputs, we have a few states to make sure we account for:
- The user may currently be entering a digit for an integer.
- The user may be entering a digit which comes after the decimal.
- The user may be entering the dot (.), indicating that they are switching from integer digits to decimal digits.
We will need to keep track of which "mode" the number input corresponds to and ensure that when the calculation is made, the digits are correctly placed on the correct sides of the decimal. In the code below, we will be using two variables to keep track of this:
- currentNumber: a string which represents the left side of the decimal. The start value is "0".
- currentNumberDecimal: a string or null which represents the right side of the decimal. If it is null, the overall number will be an integer. If it has a non-null value, the system will treat the overall number as a decimal.
When the time comes to retrieve the full value, we will call a method
Coding the Operation Input Logic
When the user is finished defining the number they want to perform the calculation on, they will select one of the mathematical operations, such as addition, to perform. When this happens, our calculator needs to:
- Handle the previous value:
- If there is no previous value, store the current number as the previous value.
- If there is a previous value, perform the previously entered operation on the current and previous numbers and store that result as the previous value.
- Clear the current number.
- Record the operation which was just selected, which will actually be performed when the user hits "Calculate", or when another operation is selected.
When the user clicks "Calculate!", the logic will be similar, with the exception that we will not be pushing a new operation, nor will we be pushing the current number to the previous number. Instead, the final result will be stored as the current number.
Full Code Implementation
Below, we'll showcase the full code contents which brings everything together: