Every software app can be written in more ways, so I hope that you like mine.
I started this little project as a challenge for myself to see how hard is to build a poket calculator interface. First I made just the body, buttons for the Numbers and for the Math operations and the screen. As the project advanced I added the switch buttons for Lights and Timer (autoclose) , then a Clear screen and a Delete buttons. After I added an On/Off button. Then I thinked that would be cool to add a history for operations, so I made the screen larger. After that I thinked that if I arrived until here would be cool to add a keyboard suport too. So initialy I developed this app just for the UI, building the calculator with the help of CSS (Bootstrap + CSS) and HTML (PUG), then I added the push buttons simulation and the lights on keyboard and screen with the help of CSS and JavaScript. After that I added a little code to intercept the click events for buttons and to add suport for math operations, and of course, to display the results on the screen. In the end, the easyest part was to add suport for keyboard keys.
Even if I wrote the code using a Node server for auto refresh the browser window, I choosed to use just one file for JavaScript. So at least for now, the js code isn't split in MVC model. Anyhow, I think that is good app to exercise the base of JavaScript, because in the code I covered a lot of principles. The code is very well commented.
You can see the app online on https://codepen.io/smcstylus/full/Yzxzzqy (for some reasons the history doesn't appear on codepen)
- HTML: PUG template engine
- CSS: CSS3, Bootstrap 5
- JavaScript: Vanila JS (ES6), jQuery 3.4.1
- Fonts: FontAvesome5, Urbanist, Quicksand
- Interface
- Simulate the press of the UI buttons when the (laptop/keyboard..) trackpad or on mobile screens is clicked, or keyboard keys are pressed/released
- On/Off button
- Autoclose (timer) switch. Reset timer on each UI button or keyboard only on allowed keys pressed.
- Lights switch (lighten buttons and the screen)
- Clear screen button
- Backspace (delete) button
- Decimal button
- Numbers buttons
- Math buttons
- Autosize entire calculator by changing just the "--numPad-size" value in the CSS file
- Display
- Display history of operations with all the operations. Scrollable area. Autoscroll to last result when is inserted (hit "Enter" or "=" keys").
- Display previous result
- Display current operation sign
- Display curent number
- Others
- Use UI buttons or keyboard keys
- Use JavaScript object as memory to store different variables
- Use custom decimals (0 - 8). To be set in calcMemory constant
- Math operations: + - * / % sqrt
- Keyboard Shortcuts
- p - On/Off
- c - Clear Screen
- l - Switch Ligts
- t - Switch Timer
- q - sqrt
- 0-9
- +
- -
- /
- *
- = or Enter - equal
- Delete or Backspace - delete
macOs Hight Siera - Firefox, Chrome, Opera GX
Android
I don't studied a pocket calculator to see the results for long numbers, so the math part is not to precisely. I suggest you to replace that part of code ( computeMath(), doMath(), mathFunctions() ) with your if you want to use this app in one of your projects. I limited more parts so please do it in a propper way if you will use it.
Below you can see what I used to build the JavaScipt code:
let
const
`My text followed by ${javascript}`
string.length
str.split(separator)
string.trim()
string.substring(start, length)
string.indexOf(needle)
string.toLowerCase()
string.endsWith(value)
number.toFixed(decimals_nr)
isNaN(value)
parseInt(value)
parseFloat(value)
Number.MAX_VALUE
Number.MIN_VALUE
Number.MAX_SAFE_INTEGER
Number.MIN_SAFE_INTEGER
!=
!==
===
<
>
&&
||
object?.key
+
-
*
/
!!~
+=
Math.sqrt(nr)
if
else if
else
istrue ? cond1 : cond2
switch(cond){
case a:
// code block to be executed
breake;
case b:
// code block to be executed
break;
default:
// code block to be executed
}
let myObject1 = {
key1 : value1,
Key2 : value2,
}
const myObject2 = {
key1: {
key11 : value11,
},
key2 : value2
key3 : [value31, value32,value33],
};
let object = {
var1 : val1,
var2 : val2,
};
let {var1, var2} = object;
array.push(new_value)
array.includes(condition)
array.indexOf(needle)
parent.getElementById(element_id)
parent.getElementsByTagName(tag_name)
parent.createElement(child_tag_name)
parent.removeChild(child)
parent.appendChild(new_element)
element.setAttribute(attribute, value)
element.createTextNode(string)
element.blur()
const myFunction = () => returned;
const myFunction = (arguments) => {
// code block to be executed
};
function myFunction() {
// code block to be executed
}
(function () {
// code block to be executed
})();
const myFunc = (argument = default_value) => {}
for(let i=x; i<y; i++){
// code block to be executed
}
for (let element in object) {
// code block to be executed
}
break; // used in for in this case
event.preventDefault()
event.key
setTimeout(function() {
// code
}, milliseconds)
let timer = setInterval(function(){
//code
}, milliseconds);
clearInterval(timer);
JSON.stringify(object)
JSON.parse(string)
string.replace(/"/g, "'")
.on("click", function(e))
.on("mousedown", function(e){})
.on("mouseup", function(e){})
.on("mouseleave", function(e){})
.keydown(function(e){})
.keyup(function(e){})
.on("change", function(e){})
$(this)
.is(":checked")
.find(selector)
.text(myText)
.html(myHTML)
.append(element)
.addClass()
.removeClass()
.scrollTop(value)
.position()
.prop(propertyName)
$(elements).each(function(index){});
MIT
Free Software!