0

This one really has me scratching my head.

I'm building a calculator using JavaScript as an exercise. Said calculator is up and running here on Codepen. In the lower left you will see a "+-" button, which simply takes the content of the input field, and reverses it's sign (positive becomes negative, negative becomes positive.) Then when the user presses an operation button this is pulled and used in the calculation. Simple right?

The function which actually changes the sign is as follows:

function toggleSign() {
    if(getCurrentDispVal()[0] === "-") {
        currentNumStr = currentNumStr.slice(1, currentNumStr.length);
    } else {
        currentNumStr = "-" + currentNumStr;
    }
    updateDisplay(currentNumStr);
}

and is called in just one place, a function which takes input from the user and decides what to do with it:

function useInput(input) {
    if(input.match(/(\d|\.)/)) {
        handleDigitInput(input);
    } else if(input.match(/(X|\/|-|\+)/)) {
        handleBinaryOperation(input);
    } else if(input.match(/=/)) {
        handleEqualsOperation();
    } else if(input.match(/^c$/)) {
        clearCurrentNumStr();
    } else if(input.match(/^ac$/)) {
        allClear();
    } else if(input.match(/^shorten$/)) {
        shortenCurrentNumStr(); 
    } else if(input.match(/^plusmin$/)) {
        toggleSign();
    }
}

Now sometimes, and only sometimes, this works as expected. For instance, enter the following: 1 on keyboard, not the screen Click the "+-" button + on keyboard 5 on keyboard enter on keyboard

Sometimes this runs properly, and spits "4" as the result. Sometimes, and this is baffling me, when you hit enter it flips the sign on "5" making it "-5" and then returns "-6" as the answer." I've done some checking and can see that when this occurs, in the useInput function both the /=/ and /^plusmin$/ conditionals are being triggered. Thus toggleSign is being called prior to handleEqualsOperation and this is lousing up the results. Strangely, if you don't use the keyboard, and just click the screen buttons directly, this problem doesn't occur.

I'm at a loss here. There doesn't seem to be any pattern as to when this occurs, and I'm using the same input above over and over. I don't understand why this is occurring, and why it isn't occurring consistently.

Jonathon Nordquist
  • 2,066
  • 4
  • 21
  • 23

1 Answers1

2

So for what I can see, there is a problem in the way you handle the "currentNumStr" variable, follow this example, to find another problem:

press 5
press the +/- button to toggleSign
press the X button
press 6

"It will display -30", but since you made an operation (handleBinaryOperation, handleEqualsOperation) "currentNumStr" will be empty"
press the +/- button to toggleSign
you will get an empty display

If you track this variable you'll get your answer.

Also keep in mind that e.key is not cross-browser compatible, maybe you could use e.keyCode or e.which instead, I got many undefined errors because of this.

EDIT: To exemplify what I added in the comments:

in the HTML change this:

<div class="calc-body>

to this, choose the id you want ( the tabindex is necessary so the div cant get the focus)

<div class="calc-body" id="forFocusId" tabindex="0">

and in the Js file, add a global var to assign the div ( if you dont want to add a variable, you can call document.getElementById("forFocusId") in the next step instead)

var focusElement = document.getElementById("forFocusId");

finally at the end of the function useInput, add

focusElement.focus();
  • I appreciate the help but a solution still eludes me. I've tried tracking the currentNumStr variable as you suggest and I've followed it all the way up. The problem is that my useButtonInput function is being called when it shouldn't. I've tracked it's event like so: function useButtonInput(e) { console.log(e) if(!displayFocused) { val = this.dataset.button; useInput(val); } } and the event that is logged is definitely a click event. But I still don't know why a click event is being called when there should be none. – Jonathon Nordquist Feb 27 '17 at 17:55
  • Hey sorry for taking so long to answer, I've seen the code more closely and the problem seems to be the focus/enter in your calculator. As you described if you clicked the "-/+" button the focus stays there, and when you press the keys space or enter, the trigger both the keyup and the button pressed in your calculater, so you migth want to change the focus to the "input screen" everytime or prevent the enter and space keys to trigger the button clicked – Luis Carlos Arellano Ochoa Feb 28 '17 at 21:39
  • And you got me there! Your comment made me realize that I needed to be tracking the event, and that got me searching for keyboard events triggering click events. This SO question: http://stackoverflow.com/questions/27878940/spacebar-triggering-click-event-on-checkbox has the answer. "click" events don't just fire on clicks, they also are tied to keyboard events in some cases. I swapped 'click' for 'mousup' and haven't seen the problem since. Thanks mate, I owe you a beer. – Jonathon Nordquist Mar 02 '17 at 00:51
  • Glad I could help! :) – Luis Carlos Arellano Ochoa Mar 02 '17 at 17:24