How to Build a Simple Web Calculator
Using TypeScript and Custom Elements
Building a calculator is a great project when you’re still learning about JavaScript/TypeScript. In this tutorial, you will be taken through the HTML, CSS, and TypeScript behind the calculator. This project will be built without a JavaScript framework and will be using a TypeScript starter project for the basic set-up of build tools.
If you want to know more about how this starter project came to be, you can read more in my post on how to make your own TypeScript starter project.
The Project
You can see the finished hosted version of this calculator on Netlify.
The Markup
The markup is very simple. The root element will be a custom element called <ws-calculator>. Inside this, there will be a display section and a button section.
The Styling
The styling is straightforward but uses a CSS grid for the buttons. This allows you to nicely position the ‘=‘ button over two rows.
The Logic
The calculator will be a custom element called ws-calculator
. This means you need to start with a class that extends the HTMLElement class.
If you’re following along with the TypeScript starter project, this should go in app.ts
.
The class needs to keep track of several things:
- The display element
- The button elements
- The current query to calculate
Let’s create several properties to hold this data. Additionally, let’s create a getter and setter for the query property. This allows you to perform extra logic when the query changes.
Now that the class can take care of the data, you need to set up the event listeners for the button clicks. Custom elements have two automatically invoked functions that will be useful in this project:
- connectedCallback — this function is invoked each time the custom element is appended into a document-connected element.
- disconnectedCallback — this function is invoked each time the custom element is disconnected from the document’s DOM.
The event listeners should be bound on the connectedCallback and unbound on the disconnectedCallback. This will prevent events to be double-bound if the calculator is moved or re-added.
Handling the button click
When you click on any button, it will trigger the handleButtonClick
method. We should determine the value of the button, but also the user value. For example, the * sign is used to perform multiplication, but on the display, you want to show the ‘x’ character.
Most buttons should add a character to the display. However, there are three buttons that have different functions:
- The AC button should clear the display.
- The CE button should remove the last character from the display.
- The = button should perform a calculation.
Let’s implement a simple switch statement to handle these different inputs.
The performCalculation
doesn’t exist yet, let’s add it as an empty function for now.
Updating the display
The query
property is now updated when buttons are clicked, but they aren’t updated on the screen yet. Let’s create a method to update the display and call the method from the query
setter method.
You should now have an almost working calculator that updates the display, can clear the display and can remove the last character. It’s time to implement the final function to perform a calculation.
Performing the calculation
There are many ways to perform a calculation based on our query. We could parse the values in between the operators and perform logic to calculate the outcome. For the purposes of this tutorial, the eval()
method will be used.
The eval()
method is a global function property that takes a string as an argument. If the string in question represents an expression, the expression is evaluated and the result is returned.
It is not advised to use eval in a production setting since it can pose security risks if third parties can alter the string. But for this simple tutorial, it is safe to use.
In this method, the multiplication and division characters are replaced by characters JavaScript understands, the query is run through the eval method and the answer is formatted to a string that is rounded up to two decimal points. Finally, the query is updated with the formatted answer, so you can either chain more calculations or be satisfied with the result.
This marks the end of the tutorial. You have just build a fully functioning calculator using TypeScript and the custom elements spec.
The GitHub repository contains the full code for this project if you want to take a look.
LEAVE A REPLY
Your email address will not be published. Required fields are marked *