MyJSCalculator - a simple javascript calculator

Coding Critique is the place to post source code for peer review by other members of DevNetwork. Any kind of code can be posted. Code posted does not have to be limited to PHP. All members are invited to contribute constructive criticism with the goal of improving the code. Posted code should include some background information about it and what areas you specifically would like help with.

Popular code excerpts may be moved to "Code Snippets" by the moderators.

Moderator: General Moderators

Post Reply
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

MyJSCalculator - a simple javascript calculator

Post by s.dot »

The Calculator

MyJSCalculator is a simple calculator that uses javascript to do the math. The calculator display is built with HTML and CSS. It does not use any images, so the filesize is minimal.
Features

* It's completely free. Released under the GNU GPL (General Public License).
* Designed to imitate the Windows©™ built in standard calculator.
* Small in filesize and in display.
* Easily change the appearance by editing the stylesheet.

Limitations
* Requires the end user to have javascript enabled in their web browser.

myjscalculator.html

Code: Select all

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
MyJSCalculator - A simple HTML/CSS/JavaScript calculator.

Copyright (C) 2007 Scott Martin <smp_info[at]yahoo[dot]com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-->
<head>
<title>MyJSCalculator</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
<link rel="stylesheet" href="myjscalculator.css" type="text/css" media="all" />
</head>
<body>

<!--
 If you're going to embed this into your web pages, the important part is below.  However,
 Don't forget to use the stylesheet, too!
-->
<noscript><big><strong>You must enable javascript in your web browser to use this calculator</strong></big></noscript>
<table cellspacing="2" cellpadding="1" border="0" style="border: solid 1px #000; background-color: #ADD8E6;">
	<tr>
		<td colspan="6"><a href="http://www.scottayy.com/myjscalculator" class="calcName" target="_blank">MyJSCalculator</a></td>
	</tr>
	<tr>
		<td colspan="6"><input id="calcDisplay" class="display" type="text" readonly="readonly" value="0" /></td>
	</tr>
	<tr>
		<td><span id="calcMem" class="mem">&nbsp;</span><input type="text" id="calcMemValue" value="" style="display: none;" /></td>
		<td colspan="5" style="padding: 0;">
			<table cellspacing="2" cellpadding="1" border="0" align="right">
				<tr>
					<td onclick="backspace();"><input class="buttonLeft" type="button" value="Backspace" style="width: 70px;" /></td>
					<td onclick="clearEntry();"><input class="buttonLeft" type="button" value="CE" /></td>
					<td style="margin-right: 0;" onclick="clearNum();"><input class="buttonLeft" type="button" value="C" /></td>
				</tr>
			</table>
		</td>
	</tr>
	<tr>
		<td onclick="memoryC();"><input class="buttonLeft" type="button" value="MC" /></td>
		<td onclick="concatNum(7);"><input class="button" type="button" value="7" /></td>
		<td onclick="concatNum(8);"><input class="button" type="button" value="8" /></td>
		<td onclick="concatNum(9);"><input class="button" type="button" value="9" /></td>
		<td onclick="operate('divide');"><input class="button" type="button" value="/" /></td>
		<td onclick="numSqrt();"><input class="button" type="button" value="sqrt" /></td>
	</tr>
	<tr>
		<td onclick="memoryR();"><input class="buttonLeft" type="button" value="MR" /></td>
		<td onclick="concatNum(4);"><input class="button" type="button" value="4" /></td>
		<td onclick="concatNum(5);"><input class="button" type="button" value="5" /></td>
		<td onclick="concatNum(6);"><input class="button" type="button" value="6" /></td>
		<td onclick="operate('multiply');"><input class="button" type="button" value="*" /></td>
		<td onclick="operate('percent');"><input class="button" type="button" value="%" /></td>
	</tr>
	<tr>
		<td onclick="memoryS();"><input class="buttonLeft" type="button" value="MS" /></td>
		<td onclick="concatNum(1);"><input class="button" type="button" value="1" /></td>
		<td onclick="concatNum(2);"><input class="button" type="button" value="2" /></td>
		<td onclick="concatNum(3);"><input class="button" type="button" value="3" /></td>
		<td onclick="operate('subtract');"><input class="button" type="button" value="-" /></td>
		<td onclick="numReciprocal();"><input class="button" type="button" value="1/x" /></td>
	</tr>
	<tr>
		<td onclick="memoryP();"><input class="buttonLeft" type="button" value="M+" /></td>
		<td onclick="concatNum(0);"><input class="button" type="button" value="0" /></td>
		<td onclick="oppNum();"><input class="button" type="button" value="+/-" /></td>
		<td onclick="addDot();"><input class="button" type="button" value="." /></td>
		<td onclick="operate('add');"><input class="button" type="button" value="+" /></td>
		<td onclick="equate();"><input class="button" type="button" value="=" /></td>
	</tr>
</table>
<span id="memCache1" style="display: none;"></span>
<input id="calcToggle" type="text" value="0" style="display: none;" />
<script type="text/javascript" src="myjscalculator.js"></script>
<!--
 If you're going to embed this into your web pages, the important part is above.  However,
 Don't forget to use the stylesheet, too!
-->

</body>
</html>
myjscalculator.css

Code: Select all

/*
MyJSCalculator - A simple HTML/CSS/JavaScript calculator.

Copyright (C) 2007 Scott Martin <smp_info[at]yahoo[dot]com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
.button, .buttonLeft
{
	width: 30px;
	height: 30px;
	font-family: "courier new", "courier", verdana;
	font-size: 10px;
	color: #000;
	border: solid 1px #000;
	text-align: center;
	background-color: #e6e6e6;
	cursor: pointer;
}
.buttonLeft
{
	width: 40px;
	color: #ff0000;
}
.mem
{
	font-family: "courier new", "courier", verdana;
	font-size: 12px;
	color: #ff0000;
}
input.button:hover, input.buttonLeft:hover
{
	background-color: orange;
}

.display
{
	border: solid 1px #000;
	width: 94%;
	text-align: right;
	padding-left: 5px;
	padding-right: 5px;
	background-color: #fff;
	color: #000;
	font-family: verdana, arial, tahoma;
	font-size: 12px;
}
a.calcName
{
	font-family: verdana, arial, tahoma;
	font-size: 11px;
	font-weight: bold;
	color: #000;
}
myjscalculator.js

Code: Select all

/*MyJSCalculator - A simple HTML/CSS/JavaScript calculator.

Copyright (C) 2007 Scott Martin <smp_info[at]yahoo[dot]com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
//avoid repetitive typing
var cdp = document.getElementById('calcDisplay');
var cm = document.getElementById('calcMem');
var cmv = document.getElementById('calcMemValue');
var cmc = document.getElementById('memCache1');
var ct = document.getElementById('calcToggle');

//functions for calculator
function concatNum(num) {
	if(ct.value == 1) {
		cdp.value = num;
	} else {
		if (cdp.value == '0') {
			cdp.value = '';
		}
		cdp.value += num;
	}
	ct.value = 0;
}

function clearNum() {
	//this should clear the entire equation!
	cdp.value = '0';
	cmc.value = '';
	ct.value = '0';
}

function clearEntry() {
	cdp.value = '0';
}

function addDot() {
	if (cdp.value.indexOf('.') == -1) {
		cdp.value += '.';
	}
}

function backspace() {
	if (cdp.value.length && (cdp.value != 0)) {
		if ((cdp.value.substr(0, cdp.value.length-1) == '') || (cdp.value.substr(0, cdp.value.length-1) == '-')) {
			cdp.value = '0';
		} else {
			cdp.value = cdp.value.substr(0, cdp.value.length-1);
		}
	}
}

function memoryS() {
	cmv.value = cdp.value;
	cm.innerHTML = 'M';
}

function memoryR() {
	if (cmv.value == '') {
		cdp.value = 0;
	} else {
		cdp.value = cmv.value;
	}
}

function memoryC() {
	cmv.value = '';
	cm.innerHTML = '&nbsp;';
}

function memoryP() {
	cdp.value = new Number(cdp.value) + new Number(cmv.value);
}

function oppNum() {
	cdp.value = new Number(-cdp.value);
}

function numSqrt() {
	var num = new Number(cdp.value);
	if (num < 0) {
		cdp.value = 'Invalid input for function.';
	} else {
		cdp.value = Math.sqrt(cdp.value);
	}
}

function numReciprocal()
{
	if ((cdp.value == 0) || isNaN(cdp.value))
	{
		cdp.value = 'Cannot divide by zero.';
	} else
	{
		cdp.value = 1 / new Number(cdp.value);
	}
}

function operate(op) {
	
	if (op == 'percent'){
		if (!cmc.value) {
			cdp.value = '0';
		} else {
			var num = cmc.value.split('-');
			cdp.value = (new Number(cdp.value)/100) * new Number(num[1]);
		}
	} else {
		if (cmc.value) {
			equate();
		}
		if (op == 'add') {
			cmc.value = 'add-'+cdp.value;
		}
		if (op == 'subtract') {
			cmc.value = 'subtract-'+cdp.value;
		}
		if (op == 'multiply') {
			cmc.value = 'multiply-'+cdp.value;
		}
		if (op == 'divide') {
			cmc.value = 'divide-'+cdp.value;
		}
		ct.value = 1;
	}
}

function equate() {
	var num = cmc.value.split('-');
	switch (num[0]) {
		case 'add':
		cdp.value = new Number(num[1]) + new Number(cdp.value);
		break;
		
		case 'subtract':
		cdp.value = new Number(num[1]) - new Number(cdp.value);
		break;
		
		case 'multiply':
		cdp.value = new Number(num[1]) * new Number(cdp.value);
		break;
		
		case 'divide':
		cdp.value = new Number(num[1]) / new Number(cdp.value);
		break;
	}
	cmc.value = '';
}
Check out the demo here: http://www.scottayy.com/myjscalculator/demo.php

And download it from here, if you want: http://www.scottayy.com/myjscalculator/download.php
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Dude, that is pretty cool. I may have to steal, er, download that today.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Thanks. :) Another product of boredom, but at least I learned what all the keys on a standard calculator are for. And I learned a new javascript method indexOf() and the Number() object.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
nickvd
DevNet Resident
Posts: 1027
Joined: Thu Mar 10, 2005 5:27 pm
Location: Southern Ontario
Contact:

Post by nickvd »

Very nicely done sir!

One minor bug I found though... After a calculation (you click the equal sign) you get the correct answer (yay!) however, if you 'type' in more numbers, they get appended to the result that's already 'on the screen'... Very minor and very easy to fix, but I thought I'd point it out nonetheless :)
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Thanks for pointing that out. :) I'll fix that after I get back from my doctors appointment.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
deadoralive
Forum Commoner
Posts: 28
Joined: Tue Nov 06, 2007 1:24 pm

Post by deadoralive »

Very nice, well done!!
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

Nice ;)
I also love the way js handles border cases:
1/0 = Infinity
Infinity * 0 = NaN
NaN + 1 = NaN

I second nickvd though, this is something that is "natural", and feels strange with your calculator.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Alrighty, fixed that. Updated the files in the download, too.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

Can we type into the number field, then use the +- etc. keys?
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Dude, I didn't even know windows calculator had that ability! That's sweet.
I could hook that up in the calculator.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

btw, while you have fixed the bug nickvd mentioned for most operations it's still present for sqrt.
Post Reply