Home > Software engineering >  Can't find a way to keep my keyboard input working on a Javascript Calculator with Keyboard Eve
Can't find a way to keep my keyboard input working on a Javascript Calculator with Keyboard Eve

Time:12-07

I'm making a simple calculator.

I've added an event listener and a console.log() to print my event and see what happens, but I've noticed that it only fires when I click on the calculator again.

// stores the results of the equations
let runningTotal = 0;  
// displays it's value on the screen
let buffer = "0"; 
// stores the last inputed operator ( ,-,*,/)
let previousOperator; 

const screen = document.querySelector('.screen');

function inputKeys(value){
    if(isNaN(value)){
        handleSymbol(value);
    } else {
        handleNumber(value);
    }

    screen.innerText = buffer;
}

function handleSymbol(symbol){
    switch (symbol) {
        case 'C':
            buffer = '0';
            runningTotal = 0;
            break;
        case '=':
            if(previousOperator === null) return;
            
            flushOperation(parseFloat(buffer));
            previousOperator = null;
            buffer = runningTotal;
            runningTotal = 0;
            
            break;
        case '←':
            if(buffer.length === 1)
                buffer = '0';
            else
                buffer = buffer.toString(0, buffer.length - 1)
                
            break;
        case ' ':
        case '−':
        case '×':
        case '÷':
            handleMath(symbol);
            break;
        case '.':
            handleDecimal(symbol);
            break;
    }
}

function handleNumber(numberString){
    if(buffer === "0"){
        buffer = numberString;
    } else {
        buffer  = numberString;
    }
}

function handleDecimal(symbol) {
    if(!buffer.includes(symbol)){
        buffer  = symbol;
    } else {
        return;
    }
}

function handleMath(symbol){
    if(buffer === '0') return; 

    const floatBuffer = parseFloat(buffer);

    if(runningTotal === 0){
        runningTotal = floatBuffer;
    } else {
        flushOperation(floatBuffer);
    }
    previousOperator = symbol;
    buffer = '0';
}

function flushOperation(floatBuffer) {
    if(previousOperator === ' '){
        runningTotal  = floatBuffer;
    } else if(previousOperator === '−'){
        runningTotal -= floatBuffer;
    } else if(previousOperator === '×'){
        runningTotal *= floatBuffer;
    } else if(previousOperator === '÷'){
        runningTotal /= floatBuffer;
    }
}

function init(){
    document.querySelector('.calc-buttons').addEventListener('keydown', function (event) {
        console.log(event);
    })
    document.querySelector('.calc-buttons').addEventListener('click', function (event) {
        inputKeys(event.target.innerText);
    })
}

init();
<div >
  <section >0</section>

  <section >

    <div class=calc-button-row>
      <button >
          C
      </button>
      <button >
          &larr;
      </button>
      <button >
          &divide;
      </button>

    </div>

      <div >
        <button >
            7
        </button>
        <button >
            8
        </button>
        <button >
            9
        </button>
        <button >
            &times;
        </button>
      </div>

      <div >
        <button >
            4
        </button>
        <button >
            5
        </button>
        <button >
            6
        </button>
        <button >
            &minus;
        </button>
      </div>

      <div >
        <button >
            1
        </button>
        <button >
            2
        </button>
        <button >
            3
        </button>
        <button >
            &plus;
        </button>
      </div>

      <div >
        <button >
            0
        </button>
        <button >
            .
        </button>
        <button >
            &equals;
        </button>
      </div>

  </section>
</div>

EDIT: Just noticed that my 'case '←'' is not working either.

CodePudding user response:

You're adding the keydown listener on the calculator. That's why you have to click on the calculator first before using the key input. You have to focus on the element first.

Instead, add the keydown listener on the document. Here's an example:

let runningTotal = 0; //stores the results of the equations
let buffer = "0"; //displays it's value on the screen
let previousOperator; //stores the last inputed operator ( ,-,*,/)

const screen = document.querySelector('.screen');

function inputKeys(value) {

  if (isNaN(value))
    handleSymbol(value);
  else
    handleNumber(value);

  screen.innerText = buffer;
}

function handleSymbol(symbol) {
  switch (symbol) {
    case 'C':
      buffer = '0';
      runningTotal = 0;
      break;
    case '=':
      if (previousOperator === null) {
        return
      }
      flushOperation(parseFloat(buffer));
      previousOperator = null;
      buffer = runningTotal;
      runningTotal = 0;
      break;
    case '←':
      if (buffer.length === 1)
        buffer = '0';
      else
        buffer = buffer.toString(0, buffer.length - 1)
      break;
    case ' ':
    case '−':
    case '×':
    case '÷':
      handleMath(symbol);
      break;
    case '.':
      handleDecimal(symbol);
      break;
  }
}

function handleNumber(numberString) {
  if (buffer === "0") {
    buffer = numberString;
  } else {
    buffer  = numberString;
  }
}

function handleDecimal(symbol) {
  if (!buffer.includes(symbol)) {
    buffer  = symbol;
  } else {
    return;
  }
}

function handleMath(symbol) {
  if (buffer === '0') {
    return;
  }
  const floatBuffer = parseFloat(buffer);

  if (runningTotal === 0) {
    runningTotal = floatBuffer;
  } else {
    flushOperation(floatBuffer);
  }
  previousOperator = symbol;
  buffer = '0';
}

function flushOperation(floatBuffer) {
  if (previousOperator === ' ') {
    runningTotal  = floatBuffer;
  } else if (previousOperator === '−') {
    runningTotal -= floatBuffer;
  } else if (previousOperator === '×') {
    runningTotal *= floatBuffer;
  } else if (previousOperator === '÷') {
    runningTotal /= floatBuffer;
  }
}

function init() {

  document.addEventListener('keydown', function(event) {
    inputKeys(event.key)
  })
  document.querySelector('.calc-buttons').addEventListener('click', function(event) {
    inputKeys(event.target.innerText);
  })
}
init();
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="style.css">
  <title>CALCULADORA DO NUNES</title>
</head>

<body>

  <div >

    <section >0</section>
    <section >
      <div class=calc-button-row>
        <button >
                    C
                </button>
        <button >
                    &larr;
                </button>
        <button >
                    &divide;
                </button>

      </div>

      <div >
        <button >
                    7
                </button>
        <button >
                    8
                </button>
        <button >
                    9
                </button>
        <button >
                    &times;
                </button>
      </div>

      <div >
        <button >
                    4
                </button>
        <button >
                    5
                </button>
        <button >
                    6
                </button>
        <button >
                    &minus;
                </button>
      </div>

      <div >
        <button >
                    1
                </button>
        <button >
                    2
                </button>
        <button >
                    3
                </button>
        <button >
                    &plus;
                </button>
      </div>

      <div >
        <button >
                    0
                </button>
        <button >
                    .
                </button>
        <button >
                    &equals;
                </button>
      </div>
    </section>

  </div>

  <script src="script.js"></script>

</body>

</html>

CodePudding user response:

It is first clue for you. Try use slice for case '←'. Just console.log(buffer); before slice and after to check your result.

  • Related