Member preview

JavaScript HTML Calculator — Simulator

The almost minimalist source code for HTML JavaScript & CSS calculator

Grab your copy of CSS Visual Dictionary incl. diagrams of all CSS properties.

To get a good idea of how flex works try flex layout editor on this page.

HTML calculators are probably one of the most basic web applications you can create. They are definitely a great way to learn JavaScript and web development! It’s basically like making a small app out of lesser parts: in particular HTML and CSS.

This tutorial was inspired by HTML: Intuitive Guide — an HTML book I have been writing for LeanPub. Check it out if you want to support my work.

The HTML Calculator — what does it look like?

No images were used to create this calculator. Visually, it’s all HTML for structure and CSS for styling, gradients and rounded corners.

You can see the working version on this jsfiddle project page: https://jsfiddle.net/wx695acf/166/

HTML Calculator — Final Result.

HTML source code

HTML is used to provide semantic structure of your webpage. But the same rules apply when you’re making a web application. I try to use id attribute for unique parts. It looks cleaner and makes you think of each part of your application individually. Avoid using class or id attributes altogether unless absolutely necessary. For example, note that none of the buttons have ids or classes associated with them. In JavaScript we will determine which button was clicked based on its innerHTML content.

<div id = "frame">
<div id = "brand">HTML ♥ Calculator</div>
<div id = "calculator">
<div id = "history">0</div>
<div id = "view">1000</div>
<div id = "buttons">
<div id = "reset">C</div>
<div></div>
<div>%</div>
<div>/</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>*</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>-</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>+</div>
<div></div>
<div>0</div>
<div>.</div>
<div id = "equals">=</div>
</div>
</div>
<!-- "on" button //-->
<div id = "on"></div>
</div>
<!-- output current queue array //-->
<div id = "message"></div>
<!-- output current number //-->
<div id = "message2"></div>

When writing this tutorial I didn’t want to make just another HTML calculator. My goal was to create one by writing minimum required code. CSS grid to the rescue! You can see how clean HTML is. It should always provide only the semantic structure of your document or app. The harder part is CSS and the hardest is writing the JavaScript. These are the areas in which your code will be the dirtiest, even if you try to minimize it (this is especially true for CSS rather than JavaScript.)

But still… trying to be mindful of your code alone can help bring its length to a minimum… It’s better to plan for clean code than not to.

CSS

    /*--font for all elements--*/
* { font-family: Arial, sans-serif; }
    /*--containers--*/
#frame,
#calculator
{ position: relative; display: block; width: 500px; }
#frame { height: 244px; padding: 16px; background: gray; border-radius: 8px; background: linear-gradient(#555, #000); }
#calculator { height: 400px; margin-top: 29px; }
    /*--the calculator view screen--*/
#history { width: 100%; height: 16px; background: #333; color: #999; text-align: right; box-sizing: border-box; padding: 4px; font-size: 12px; }
#view { width: 100%; height: 28px; background: #333; color: #CCC; text-align: right; font-size: 20px; box-sizing: border-box; padding: 4px; }
    /*--HTML Calculator--*/
#brand { position: absolute; top: 10px; left: 24px; color: gray; font-size: 27px; font-style: italic; }
    /*--this is what determines 4 buttons per row--*/
#buttons { display: grid;
grid-template-columns: auto auto auto auto }
    /*--the rest of button styling--*/
#buttons * { cursor: pointer; background: white; text-align: center; height: 32px; line-height: 32px; }
#buttons * { border: 1px solid #aaa; border-right: unset; border-bottom: unset; }
    /*--button style when mouse is over it--*/
#buttons *:hover {
background: lime; color: #333; font-weight: bold; }
#buttons * { background: linear-gradient(#fff, #bbb); }
    /*--make sure text in buttons cannot be selected--*/
#buttons * {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
    /*--custom button colors--*/
#reset { background: yellow; }
#equals { background: blue; color: white; }
    /*--the on switch in upper right corner--*/
#on { position: absolute; top: 8px; right: 8px; width: 8px; height: 8px; background: linear-gradient(lime, green); border-radius: 16px; border: 1px solid #000; }

There probably is a way to make it even shorter. But dinosauric cross-browser CSS code for making sure text in buttons cannot be selected with the mouse cursor takes more space than most of the other CSS commands.

JavaScript

And finally, at the core of HTML calculator functionality is JavaScript.

/*-- These arrays store the calculator queue & current number --*/
var
queue = new Array();
var current_number = new Array();
var tally = 0;
/*-- In some cases we need to disable digits / action keys --*/
let can_use_actions = false;
let can_use_digits = true;
/*-- Overwrite a common long JavaScript function to "gid" --*/
function gid(id) { return document.getElementById(id); }
function print_queue() {
gid("message").innerHTML = JSON.stringify(queue);
}
function print_current() {
gid("message2").innerHTML = array_to_number(current_number); }
function array_to_number(number) {
return number.toString().replace(/,/gi, ""); }
function reset_history() { gid("history").innerHTML = ""; }
function update_history() {
gid("history").innerHTML = queue.toString().replace(/,/gi, ""); }
/*-- Scroll through all buttons on the calculator --*/
Object.entries(
document.querySelectorAll("#buttons div")).map((element) => {
element[1].addEventListener("click", function(event) {
    // get button value: 0-9,+,-,*,/,C or =
let
value = event.target.innerHTML;
    if (value == "." && current_number.indexOf(".") == -1)
current_number.push(".");
/*-- Digit was pressed -- but don't process,
it if digits cannot be used at this time *--/
    if (can_use_digits) {
if (!isNaN(value) && value != "") {
current_number.push(value);
gid("view").innerHTML = array_to_number(current_number);
print_queue();
print_current();
/*-- At least one digit was entered,
we can use actions again --*/

can_use_actions = true;
}
}
/*-- Process non-digit calculator keys, if enabled --*/
    switch (event.target.innerHTML)
{
case 'C': /*-- Reset view --*/
document.getElementById("view").innerHTML = "0";
queue = new Array();
current_number = new Array();
can_use_actions = false;
can_use_digits = true;
break;
      case '=':        /*-- Reset view --*/
var complete = (queue.toString()+current_number).replace(/,/gi, "");
queue = new Array();
current_number = new Array();
/*-- Assign result to current number in queue --*/
var evaluated = eval(complete);
gid("view").innerHTML = evaluated;
current_number[0] = evaluated;
reset_history();
/*-- We just calculated result,
This result becomes the first number in the queue
Disable digits... and enable actions (+-/*) --*/

can_use_actions = true;
can_use_digits = false;
break;
      case '*':
if (can_use_actions) {
queue.push(array_to_number(current_number));
current_number = new Array();
queue.push("*");
can_use_actions = false;
can_use_digits = true;
}
break;
      case '/':
if (can_use_actions) {
queue.push(array_to_number(current_number));
current_number = new Array();
queue.push("/");
can_use_actions = false;
can_use_digits = true;
}
break;
      case '+':
if (can_use_actions) {
queue.push(array_to_number(current_number));
current_number = new Array();
queue.push("+");
can_use_actions = false;
can_use_digits = true;
}
break;
      case '-':
if (can_use_actions) {
queue.push(array_to_number(current_number));
current_number = new Array();
queue.push("-");
can_use_actions = false;
can_use_digits = true;
}
break;
default:

update_history();
break;
}
/*-- Display what's in queue array now just for reference --*/
print_queue();
 });
});

You can see this JavaScript HTML calculator in action at https://jsfiddle.net/wx695acf/166/

Thanks for reading!