At your attention is a simple tutorial about building a javascript calculator using jQuery. The whole code is explained below and a demo of the calculator is available here: calculator demo.
As I think the markup and the styling are self-explanatory, they would not be shown here explicitly, so let’s start with the code.
First we declare a few variables, half of them pointing to HTML elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$('document').ready(function(){ var $calc = $("#calculator"); var $display = $("#display"); var $digits = $(".digits"); var $operations = $(".operations"); var init = 0; var operand = init; var operation = null; var afterOperation = false; var reset = function() { $display.text(init); operand = null; operation = null; }; |
$calc points to the calculator body, but I am pretty sure it has actually never been used through the code.
$display points at – of course – the calculator display (a div element), while $digits and $operations are sets representing the digits and operations DIVs respectively. The init variable is used by initializing the calculator and resetting the state – of course, it is 0. What operand point to is the first of two operands, taking part in each operation. The operation variable is used to hold the last unexecuted operation, chosen by the user. The afterOperation flag indicates whether the last user’s choice was a digit or an operation. The reset variable, pointing to an anonymous function, resets the display and both operand and operation, used through the code below.
The remaining part of the code is actually a few click handlers – for clicking on a digit or a operation button and two additional – for the decimal point (which I, should admit, wrongly call ‘dot’) and for the change of the sign (+/-). The first function, which comes after the variable declaration and initialization is the digit click handler.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$digits.not($('#dot, #sign')).click(function(event) { event.preventDefault(); if (afterOperation == false) { if ($display.text() == init && $display.text().indexOf('.')<0) { $display.text($(this).text()); } else { $display.append($(this).text()); } } else { $display.text($(this).text()); afterOperation = false; } }); |
First, as you can see, I exclude the dot and the sign buttons from the elements set, as they actually belong to the digits class, but should be handled a bit differently.
Here the afterOperation flag is used for the first time – there are two options, depending on the flag value – the first one (if (afterOperation == false) {…) is used when we are ‘building’ the value digit by digit and the second one is used to start ‘building’ the value after an operation has been performed. The main difference is in the text() and append() functions – the first one types the clicked digit ($(this).text()) in the display, while the second one simply concatenates the digit to these, already present in the display.
By afterOperation with a value of false, there are analogically two cases – the first one (if ($display.text() == init && $display.text().indexOf(‘.’)<0) {...) checks whether the display has the init value (0) AND whether NO decimal point is available. In this case the text() function is used – that means that the newly chosen digit is written in the display on the init value’s place. The reason to check for the absence of the decimal point, is the following – when we have for example 0 on the display and click the ‘dot’ button for adding a decimal point, the point is concatenated to the zero. However, the expression “0.” == 0 evaluates to true and so the text() function would be invoked, while we need to append digits after the decimal point – so the $display.text().indexOf(‘.’)<0 statement has been added. So in the case “0.” we have true for the first statement $display.text() == init and false for the second one, thus eventually having true AND false, which evaluates to false, making the code appending digits after the dot instead of not resetting the display with the text() function.
Let’s now have a look at the operation handler.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
$operations.click(function(event){ event.preventDefault(); var currOperation = $(this).text(); var currOperand = parseFloat($display.text()); if (currOperation != 'CE') { // Do the math if (operation != null && !afterOperation) { switch(operation) { case '+': { $display.text(operand + currOperand); break; } case '-': { $display.text(operand - currOperand); break; } case '*': { $display.text(operand * currOperand); break; } case '/': { if (currOperand != 0) { $display.text(operand / currOperand); } else { alert("What the fuck?!"); reset(); } break; } } } if (currOperation != '=') { operation = currOperation; } else { operation = null; afterOperation = false; return; } operand = parseFloat($display.text()); afterOperation = true; } else { reset(); } }); |
First, we make two additional local variables – currOperation for the current operation and currOperand for the current operand. Then we simply check if the Clear button is pressed – if so, we call the reset() function.
If not, however, we go on with the math.
First, we check if there is already an operation set AND whether the flag afterOperation has a value of false, which means that no operation button has been clicked just before the event, being handled at the moment. If both the upper conditions are satisfied, a switch statement (for the operation, not currOperation) takes care for doing the math. Please note that if we have typed a value (e.g. 5) for example, than chosen ‘+’ operation, type a value again and chose a ‘-‘ operation, the operation variable would point to the last unhandled one – that means the plus operation, so it would be caught and executed by the switch statement. So, at the moment of clicking on the minus sign, the plus operation would be executed.
The expression if (currOperation != ‘=’) {operation = currOperation;} takes care of assigning the current and still not executed operation (the ‘minus’ from the example above) to the operation variable. The operation behind the equal sign is, of course, not to be remembered anywhere – by clicking on the equal sign, we execute the last available operation and reset the operation and the afterOperation flag.
However, no matter how many times we have clicked on an operation button (different from “CE” and “=”),
1 2 3 4 |
... operand = parseFloat($display.text()) afterOperation = true; ... |
statements would be executed – operand should point to the value, currently available on the display (that is – most likely – the result of the past operation) and afterOperation should be true.
The last two handlers are for the decimal point and the switch sign.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$('#dot').click(function(event){ event.preventDefault(); if (!afterOperation) { if ($display.text().indexOf('.') < 0) { $display.append('.'); } } else { $display.text('0.'); afterOperation = false; } }); $("#sign").click(function(event){ event.preventDefault(); if (afterOperation) { return; } else { $display.text(parseFloat($display.text())*(-1)); afterOperation = true; } }); |
The ‘dot’ click handler appends a single dot to the digits available in the display if afterOperation flag is false or writes “0.” string in the display in case an operation button has been just clicked on.
The ‘sign’ click handler switched the sign only if the afterOperation flag is set to false.
I really hope the article has been useful and adequately responding to your needs.
Ich wei? nicht, was ich sagen soll. Dieser Blog ist fantastisch. Das ist nicht wirklich eine wirklich gro?e Aussage, aber die alles, was ich tun konnte, nach der Lektüre dieses. Sie wissen so viel über dieses Thema. So sehr, dass Sie in mir den Wunsch, mehr darüber zu erfahren. Ihr Blog ist mein Sprungbrett, mein Freund. Vielen Dank für das Heads-up zu diesem Thema.
I absolutely love your blog and find a lot of your post’s to be precisely what I’m looking for. Would you offer guest writers to write content for yourself? I wouldn’t mind composing a post or elaborating on a lot of the subjects you write regarding here. Again, awesome blog!
cool thanks for Reisadvies sharing! btw are there feeds in your blog? I want to add them to my reader Finnaly i discovered your postkeep blogging Damn ! I simply found a mistake within your website! See if css is managed right!
Undeniably consider that that you stated. Your favorite justification appeared to be at the web the simplest factor to remember of. I say to you, I definitely get irked whilst people consider worries that they plainly do not realize about. You controlled to hit the nail upon the top and also outlined out the entire thing with no need side-effects , other people could take a signal. Will probably be again to get more. Thank you!
Is there something wrong with the RSS feed here. Looks like a broken link to me?
Thank you for the great read. Will check back when I get a chance.
Pardon me, but I attempted to email you regarding something on your website but the given e-mail address didn’t work. Is there an alternative place I could contact you?
So I’m obviously new to the site. I figured out how to customize my blog page but now I need some help learning how to delete the posts that seem to automatically be there as examples and create my own..
Hi, Thank you for this post as I am learning java-script at the moment and I am looking for a way to not use eval function. However I am having trouble getting this code to work. When i click onto the calculator nothing is being displayed. I would love if somebody can help me here, I think my trouble may be how the functions are set up, I do programming in C language and it is very easy to see when you are missing brackets etc but js it hard!!! please help me and thank you in advance those who do!! i am going to make my own css to make it look fancy but would like to see it working first.
My source.html is this:
Javascript Calculator with jQuery | if-act.net
0
1
2
3
4
5
6
7
8
9
0
+
–
*
/
.
+/-
CE
=
……………………………………………………………….
And my script.js with the functions looks like this:
………………………………………………………………..
$(‘document’).ready(function(){
var $calc = $(“#calculator”);
var $display = $(“#display”);
var $digits = $(“.digits”);
var $operations = $(“.operations”);
var init = 0;
var operand = init;
var operation = null;
var afterOperation = false;
var reset = function() {
$display.text(init);
operand = null;
operation = null;
$digits.not($(‘#dot, #sign’)).click(function(event) {
event.preventDefault();
if (afterOperation == false) {
if ($display.text() == init && $display.text().indexOf(‘.’)<0) {
$display.text($(this).text());
} else {
$display.append($(this).text());
}
} else {
$display.text($(this).text());
afterOperation = false;
}
});
$operations.click(function(event){
event.preventDefault();
var currOperation = $(this).text();
var currOperand = parseFloat($display.text());
if (currOperation != 'CE') {
// Do the math
if (operation != null && !afterOperation) {
switch(operation) {
case '+': {
$display.text(operand + currOperand);
break;
}
case '-': {
$display.text(operand – currOperand);
break;
}
case '*': {
$display.text(operand * currOperand);
break;
}
case '/': {
if (currOperand != 0) {
$display.text(operand / currOperand);
} else {
alert("What the fuck?!");
reset();
}
break;
}
}
}
if (currOperation != '=') {
operation = currOperation;
} else {
operation = null;
afterOperation = false;
return;
}
operand = parseFloat($display.text());
afterOperation = true;
} else {
reset();
}
});
$('#dot').click(function(event){
event.preventDefault();
if (!afterOperation) {
if ($display.text().indexOf('.') < 0) {
$display.append('.');
}
} else {
$display.text('0.');
afterOperation = false;
}
});
$("#sign").click(function(event){
event.preventDefault();
if (afterOperation) {
return;
} else {
$display.text(parseFloat($display.text())*(-1));
afterOperation = true;
}
});
});
………………………………………………….
Thanks a mill,
HAT^
Source Code looks like this actually!!:
Javascript Calculator with jQuery | if-act.net
0
1
2
3
4
5
6
7
8
9
0
+
–
*
/
.
+/-
CE
=
Hi,
first make sure you are loading the jQuery library, then you may also use the browser console and paste the error or try debugging the code by yourself.
If it does not help, make a fiddle (http://jsfiddle.net) with your code (both the markup and the javascript of course) and drop the link here.
Cheers,
Ivan