2

I'm doing an example for this javascript textbook and it's a simple calculator. There are two input (number) tags where the user selects a number and a select tag with options for a modifier (see code).

<input type="number" value="2" id='num1'>
<select id="operation">
    <option>+</option>
    <option>-</option>
    <option>*</option>
    <option>/</option>
    <option>%</option>
</select>
<input type="number" value="2" id='num2'> =
<input type='text' readonly>
<br>
<input id="button1" type="button" value="Do It!">

What I have to do is get the values of both the numbers and then calculate the operation based on which modifier is selected in the options.

window.addEventListener("load", function() {
    document.getElementById("button1").onclick = function(event) {
        var num1 = document.getElementById("num1").value;
        var num2 = document.getElementById("num2").value;
        var mod = document.getElementById("operation").selectedIndex;
    }
});

However, I don't understand how to do the calculation with the modifier. Would I need an if statement where it checks what value the mod has and then depending on that it does a certain calculation? Or is there a simpler way to just get the modifier and do a certain calculation that way?

2 Answers 2

5

You can do something like this. The function will be called even if you just change the mathematical operator in the select box.

If you want to get the selected value from the select box, you have to use the .value prop, same as a normal input.

function count() {
  var num1 = document.getElementById("num1").value;
  var num2 = document.getElementById("num2").value;
  var mod = document.getElementById("operation").value;
  document.getElementById('result').value = eval(num1 + mod + num2);
}
<input type="number" value="2" id='num1'>
<select id="operation" onchange='count()'>
                <option>+</option>
                <option>-</option>
                <option>*</option>
                <option>/</option>
                <option>%</option>
            </select>
<input type="number" value="2" id='num2'> =
<input type='text' readonly id='result'><br>
<input id="button1" type="button" value="Do It!" onclick='count()'>

Like Scott Marcus pointed, the eval() function is not really suggested to use anywhere in your project and I'm aware of that, but this is only for learning purposes.

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

8 Comments

Don't ever use eval(). It slows execution, changes scope and opens the door to XSS attacks. There is hardly ever a valid use case for it.
@ScottMarcus Instead of downvoting, give another, working solution. And by the way - I'm sure that OP is just learning JS and he decided to do a simple calculator app. It's not for a commercial usage. I was doing the same thing, when I was starting with JS :)
@ScottMarcus I'm still waiting for your reply.
I was working on my answer - that's why I didn't respond right away. The fact that the OP may be just learning JS is all the more reason not to suggest something like eval. It takes time and experience to understand why it is dangerous and how to avoid it. It is best to show the proper way to solve the problem instead of introducing a solution that should never be used.
@ScottMarcus The fact that you are IT instructor doesn't mean anything. You have just proposed him more complex but slower solution. I've provided him a quicker way, but less safe. But that's not a reason for a downvote.
|
1

You will need to perform some if/then testing to see which value was selected and the proceed from there.

Also, don't use inline HTML event handling attributes (onclick, onchange) as they:

  • create spaghetti code that is hard to read
  • create anonymous global wrapper functions that modify the this binding
  • don't follow W3C DOM Event Standards

Instead, follow standards and set up event handlers using .addEventListener()

Lastly, it's not a great UI design to use a textbox (even a readonly one) for output that will not be interacted with directly. Instead, use a non-form HTML element (like a <span>) to house the result. You can always style the element to look anyway you want.

// When the DOM is loaded
window.addEventListener("DOMContentLoaded", function(){

  // Get references to DOM elements, not their values
  // This allows you to refrence the element over and over
  // without having to re-scan the DOM for it
  var select = document.getElementById("operation");
  var oper1 = document.getElementById("num1");
  var oper2 = document.getElementById("num2");
  var result = document.getElementById("result");
  var btn = document.getElementById("button1");

  // Set up a click event handler for the button and the select:
  btn.addEventListener("click", count);
  select.addEventListener("change", count);

  function count() {
    var answer = null;
  
    // Convert the text values to numeric values
    var n1 = parseFloat(oper1.value);
    var n2 = parseFloat(oper2.value);

    // Determine the math operation needed and proceed accordingly
    switch (select.value){
      case "+":
        answer = n1 + n2;
        break;
      case "-":
        answer = n1 - n2;
        break;
      case "*":
        answer = n1 * n2;
        break;
      case "/":
        answer = n1 / n2;
        break;
      case "%":
        answer = n1 % n2;
        break;       
    }

    // Inject the answer into the HTML element
    result.textContent = answer; 
  }
});
<input type="number" value="2" id='num1'>
<select id="operation">
                <option>+</option>
                <option>-</option>
                <option>*</option>
                <option>/</option>
                <option>%</option>
            </select>
<input type="number" value="2" id='num2'> =
<span id='result'></span><br>
<input id="button1" type="button" value="Do It!">

10 Comments

I totally disagree about using inline event handling attributes. If you are using it wisely, you won't make a spaghetti code. Do you know anything about Angular? It uses inline events in HTML often. I'm sure that if it would be a bad habit, Google wouldn't introduce it.
Thank you! For some reason when I hit the button it doesn't print out the answer though.
@Kinduser You seem to want to just thumb your nose at standards and best practices. I'm not giving you my opinions here - I'm giving you well-established facts that are industry standards and best practices. Comparing inline HTML event attributes to Angular's use of them is anecdotal at best since Angular's code processes in a completely different way. In short, you can disagree all you want, but that doesn't make you right.
@ScottMarcus Good night.
@ScottMarcus I personally use Riot.js which also uses inline event handlers. However, unlike Angular is stays very close to W3 Spec. I agree with @KindUser that if used wisely, you won't end up with spaghetti code. Eval() is bad for production but a complex example like yours is just as bad for learning. The OP specifically asked, ". . . Or is there a simpler way to just get the modifier and do a certain calculation that way?" And the answer is yes– by using eval(). Not recommended, but yes—it is possible.
|

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.