Myra_
Myra_

Reputation: 3

Vanilla JavaScript calculator

So I've been working on a "very simple" calculator only using vanilla JavaScript. However I don't know why is it now working.

This is my JavaScript and HTML code:

(function() {
  "use strict";


  var elem = function(element) {
    if (element.charAt(0) === "#") { 
      return document.querySelector(element); 
    }

    return document.querySelectorAll(element); 
  };

 // Variables
 var screen = elem('.screen'); 
   equal = elem('.equal'); 
   nums = elem('.num');
   ops = elem('.operator');
   theNum = ""; 
   oldNum = ""; 
   resultNum; 
   operator; 
    

  // When: Number is clicked. Get the current number selected
  var setNum = function() {
    if (resultNum) { 
      theNum = this.getAttribute('data-num');
      resultNum = "";
    } else { 
      theNum += this.getAttribute('data-num');
    }

    viewer.innerHTML = theNum; 

  };


  var moveNum = function() {
    oldNum = theNum;
    theNum = "";
    operator = this.getAttribute('data-ops');

    equal.setAttribute('data-result', ''); 
  };


  var displayNum = function() {


    oldNum = parseFloat(oldNum);
    theNum = parseFloat(theNum);


    switch (operator) {
      case "plus":
        resultNum = oldNum + theNum;
        break;

      case "minus":
        resultNum = oldNum - theNum;
        break;

      case "times":
        resultNum = oldNum * theNum;
        break;

      case "divided by":
        resultNum = oldNum / theNum;
        break;


      default:
        resultNum = theNum;
    }


    viewer.innerHTML = resultNum;
    equal.setAttribute("data-result", resultNum);


    oldNum = 0;
    theNum = resultNum;

  };


  var clearAll = function() {
    oldNum = "";
    theNum = "";
    viewer.innerHTML = "0";
    equals.setAttribute("data-result", resultNum);
  };

  for (var i = 0, l = nums.length; i < l; i++) {
    nums[i].onclick = setNum;
  }

  for (var i = 0, l = ops.length; i < l; i++) {
    ops[i].onclick = moveNum;
  }


  equals.onclick = displayNum;


  elem("#clear").onclick = clearAll;
<div id="calculator">

  <div class="top">
    <button id="clear">C</button>
    <div class="screen"></div>

  </div>

  <div class="btns">

    <button class="num" data-num="7">7</button>
    <button class="num" data-num="8">8</button>
    <button class="num" data-num="9">9</button>

    <button class="operator" data-ops="plus">+</button>

    <button class="num" data-num="4">4</button>
    <button class="num" data-num="5">5</button>
    <button class="num" data-num="6">6</button>

    <button class="operator" data-ops="minus">-</button>

    <button class="num" data-num="1">1</button>
    <button class="num" data-num="2">2</button>
    <button class="num" data-num="3">3</button>

    <button class="operator" data-ops="divided by">÷</button>

    <button class="num" data-num="0">0</button>
    <button class="num" data-num=".">.</button>
    <button class="equal" data-result="">=</button>

    <button class="operator" data-ops="times">x</button>

  </div>
</div>

I'm not sure if what I'm doing is correct. I've been pretty much improvising but if anyone knows an easier way or correct way of making the calculator work I'd really appreciate the help.

Upvotes: 0

Views: 1406

Answers (3)

Hamza Dahmoun
Hamza Dahmoun

Reputation: 1294

  1. remove the function itself
  2. add var before declaring variables: equal to viewer
  3. use: var equal = elem('.equal')[0]; because you will get an array of DOM objects by className, you need the first one
  4. use: var viewer = elem('.screen')[0]; because you will get an array of DOM objects by className, you need the first one
  5. declare var viewer = elem('.screen');
  6. Two words in the code 'equals' should be 'equal', remove the 's' in the end of the word
  7. And the working code is:

    "use strict";
    var elem = function(element) {
    if (element.charAt(0) === "#") { 
    return document.querySelector(element);
    }
    return document.querySelectorAll(element);
    };
    // Variables
    var screen = elem('.screen');
    var  equal = elem('.equal')[0];
    var   nums = elem('.num');
    var   ops = elem('.operator');
    var   theNum = ""; 
    var   oldNum = ""; 
    var   resultNum; 
    var   operator; 
    var viewer = elem('.screen')[0];
    // When: Number is clicked. Get the current number selected
    var setNum = function() {
    if (resultNum) { 
    theNum = this.getAttribute('data-num');
    resultNum = "";
    } else { 
    theNum += this.getAttribute('data-num');
    }
    viewer.innerHTML = theNum; 
    };
    var moveNum = function() {
    oldNum = theNum;
    theNum = "";
    operator = this.getAttribute('data-ops');
    equal.setAttribute('data-result', ''); 
    };
    var displayNum = function() {
    oldNum = parseFloat(oldNum);
    theNum = parseFloat(theNum);
    
    switch (operator) {
    case "plus":{
    resultNum = oldNum + theNum;
    break;
    }
    
    case "minus":
    resultNum = oldNum - theNum;
    break;
    
    case "times":
    resultNum = oldNum * theNum;
    break;
    
    case "divided by":
    resultNum = oldNum / theNum;
    break;
    
    default:
    resultNum = theNum;
    }
    
    
    viewer.innerHTML = resultNum;
    equal.setAttribute("data-result", resultNum);
    
    
    oldNum = 0;
    theNum = resultNum;
    
    };
    var clearAll = function() {
    oldNum = "";
    theNum = "";
    viewer.innerHTML = "0";
    equal.setAttribute("data-result", resultNum);
    };
    
    for (var i = 0, l = nums.length; i < l; i++) {
    nums[i].onclick = setNum;
    }
    
    for (var i = 0, l = ops.length; i < l; i++) {
    ops[i].onclick = moveNum;
    }
    
    
    equal.onclick = displayNum;
    
    elem("#clear").onclick = clearAll;
    

Upvotes: 0

John Slegers
John Slegers

Reputation: 47081

I wrote a basic calculator for a school assignment back in 2003. Even though the code is 12+ years old, it still works in modern browsers today. Feel free to check it out any borrow any code you might find useful.

You can find the complete code below as well as in this github repository.

By the way, the behavior of my calculator is intended to work exactly like that of a real, physical, old school calculator... which means that you need to push the on/c button before you can do anything else ;-)

A screenshot :

enter image description here

The code :

var on = false, lastprinted = "", currentfunc ="", memory;

function testoverflow() {
    var overflowflag;
    if (memory >= 1000000000000) {
        turn("error");
        overflowflag = true;
    } else
        overflowflag = false;
    return overflowflag;
}

function findmaxlength(location) {
    var maxlength = 12;
    if (location.indexOf("-", 0) != -1) maxlength++;
    if (location.indexOf(".", 0) != -1) maxlength++;
    return maxlength;
}

function showresult(lg, hf) {
    memory = memory.toString();
    memory = parseFloat(memory.substring(0,findmaxlength(memory)));
    document.calculator.display.value = memory;
    lastprinted = lg;
    currentfunc = hf;
}

function turn(onoff) {
    if (onoff == "ce") {
        if (on) {
            document.calculator.display.value="0";
        }
    } else {
        switch (onoff) {
            case "onc":
                document.calculator.display.value="0";
                on = true;
                break;
            case "error":
                document.calculator.display.value = "ERROR";
                break;
            case "off":
                document.calculator.display.value="";
                on = false;
                break;
        } 
        currentfunc = "";
        memory = null;
    }
    lastprinted = "";
}

function number(input) {
    if (on) {
        if ((document.calculator.display.value.length < findmaxlength(document.calculator.display.value)) || (lastprinted != "number")) {
            if (!((document.calculator.display.value == "0") && ((input == "00") || (input == "0")))) {
                if ((lastprinted == "number")&&(document.calculator.display.value != "0")) {
                    document.calculator.display.value += input;
                    lastprinted = "number";
                } else if (input != "00") {
                    document.calculator.display.value = input;
                    lastprinted = "number";
                }
            }
        }
    }
}

function func(symbool) {
    if ((on) && (document.calculator.display.value != "ERROR")) {
        if (memory == null) {
            memory = parseFloat(document.calculator.display.value);
            lastprinted = "func";
            currentfunc = symbool;
        } else if ((document.calculator.display.value == "0") && (currentfunc == "/")) {
            turn("error");
        } else {
            eval("memory = " + memory + currentfunc + "(" + document.calculator.display.value +");");
            if (! testoverflow()) showresult("func", symbool);
        }
    }
}

function result(name) {
    var value;
    if ((on) && (document.calculator.display.value != "ERROR")) {
        if (memory != null) {
            value = document.calculator.display.value;
            if (name == "procent") value = memory * parseFloat(document.calculator.display.value)/ 100; 
            eval("memory = " + memory + currentfunc + "(" + value +");");
            if (! testoverflow()) {
                showresult("name", "");
                memory = null;
            }		
        }
    }
}

function dot() {
    var maxlength = 12;
    if ((on) && (document.calculator.display.value != "ERROR")) {
        if (document.calculator.display.value.indexOf("-", 0) != -1) maxlength++;
        if (((lastprinted == "number") || (document.calculator.display.value="0")) && !(document.calculator.display.value.length >= maxlength) && (document.calculator.display.value.indexOf(".", 0) == -1)) {
            document.calculator.display.value += ".";
            lastprinted = "number";
        }
    }
}

function negative() {
    if ((on) && (lastprinted == "number") && (document.calculator.display.value != "ERROR")) {
        if (document.calculator.display.value.indexOf("-", 0) == -1) document.calculator.display.value = "-" + document.calculator.display.value;
        else document.calculator.display.value = document.calculator.display.value.substring(1,14);
    }
}
body {background-color: #CCCCCC; color: #555555; font-family: Arial; font-weight: bold; font-size: 8pt;}
a {color: #CC5555; text-decoration: none}
a:visited {color: #CC5555; text-decoration: none}
a:active {color: #FF0000; text-decoration: none}
a:hover {color: #FF0000; text-decoration: none}
.button {height: 30px; width: 40px; background-color: #555555; border-color: #555555; color:#FFFFFF;}
.invisbutton {height: 28px; width: 40px; background-color: #7555C6; border-color: #7555C6; border-style:solid;}
.display {height: 50px; width: 217px; background-color: #D6D39F; border-color: #000000; color:#222222; border-style: solid; text-align: right; font-size: 22pt;}
.redbutton {height: 30px; width: 40px; background-color: #EE0000; border-color: #EE0000; color:#FFFFFF;}
.yellowbutton {height: 30px; width: 40px; background-color: #EEEE00; border-color: #EEEE00; color:#000000;}
.device {height: 30px; width: 40px; background-color: #7555C6; border-color: #7555C6; border-style:ridge;}
<table class="device" cellspacing="20" cellpadding="0">
    <tr>
        <td align="center">
            <form name="calculator">
                <table>
                    <tr>
                        <td colspan="5"><input type="text" name="display" class="display" readonly='readonly'></td>
                    </tr>
                    <tr>
                        <td colspan="5"><input type="text" class="invisbutton" style="height:15px;" readonly='readonly'></td>
                    </tr>
                    <tr>
                        <td><input type="text" name="hidden" class="invisbutton" readonly='readonly'></td>
                        <td><input type="text" name="hidden2" class="invisbutton" readonly='readonly'></td>
                        <td><input type="button" name="off" class="redbutton" value="off" onclick="turn(this.name);"></td>
                        <td><input type="button" name="ce" class="yellowbutton" value="ce" onclick="turn(this.name);"></td>
                        <td><input type="button" name="onc" class="yellowbutton" value="on/c" onclick="turn(this.name);"></td>
                    </tr>
                    <tr>
                        <td><input type="button" name="number7" class="button" value="7" onclick="number(this.value);"></td>
                        <td><input type="button" name="number8" class="button" value="8" onclick="number(this.value);"></td>
                        <td><input type="button" name="number9" class="button" value="9" onclick="number(this.value);"></td>
                        <td><input type="button" name="procent" class="button" value="%" onclick="result(this.name);"></td>
                        <td><input type="button" name="plusmin" class="button" value="+/-" onclick="negative();"></td>
                    </tr>
                    <tr>
                        <td><input type="button" name="number4" class="button" value="4" onclick="number(this.value);"></td>
                        <td><input type="button" name="number5" class="button" value="5" onclick="number(this.value);"></td>
                        <td><input type="button" name="number6" class="button" value="6" onclick="number(this.value);"></td>
                        <td><input type="button" name="func-" class="button" value="-" onclick="func(this.name.substring(4, 5));"></td>
                        <td><input type="button" name="func/" class="button" value="/" onclick="func(this.name.substring(4, 5));"></td>
                    </tr>
                    <tr>
                        <td><input type="button" name="number1" class="button" value="1" onclick="number(this.value);"></td>
                        <td><input type="button" name="number2" class="button" value="2" onclick="number(this.value);"></td>
                        <td><input type="button" name="number3" class="button" value="3" onclick="number(this.value);"></td>
                        <td rowspan="2"><input type="button" name="func+" class="button" value="+" style="height: 64px" onclick="func(this.name.substring(4, 5));"></td>
                        <td><input type="button" name="func*" class="button" value="x" onclick="func(this.name.substring(4, 5));"></td>
                    </tr>
                    <tr>
                        <td><input type="button" name="number0" class="button" value="0" onclick="number(this.value);"></td>
                        <td><input type="button" name="number00" class="button" value="00" onclick="number(this.value);"></td>
                        <td><input type="button" name="dot" class="button" value="." onclick="dot();"></td>
                        <td><input type="button" name="equals" class="button" value="=" onclick="result(this.name);"></td>
                    </tr>
                </table>
            </form>
        </td>
    </tr>
</table>

Upvotes: 1

Scott Schwalbe
Scott Schwalbe

Reputation: 430

Are you closing your IIFE at the end of your code? If not, add

})();

to the end of your file.

separate

    // Variables
  var screen = elem('.screen'); 
    equal = elem('.equal'); 
    nums = elem('.num');
    ops = elem('.operator');
    theNum = ""; 
    oldNum = ""; 
    resultNum; 
    operator; 

by commas, not semicolons.

Also, viewer is not defined.

There might be other things, but that should be a start

Upvotes: 0

Related Questions