Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

Help with a simple javascript calculator!

calculator

This topic has been archived. This means that you cannot reply to this topic.
1 reply to this topic

#1 TylerKlimek

TylerKlimek

    CC Lurker

  • Just Joined
  • Pip
  • 1 posts

Posted 10 December 2014 - 03:08 PM

I am working on a calculator program to practice and aid in learning javascript. I have this so far:
<!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">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-type" />
<title>Calculator</title>
<h1><center>On-Line Calculator</center></h1>
<script LANGUAGE="Javascript">
function addChar(input, character) {
if(input.value == null || input.value == "0")
input.value = character
else
input.value += character
}

function sqrt(form) {
form.display.value = Math.sqrt(form.display.value);
}

function changeSign(input) {
if(input.value.substring(0, 1) == "-")
input.value = input.value.substring(1, input.value.length)
else
input.value = "-" + input.value
}

function compute(form) {
form.display.value = eval(form.display.value)
}

function checkNum(str) {
for (var i = 0; i < str.length; i++) {
var ch = str.substring(i, i+1)
if (ch < "0" || ch > "9") {
if (ch != "/" && ch != "*" && ch != "+" && ch != "-" && ch != "."
&& ch != "(" && ch!= ")") {
alert("invalid entry!")
return false
}
}
}
return true
}
</script>
</head>
<body>
<form name="sci-calc">
<table  border="2"CELLSPACING="1" CELLPADDING="5" align="center" >
<tr>
<td COLSPAN="3" align="center"><input name="display" value="0" SIZE="28" MAXLENGTH="25"></td>
<td align="center" colspan="1" ><input type="button" value="  %  " ONCLICK="addChar(this.form.display, '%')" style="width: 135px"></td>

</tr>
<tr>
<td align="center" colspan="1" ><input type="button" value="  7  " ONCLICK="addChar(this.form.display, '7')" style="width: 135px"></td>
<td align="center" colspan="1" ><input type="button" value="  8  " ONCLICK="addChar(this.form.display, '8')" style="width: 136px" ></td>
<td align="center"colspan="1"><input type="button" value="  9  " ONCLICK="addChar(this.form.display, '9')" style="width: 135px" ></td>
<td align="center"colspan="1"><input type="button" value="   +  " ONCLICK="addChar(this.form.display, '+')" style="width: 137px"></td>
</tr>
<tr>
<td align="center"colspan="1"><input type="button" value="  4  " ONCLICK="addChar(this.form.display, '4')" style="width: 133px"></td>
<td align="center" colspan="1"><input type="button" value="  5  " ONCLICK="addChar(this.form.display, '5')" style="width: 131px"></td>
<td align="center"colspan="1"><input type="button" value="  6  " ONCLICK="addChar(this.form.display, '6')" style="width: 134px"></td>
<td align="center"colspan="1"><input type="button" value="   -   " ONCLICK="addChar(this.form.display, '-')" style="width: 139px"></td>
</tr>
<tr>
<td align="center"colspan="1" ><input type="button" value="  1  " ONCLICK="addChar(this.form.display, '1')" style="width: 133px"></td>
<td align="center" colspan="1"><input type="button" value="  2  " ONCLICK="addChar(this.form.display, '2')" style="width: 128px"></td>
<td align="center"colspan="1"><input type="button" value="  3  " ONCLICK="addChar(this.form.display, '3')" style="width: 132px"></td>
<td align="center"colspan="1"><input type="button" value="   *   " ONCLICK="addChar(this.form.display, '*')" style="width: 137px"></td>
</tr>
<tr>
<td align="center"colspan="1"><input type="button" value="  0  " ONCLICK="addChar(this.form.display, '0')" style="width: 131px"></td>
<td align="center" ><input type="button" value="   .  " ONCLICK="addChar(this.form.display, '.')" style="width: 129px"></td>
<td align="center"><input type="button" value=" sqrt " ONCLICK="if (checkNum(this.form.display.value)) { sqrt(this.form) }" style="width: 136px"></td>
<td align="center"><input type="button" value="   /   " ONCLICK="addChar(this.form.display, '/')" style="width: 139px"></td>
</tr>
<tr>
<td align="center" ><input type="button" value="    (    " ONCLICK="addChar(this.form.display, '(')" style="width: 131px"></td>
<td align="center" ><input type="button" value="   )   " ONCLICK="addChar(this.form.display, ')')" style="width: 132px"></td>
<td align="center" ><input type="button" value="=" name="enter" ONCLICK="if (checkNum(this.form.display.value)) { compute(this.form) }" style="width: 141px"></td>
<td align="center" ><input type="button" value="clear" ONCLICK="this.form.display.value = 0 " style="width: 141px"></td>
</tr>
</table>
</form>
</html>
 
I have a couple questions:
 
1. I need a working percentage button, the one I have now does not do what I need it to do. It should display what precent the first input number is of the second. I.e. if the first number is 5 and the second is 20, then the result should be 25 (meaning 25 %). 
2. I need to display all the operations entered, not only the results of the calculations performed by the user. For example, on 3+4, instead of just displaying "7", display "3 + 4 = 7". Keep the display of all previous calculations in the input field, instead of just the current one.
 
Can someone help me out here? Thanks!

Edited by TylerKlimek, 10 December 2014 - 03:10 PM.


#2 RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1310 posts

Posted 10 December 2014 - 08:14 PM

For 2), I am thinking why not change this?:
function compute(form) {
form.display.value = eval(form.display.value)
}
I am thinking, since you are using JavaScript's eval () function, it may make sense to separate the input from the answer? In particular, make the JavaScript be something more like:
function compute (form){ 
form.answer.value = eval (form.userInput.value); 
} 
And then you could have two INPUT elements instead of just one? And put a <span>=</span> in between the INPUT elements?

Also since you are using eval (), an expression like "4 * 2 + 5" (without the quotes) should work, but your code is preventing it from working. Why not change this function?:
function checkNum(str) {
for (var i = 0; i < str.length; i++) {
var ch = str.substring(i, i+1)
if (ch < "0" || ch > "9") {
if (ch != "/" && ch != "*" && ch != "+" && ch != "-" && ch != "."
&& ch != "(" && ch!= ")") {
alert("invalid entry!")
return false
}
}
}
return true
}
Have something like this?:
function check_number (x){ 
  var y; 
  try { 
    y = eval (x); 
  } catch (err){ 
    // invalid ! caused script error 
    return false; 
  } 
  if (isNaN (y) || !isFinite (y)){ 
    // invalid ! either is not a number or is infinite 
    return false; 
  } 
  return true; // valid! 
} 
There is, of course, the danger that the user can type in something JavaScript-ty that would do something not-so-good (e.g., "document.title = 'haha!'"), and ideally if you wanted to practicce then building your own eval () function would be the best. If you do build your own eval () function, I recommend following Java's organizational pattern of organizing things into classes and using one .js file per class; programming is so much easier and more elegant that way, I think.

But of course re-inventing the wheel is usually not the best idea ever unless you want to practice. Another idea of how you can check to make sure the script they entered doesn't have anything funny like "alert ('hi!')" or something is check to make sure there is not any alphabetic text.

And later, if you want to enable things like sin () and cos () in the input, then not having any alphabetic text would not be so good. In that case, you can do a bunch of such code:
var text = ...; 
text = text.replace (/sin/g, ""); 
text = text.replace (/cos/g, ""); 
etc. ... 
String.replace () has two parameters: the text to find, and the text to replace the found text with. The "/" characters tell JavaScript it is a regular expression, and the "g" at the end tells it to replace ALL occurrences - if you don't put the "g" , it'll only replace just the first occurrence (e.g., if the user enters "sin(5)" then it'll work without the "g" , but if user enters "sin (5) + sin (7)" then it won't work).

You can, later, do the same for variable names, too. Note, though, that it is generally a good idea to take out the longest-named variables first. For example, if there are two variables, one named "man" and one named "woman" , then if the user entered "woman" - and you take out "man" first in your code - then the result will be "wo" , and that won't be later filtered by taking out instances of "woman" . But if you take out "woman" (the longer word) first, then you're sure you already took out all the "woman" words, and you can proceed to taking out the shorter-name words.

Now as for where I am going with this. Once you take out all the "sin" and "cos" and other allowed words, then you can check for any remaining alphanumeric characters. If there are any, then it is an invalid input.


For example, say you define some variables for your user:
  • one
  • two
  • ans
And user is allowed to enter an expression with numbers and those variable names. If user enters "one * 2 + 3 - (4 * ans)" , then it is a valid input. How do you check? You take out (using .replace ()) all the allowed words, so it turns into " * 2 + 3 - (4 * )" , and then, when you check for alphabetic characters, there won't be any, so you know there isn't anything funny.

But if the user input is "document.body.innerHTML = ''", then, after taking out all the allowed words and checking for alphabetic characters, there will be a lot of those. So your code can know that it is an invalid input.
Regards,
RR




Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download