0

I'm trying to make a calculator in JS and I'm searching for ways to add, subtract, multiply and divide button values. I've created a function to display the buttons but now I realize that that might not be necessary and I might need just one function which displays and does the operation.

HTML code:

        <div class="numbers">
            <button value="1" onclick="displayButtons(this)">1</button>
            <button value="2" onclick="displayButtons(this)">2</button>
            <button value="3" onclick="displayButtons(this)">3</button>
            <button value="4" onclick="displayButtons(this)">4</button> 
            <button value="=" id="calculate" onclick="performOperations(this)">=</button>
            **etc.**
        <div class="operations">
            <button value="+" onclick="displayButtons(this)" style="width: 2rem; top: 5rem;">+</button>
            <button value="-" onclick="displayButtons(this)" style="left: -6rem; top: 5rem;">-</button>
            **etc.**

JS code:


function displayButtons(button) {
    outputDiv.innerHTML += button.value
}

function performOperations(button) {

    var val = parseFloat(button.getAttribute("value"));
    var total = parseFloat(document.getElementById('output').getAttribute("value"));

    document.getElementById('output').innerHTML = total + val;
}

That is my attempt to do addition the button values and I have the performOperations called on the "=" sign which currently displays NaN onclick. (I'm working on the addition first).
Any push in the right direction is appreciated. Thank you!

4
  • If the value of the = button is =, what exactly are you attempting to do with parsing it to Float and adding = to total ? Commented May 24, 2022 at 18:46
  • My suggestion is that you debug each line to see what is happening yourself. Commented May 24, 2022 at 18:47
  • You are right, the = value doesn't make sense. As for debugging, do you have any website or software recommendations which will help me debug it line by line? I only use Chrome Developer Tools. Commented May 24, 2022 at 18:58
  • Personally, I use console.log() for debugging. When I question what the outcome of a line of code is, I will console.log() the result to verify if it's producing the result I expect. Commented May 24, 2022 at 19:05

1 Answer 1

2

You're right that you can use one function to do all the work but it means that you have to mark up your HTML with classes and data-attributes.

In this example I've used CSS grid to display the various calculator buttons. The "equals" and "clear" buttons have a data attribute to help the function decide what operation to do.

// Cache our elements and add an event listener
// to the button container. `handleClick` returns a
// new function that is called when the listener is fired
const output = document.querySelector('.output');
const buttons = document.querySelector('.buttons');
buttons.addEventListener('click', handleClick(), false);

function handleClick() {

  // Initialise the sum
  const sum = [];

  // Return the function that will be called
  // when a click event occurs
  return function(e) {

    // Because we're using event delegation (details
    // below) we need to check that the element that
    // was clicked was a button
    if (e.target.matches('.button')) {

      // Destructure the type from the dataset, and
      // the text content
      const { dataset: { type }, textContent } = e.target;

      // `switch` on the type
      switch (type) {

        // If it's equals evaluate the elements in
        // the array, and output it
        case 'equals': {
          output.textContent = eval(sum.join(''));
          break;
        }
        
        // Clear empties the array, and clears
        // the output
        case 'clear': {
          sum.length = 0;
          output.textContent = '';
          break;
        }
        
        // Otherwise add the textContent to
        // the array, and update the output
        default: {
          sum.push(textContent);
          output.textContent = sum.join(' ');
          break;
        }
      }
    }

  }

}
.container{width:175px;}
.buttons {display: grid; grid-template-columns: repeat(4, 40px);grid-gap:0.3em;}
.button {display:flex;justify-content:center;align-items:center;background-color: #efefef; border: 1px solid #565656;padding: 0.5em;}
.button:not(.void):hover {background-color: #dfdfdf; cursor:pointer;}
.output {height: 20px; padding: 0.5em 0.2em;font-size: 1.2em;border:1px solid #565656;margin-bottom: 0.2em;}
<div class="container">
  <div class="output"></div>
  <div class="buttons">
    <div class="button">7</div>
    <div class="button">8</div>
    <div class="button">9</div>
    <div class="button">*</div>
    <div class="button">4</div>
    <div class="button">5</div>
    <div class="button">6</div>
    <div class="button">/</div>
    <div class="button">1</div>
    <div class="button">2</div>
    <div class="button">3</div>
    <div class="button">-</div>
    <div class="button">0</div>
    <div data-type="clear" class="button">C</div>
    <div data-type="equals" class="button">=</div>
    <div class="button">+</div>
  </div>
</div>

Additional documentation

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for showing me the solution. What I'm surprised is that I had a code in mind which looked like: var answer = num1 + num2 return answer Where are all the operations coming from? For instance the division or multiplication. Which part tackles that? Thank you!
@RebjaA. It all happens in the eval statement: eval(sum.join(''). When you click on a button its text content is added to an array whether its 1, 5, +, or *. When the equals button is clicked it joins up the array, evaluates the string, and then outputs it.
So the sum.join method kind of detects the operations symbols and performs the necessary operations? Am I correct? Sorry, I just want to make sure I understand the code.
Yeah, so if I click 1 then + then 1 then 0 the array will be [ '1', '+', '1', '0' ]. The join makes it "1+10". And that expression is evaluated to 11.
I see now. I'll look into the join method more since I didn't know it could do that. 😅 Thank you so so much! I appreciate it a ton.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.