Introduction
Scientific Calculator ZENO-5000 is a lightweight web application (<40kb), utilizing the latest HTML5/CSS3 features and client-side jQuery/Java scripting. The application does not include any graphic files. It is portable, capable of running in online/offline modes on PC/mobile devices.
Background
Calculators software implemented as web “thin client” apps require the “live” Internet connection. There are certain pros and cons in such approach: “thin client” web applications are “zero-installable” and platform/OS independent, thus portable/capable of running in any major web browser (it’s relevant to mention, that web browsers are rapidly becoming de facto a “virtual OS”, kind of substitute for real OS in regards to the web applications and services). But, the need for Internet connectivity presents certain limitation; it's highly desirable to have the calculator application, capable of running in off-line mode as well. A possible solution is implementing the app via just client-scripting, primarily JavaScript code, which is compatible with any major web browser. Such web app could either run in online mode as usual, or it could be downloaded and cached on the client’s platform.
A possible solution is to implement the application utilizing just client-scripting, primarily JavaScript code, which is compatible with practically any major existing web browser. Such web application could either run in online mode as usual, or it could be downloaded and cached on the client’s platform, available in offline mode as well. There are several core requirements to such “universal” solutions:
- It must be platform/OS independent, capable of running within 4 major browsers (Mozilla Firefox, Internet Explorer from Microsoft, Google Chrome and Apple Safari)
- Installation process must be simple and straightforward, just as “copy-paste”
- It should have an extremely small “digital footprint” considering the potential memory space limitations on the portable devices
Adherence to the above mentioned design principle would ensure the high portability of OSC and its compliance with the majority of available mobile/stationary computational platforms.
Scientific Calculator ZENO-5000, Sample Screenshots
Fig.1. Scientific Calculator ZENO-5000 sample screen shot showing the extended key pad
Fig.2. Scientific Calculator ZENO-5000: sample screen shot showing stack register pop-up
Core Functionality
- Data Entry operations: In simple words, that means clicking on any numeric key, or just entering the constant values, like number pi, e, square root of 2, etc.
- Unary operations: These are to be performed directly on the content of the input box, like inverse function 1/x, or trigonometric sin(x).
- Binary operations to be performed on the pair of numeric values: one of them stored in the internal memory register called “stack” and the second number shown in the input box. This type includes all four arithmetic operations, exponent calculation (y^x, which stands for “y power x”) and percent calculation.
Memory operations are implemented in practically every modern calculator. This convenient feature allows the intermediate results to be stored in internal memory register for later use. In brief, memory operations include the following:
- Move/Copy the content of the input box to the memory (use down arrow key)
- Move/Copy the content of the memory to the input box (use up arrow key)
- Clear Memory: Click on the memory box (just below the input box) to clear the content
- Add to Memory (use the key labeled as M+)
- Subtract from Memory (use the key labeled as M-)
Application Architecture
Online Scientific Calculator ZENO-5000 (hereinafter – ZENO) is implemented as Rich Internet Application, utilizing the latest features presented in emerging Internet standards (HTML5/CSS3) and client-side scripting (jQuery/JavaScript). It could run in major web browsers in either online, or offline modes: to utilize the latter, application files must be downloaded and stored on the client’s computer. These files include:
- Main file: zeno.htm (file contains dynamic link to jQuery library online)
- Style sheet (CSS) file: oscZeno.css
- Computational engine written in Javascript: oscZeno.js
- Reference file: oscZenoRef.js
Binary operations involve the “stack” memory register (variable stackValue
), storing the first operand. Another variable opCode
stores the operation code:
0-no operation
1-Addition
2-Subtraction
3-Multiplication
4-Division
5-power (y^x)
6-percent
The operations are performed on the content of the stack and numeric value entered into the input box. Auxiliary register (var boolClear
) provides “clear input box before next data entry” functionality: it stores the Boolean value, forcing the code to clear the input register before another numeric value could be entered.
Points of Interest
Scientific Calculator ZENO-5000 is fully compatible with Mozilla/Webkit based Web Browsers, presumably with Internet Explorer 9. It has been tested on various desktop and mobile platforms (iPod Touch (Safari) and Windows Phone 7).
Project ZENO-5000 does not utilize any image files, thus having an extremely small digital footprint. All aesthetic enhancements achieved through the novel features are introduced in HTML 5/ CSS 3, namely: rounded corners, gradients, drop-shadows, etc. The most innovative HTML 5/CSS 3 coding techniques are demonstrated below:
Listing 1: CSS 3 code snippet is used to add the shadows to the screen objects (note: no graphic images required).
-moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
-webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
Listing 2: CSS 3 code snippet used to implement the rounded corners (note: no graphic images required).
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
Listing 3: CSS 3 code snippet used to create the color gradient (does not work in IE<9).
background: -webkit-gradient(linear, left top, right top from(#ffffcc), to(#ffffff));
background: -moz-linear-gradient(left top, #ffffcc, #ffffff);
Listing 4: jQuery code snippet performs a short animation on document load event, demonstrating the toggle features. Initially, the sliding panel is shown in collapsed mode (Fig.3).
$(document).ready(function () {
$("div.oscExtControl").fadeTo(1000, 0.25,
function () { $("div.oscExtControl").fadeTo(1000, 1.00); });
$("div.oscExtPanel").slideToggle("fast");
$("div.oscStackRegister").slideToggle("normal");
Listing 5: jQuery code snippet enables the panel slide (toggle) on control button click (see the Fig.1,2, showing the extended panel)
$("div.oscExtControl").click(function () {
var ctl = $(this);
$("div.oscExtPanel").slideToggle("fast", function () {
oscExtState = !oscExtState;
if (oscExtState) ctl.html(strLess); else ctl.html(strMore);
});
});
Listing 6: Available Unary operations apply directly to the content of the input box.
$("button.keyPad_btnUnaryOp").click(function () {
var inputBox = $(keyPad_UserInput);
var x = parseFloat(inputBox.val());
var retVal = oscError;
switch (this.id) {
case 'keyPad_btnInverseSign': retVal = -x; break;
case 'keyPad_btnInverse': retVal = 1 / x; break;
case 'keyPad_btnSquare': retVal = x * x; break;
case 'keyPad_btnSquareRoot': retVal = Math.sqrt(x); break;
case 'keyPad_btnCube': retVal = x * x * x; break;
case 'keyPad_btnCubeRoot': retVal = Math.pow(x, 1 / 3); break;
case 'keyPad_btnLn': retVal = Math.log(x); break;
case 'keyPad_btnLg': retVal = Math.log(x) / Math.LN10; break;
case 'keyPad_btnExp': retVal = Math.exp(x); break;
case 'keyPad_btnSin': retVal = Math.sin(x); break;
case 'keyPad_btnCosin': retVal = Math.cos(x); break;
case 'keyPad_btnTg': retVal = Math.tan(x); break;
case 'keyPad_btnCtg': retVal = 1 / Math.tan(x); break;
case 'keyPad_btnAsin': retVal = Math.asin(x); break;
case 'keyPad_btnAcos': retVal = Math.acos(x); break;
case 'keyPad_btnAtan': retVal = Math.atan(x); break;
case 'keyPad_btnSec': retVal = 1 / Math.cos(x); break;
case 'keyPad_btnCosec': retVal = 1 / Math.sin(x); break;
case 'keyPad_btnSinH':
retVal = (Math.pow(Math.E, x) - Math.pow(Math.E, -x)) / 2; break;
case 'keyPad_btnCosinH':
retVal = (Math.pow(Math.E, x) + Math.pow(Math.E, -x)) / 2; break;
case 'keyPad_btnTgH':
retVal = (Math.pow(Math.E, x) - Math.pow(Math.E, -x));
retVal /= (Math.pow(Math.E, x) + Math.pow(Math.E, -x));
break;
case 'keyPad_btnSecH':
retVal = 2 / (Math.pow(Math.E, x) + Math.pow(Math.E, -x)); break;
case 'keyPad_btnCosecH':
retVal = 2 / (Math.pow(Math.E, x) - Math.pow(Math.E, -x)); ; break;
case 'keyPad_btnOnePlusX': retVal = 1 + x; break;
case 'keyPad_btnOneMinusX': retVal = 1 - x; break;
default: break;
}
boolClear = true;
inputBox.val(retVal);
inputBox.focus();
});
Listing 7: jQuery code snippet to clear memory by clicking on the memory box (optionally, could apply to input box as well)- particular valuable convenience feature in touch-screen mobile devices (iPhone, WP7, etc.).
$("div#keyPad input.keyPad_TextBox").click(function () {
var inBox = $(keyPad_UserInput);
var mem = $(keyPad_Mem);
switch (this.id) {
case 'keyPad_Mem': $(keyPad_Mem).val(strEmpty); memVal = 0; break;
default: break;
}
});
Listing 8: Available constants to be entered directly in extended mode (expanded panel).
$("button.keyPad_btnConst").click(function () {
var retVal = strEmpty;
switch (this.id) {
case 'keyPad_btnPi': retVal = Math.PI; break;
case 'keyPad_btnPiDiv2': retVal = Math.PI / 2; break;
case 'keyPad_btnPiDiv3': retVal = Math.PI / 3; break;
case 'keyPad_btnPiDiv4': retVal = Math.PI / 4; break;
case 'keyPad_btnPiDiv6': retVal = Math.PI / 6; break;
case 'keyPad_btnE': retVal = Math.E; break;
case 'keyPad_btnInvE': retVal = 1 / Math.E; break;
case 'keyPad_btnSqrt2': retVal = Math.SQRT2; break;
case 'keyPad_btnSqrt3': retVal = Math.sqrt(3); break;
case 'keyPad_btnCubeRoot2': retVal = Math.pow(2, 1 / 3); break;
case 'keyPad_btnLn10': retVal = Math.LN10; break;
case 'keyPad_btnLgE': retVal = Math.LOG10E; break;
case 'keyPad_btnSigma': retVal = 0.69; break;
case 'keyPad_btnSigma3': retVal = 0.007; break;
case 'keyPad_btnSigma6': retVal = 3.4 * Math.pow(10, -6); break;
default: break;
}
boolClear = true;
$(keyPad_UserInput).val(retVal);
inputBox.focus();
});
Listing 9: Entire CSS file:
body {
margin: 0;
padding: 0;
font-family: Arial, Calibri, Verdana, Tahoma, Times New Roman ;
text-align: center;
vertical-align: middle;
background-color: #eaeaea;
}
.oscCenterColumn {
width: 480px;
padding: 10px 0px 0px 0px;
margin: 10px auto;
text-align: left;
}
.oscMain {
padding:10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
-moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
-webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
background: -webkit-gradient(linear, left top, left bottom,
from(#404040), to(#707070));
background: -moz-linear-gradient(top, #404040, #707070);
}
header, footer, nav { display:block }
.oscTitle {
float:right;
margin:0px 0px 0px 0px;
font-size: 24px;
font-weight:lighter;
color: #dadada;
vertical-align:middle;
}
.oscModel {
text-align:center;
height:30px;
line-height:30px;
background-color: #303030;
vertical-align:middle;
}
.oscModel {
width: 150px;
margin:0px 0px 0px 0px;
font-size: 24px;
font-weight:bold;
color: yellow;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
}
button.oscNav
{
float:left;
height:30px;
line-height:30px;
vertical-align:middle;
font-size: 14px;
font-family: Arial, Tahoma, Verdana, Calibri;
color: #bababa;
margin: 0px 0px 0px 3px;
padding: 0px 5px 0px 5px;
border: 1px solid olive;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
background: #505050;
background: -moz-linear-gradient(top, #909090, #505050 15px, #303030 15px, #202020);
background: -webkit-gradient(linear, left top, left bottom, from(#909090),
color-stop(0.5, #505050), color-stop(0.5, #303030), to(#202020));
cursor: pointer;
cursor: hand;
}
a { text-decoration:none;}
button.oscNav:active { border: solid 2px #dadada; }
button.oscNav:hover {
background: #454545;
background: -moz-linear-gradient(top, #505050, #202020 20px, #303030 20px, #909090);
background: -webkit-gradient(linear, left top, left bottom, from(##505050),
color-stop(0.5, #202020), color-stop(0.5, #303030), to(##909090));
}
.oscExtControl, .oscStackControl
{
float:right;
margin:0px 0px 0px 5px;
width:60px;
height:30px;
line-height:30px;
vertical-align:middle;
text-align:center;
background-color: olive;
color: #dadada;
font-size: 22px;
font-weight:bold;
cursor: pointer;
cursor: hand;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
.oscStackRegister
{
position:absolute;
width:310px;
height:30px;
line-height:30px;
vertical-align:middle;
margin:5px 0px 0px 10px;
font-size: 22px;
font-weight:normal;
text-align:center;
color:#eaeaea;
background-color:Olive;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
filter:alpha(opacity=90);
-moz-opacity:0.9;
opacity: 0.9;
z-index:20;
cursor: pointer;
cursor: hand;
}
.oscExtPanel
{
margin:0px;
padding: 5px 5px 5px 5px;
display:block;
background-color:#404040;
border: solid 1px Olive;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
div#keyPad { width: 100%; }
.keys_ToRight { float:right; }
div#keyPad input, div#keyPad button
{
height: 40px;
vertical-align:middle;
line-height:40px;
margin: 0px;
padding: 0px;
border: 1px solid olive;
font-family: Arial, Tahoma, Verdana, Calibri;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
}
div#keyPad button {
width: 60px;
text-align: center;
font-size: 20px;
cursor: pointer;
cursor: hand;
color: #dadada;
font-weight:bold;
background:#404040;
background: -moz-linear-gradient(top, #dadada, #505050 20px, #303030 20px, #202020);
background: -webkit-gradient(linear, left top, left bottom, from(#dadada),
color-stop(0.5, #505050), color-stop(0.5, #303030), to(#202020));
}
div#keyPad button:active { border: solid 2px #707070; }
div#keyPad button:hover {
background: #454545;
background: -moz-linear-gradient(top, #505050, #202020 20px, #303030 20px, #909090);
background: -webkit-gradient(linear, left top, left bottom, from(##505050),
color-stop(0.5, #202020), color-stop(0.5, #303030), to(##909090));
}
div#keyPad input {
width: 330px;
text-align: left;
text-indent:10px;
font-size: 24px;
color: #202020;
background: -webkit-gradient(linear, left top, right top from(#ffffcc), to(#ffffff));
background: -moz-linear-gradient(left top, #ffffcc, #ffffff);
}
div#keyPad input#keyPad_Mem {color: #909090;}
div#keyPad button#keyPad_btnEnter { width:188px; font-size: 20px; color:Yellow;}
div#keyPad .keyPad_btnMemOp
{ font-size: 20px; color: Olive;}
div#keyPad button#keyPad_btn0
{ width: 125px; }
div#keyPad button#keyPad_btnBack,
div#keyPad button#keyPad_btnClr,
div#keyPad button#keyPad_btnAllClr
{
border-color:red;
color:red;
}
div#keyPad button#keyPad_btnBack {font-size: 18px;}
div#keyPad button#keyPad_btnSquare,
div#keyPad button#keyPad_btnCube,
div#keyPad button#keyPad_btnExp,
div#keyPad keyPad_btnYpowX
{ font-size: 16px; }
.clear {clear:both;}
.oscDisclaimer
{
margin: 5px 0px 5px 0px;
color: #adadad;
font-weight: normal;
font-size: 10pt;
text-align:center;
}
.oscNotice {
margin-top:5px;
text-align:center;
font-size: 12px;
color: #606060;
}
.oscSpacer2, .oscSpacer3, .oscSpacer5 {clear:both; width:100%;}
.oscSpacer2 {height:2px;}
.oscSpacer3 {height:3px;}
.oscSpacer5 {height:5px;}
#ie { background-color: #303030; }
Listing 10: JavaScript computational engine and jQuery animation enhancement:
$(document).ready(function () {
$("div.oscExtControl").fadeTo(1000, 0.25,
function () { $("div.oscExtControl").fadeTo(1000, 1.00); });
$("div.oscExtPanel").slideToggle("fast");
$("div.oscStackRegister").slideToggle("normal");
$("div.oscStackControl").mouseover(function () {
var ctl = $("div.oscStackRegister");
var op = "";
if (opCode == 1) op = " +";
else if (opCode == 2) op = " -";
else if (opCode == 3) op = " *";
else if (opCode == 4) op = " /";
ctl.html(stackVal + op);
ctl.show(300);
})
.mouseout(function () { $("div.oscStackRegister").hide(); })
.mouseleave(function () { $("div.oscStackRegister").hide(); });
$("div.oscStackRegister").click(function ()
{ $("div.oscStackRegister").hide(); });
$(this).click(function () { $("div.oscStackRegister").hide(); });
$("div.oscMemLabel").click(function ()
{ $(keyPad_Mem).val(strEmpty); memVal = 0; });
$("div.oscExtControl").click(function () {
var ctl = $(this);
$("div.oscExtPanel").slideToggle("fast", function () {
oscExtState = !oscExtState;
if (oscExtState) ctl.html(strLess); else ctl.html(strMore);
});
});
$("div#keyPad button.keyPad_btnNumeric").click(function () {
var btnVal = $(this).html();
var inBox = $(keyPad_UserInput);
if (boolClear) { inBox.val(strEmpty); boolClear = false; }
var str = inBox.val();
if (str.length > maxLength) return;
if (this.id == "keyPad_btnDot" && str.indexOf('.') >= 0) return;
inBox.val(str + btnVal);
inBox.focus();
});
$("button.keyPad_btnConst").click(function () {
var retVal = strEmpty;
switch (this.id) {
case 'keyPad_btnPi': retVal = Math.PI; break;
case 'keyPad_btnPiDiv2': retVal = Math.PI / 2; break;
case 'keyPad_btnPiDiv3': retVal = Math.PI / 3; break;
case 'keyPad_btnPiDiv4': retVal = Math.PI / 4; break;
case 'keyPad_btnPiDiv6': retVal = Math.PI / 6; break;
case 'keyPad_btnE': retVal = Math.E; break;
case 'keyPad_btnInvE': retVal = 1 / Math.E; break;
case 'keyPad_btnSqrt2': retVal = Math.SQRT2; break;
case 'keyPad_btnSqrt3': retVal = Math.sqrt(3); break;
case 'keyPad_btnCubeRoot2': retVal = Math.pow(2, 1 / 3); break;
case 'keyPad_btnLn10': retVal = Math.LN10; break;
case 'keyPad_btnLgE': retVal = Math.LOG10E; break;
case 'keyPad_btnSigma': retVal = 0.69; break;
case 'keyPad_btnSigma3': retVal = 0.007; break;
case 'keyPad_btnSigma6': retVal = 3.4 * Math.pow(10, -6); break;
default: break;
}
boolClear = true;
$(keyPad_UserInput).val(retVal);
inputBox.focus();
});
$("div#keyPad button.keyPad_btnBinaryOp").click(function () {
var inBox = $(keyPad_UserInput);
var newOpCode = 0;
if (inBox.val().indexOf('-') >= 0) return;
if (inBox.val().indexOf('+') >= 0) return;
if (inBox.val().indexOf('*') >= 0) return;
if (inBox.val().indexOf('÷') >= 0) return;
switch (this.id) {
case 'keyPad_btnPlus': newOpCode = 1; break;
case 'keyPad_btnMinus': newOpCode = 2; break;
case 'keyPad_btnMult': newOpCode = 3; break;
case 'keyPad_btnDiv': newOpCode = 4; break;
case 'keyPad_btnYpowX': newOpCode = 5; break;
case 'keyPad_btnPercent':
if (opCode == 1 || opCode == 2)
{ inBox.val(stackVal * parseFloat(inBox.val()) / 100); }
else if (opCode == 3 || opCode == 4)
{ inBox.val(parseFloat(inBox.val()) / 100); }
else return;
break;
default: break;
}
if (opCode) { oscBinaryOperation(); }
else { stackVal = parseFloat(inBox.val()); boolClear = true; }
opCode = newOpCode;
inBox.focus();
});
function oscBinaryOperation() {
var inBox = $(keyPad_UserInput);
var x2 = parseFloat(inBox.val());
switch (opCode) {
case 1: stackVal += x2; break;
case 2: stackVal -= x2; break;
case 3: stackVal *= x2; break;
case 4: stackVal /= x2; break;
case 5: stackVal = Math.pow(stackVal, x2); break;
default: break;
}
inBox.val(stackVal);
boolClear = true;
inBox.focus();
}
$("button.keyPad_btnUnaryOp").click(function () {
var inputBox = $(keyPad_UserInput);
var x = parseFloat(inputBox.val());
var retVal = oscError;
switch (this.id) {
case 'keyPad_btnInverseSign': retVal = -x; break;
case 'keyPad_btnInverse': retVal = 1 / x; break;
case 'keyPad_btnSquare': retVal = x * x; break;
case 'keyPad_btnSquareRoot': retVal = Math.sqrt(x); break;
case 'keyPad_btnCube': retVal = x * x * x; break;
case 'keyPad_btnCubeRoot': retVal = Math.pow(x, 1 / 3); break;
case 'keyPad_btnLn': retVal = Math.log(x); break;
case 'keyPad_btnLg': retVal = Math.log(x) / Math.LN10; break;
case 'keyPad_btnExp': retVal = Math.exp(x); break;
case 'keyPad_btnSin': retVal = Math.sin(x); break;
case 'keyPad_btnCosin': retVal = Math.cos(x); break;
case 'keyPad_btnTg': retVal = Math.tan(x); break;
case 'keyPad_btnCtg': retVal = 1 / Math.tan(x); break;
case 'keyPad_btnAsin': retVal = Math.asin(x); break;
case 'keyPad_btnAcos': retVal = Math.acos(x); break;
case 'keyPad_btnAtan': retVal = Math.atan(x); break;
case 'keyPad_btnSec': retVal = 1 / Math.cos(x); break;
case 'keyPad_btnCosec': retVal = 1 / Math.sin(x); break;
case 'keyPad_btnSinH':
retVal = (Math.pow(Math.E, x) - Math.pow(Math.E, -x)) / 2; break;
case 'keyPad_btnCosinH':
retVal = (Math.pow(Math.E, x) + Math.pow(Math.E, -x)) / 2; break;
case 'keyPad_btnTgH':
retVal = (Math.pow(Math.E, x) - Math.pow(Math.E, -x));
retVal /= (Math.pow(Math.E, x) + Math.pow(Math.E, -x));
break;
case 'keyPad_btnSecH':
retVal = 2 / (Math.pow(Math.E, x) + Math.pow(Math.E, -x)); break;
case 'keyPad_btnCosecH':
retVal = 2 / (Math.pow(Math.E, x) - Math.pow(Math.E, -x)); ; break;
case 'keyPad_btnOnePlusX': retVal = 1 + x; break;
case 'keyPad_btnOneMinusX': retVal = 1 - x; break;
default: break;
}
boolClear = true;
inputBox.val(retVal);
inputBox.focus();
});
$("div#keyPad button.keyPad_btnCommand").click(function () {
var inBox = $(keyPad_UserInput);
var mem = $(keyPad_Mem);
var strInput = inBox.val();
switch (this.id) {
case 'keyPad_btnEnter':
inBox.val(oscBinaryOperation()); opCode = 0; inBox.focus(); return;
case 'keyPad_btnClr':
if (strInput == strEmpty) { opCode = 0; boolClear = false; }
else { inBox.val(strEmpty); }
break;
case 'keyPad_btnBack': if (strInput.length > 0) {
inBox.val(strInput.substring(0, strInput.length - 1)); break;
}
case 'keyPad_btnAllClr':
inBox.val(strEmpty);
stackVal = strEmpty;
mem.val(strEmpty);
opCode = 0;
break;
default: break;
}
});
$("div#keyPad button.keyPad_btnMemOp").click(function () {
var inBox = $(keyPad_UserInput);
var mem = $(keyPad_Mem);
try {
memValNumeric = parseFloat(mem.val());
}
catch (ex)
{ memVal = strEmpty; mem.val(strEmpty); return; }
switch (this.id) {
case 'keyPad_btnToMem': mem.val(inBox.val()); inBox.val(strEmpty); break;
case 'keyPad_btnFromMem': inBox.val(mem.val()); break;
case 'keyPad_btnMemPlus':
memVal += parseFloat(inBox.val()); mem.val(memVal);
boolClear = true; break;
case 'keyPad_btnMemMinus':
memVal -= parseFloat(inBox.val()); mem.val(memVal);
boolClear = true; break;
default: break;
}
});
$("div#keyPad input.keyPad_TextBox").click(function () {
var inBox = $(keyPad_UserInput);
var mem = $(keyPad_Mem);
switch (this.id) {
case 'keyPad_Mem': $(keyPad_Mem).val(strEmpty); memVal = 0; break;
default: break;
}
});
})
History
Online Scientific Calculator ZENO-5000 was started as an educational project, intended to demonstrate the power of emerging Internet standards and, namely: HTML 5 and CSS 3, accompanied by increasingly popular jQuery (extension to JavaScript). ZENO is implemented as rich internet application (RIA) with an extremely small digital footprint. It does not use any graphic files: all aesthetic enhancements, like color gradients, rounded corners, box shadows, etc., are achieved via new features available in HTML5/CSS 3, thus dramatically simplifying the page layout design and ensuring fast application load. Project ZENO provides deep insight into web applications client-side coding technique, intended primarily for the didactic purpose. Later it was extended with engineering functions, resulting in rather popular online Engineering Calculator "VOLTA"