Tag: calculator

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");

varinit=0;

varoperand=init;

varoperation=null;

varafterOperation=false;

varreset=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();

varcurrOperation=$(this).text();

varcurrOperand=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.