-3

I created a simple input box where a user would type in a simple equation (no variables)

For example a user would enter

(5+6) * 7 -2

And when the user hits the "Calculate" button, it triggers the jQuery which converts the input using .toString() which in turns solves the equation and then places the value in the element.

I am relatively new so I apologize if I am making really bad mistakes. I hope I have explained this properly.

Here is the HTML

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Interview exercise</title>
    <script type="text/javascript" src="test.js"></script>
</head>
<body>
    <input name = "equation"/> = <span id="answer"/>
    <br/>
    <button>Calculate</button>
</body>
</html>

Here is the JavaScript/jQuery

$(document).ready(function() {
    $('button').click(function() {
        var answer = $("input[name=equation]").toString();
        $('#answer') = answer;
    });
});
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
flatafor
  • 57
  • 1
  • 2
  • 6
    A string is not a mathematical operation. You'd have to parse the string and basically implement your own calculator. – Derek Nov 02 '16 at 01:09
  • try `$("#answer").text(eval(answer))` – Isaac Nov 02 '16 at 01:10
  • `eval` can be used but that is not safe. – Daniel A. White Nov 02 '16 at 01:10
  • 2
    For your sanity, I'd recommend learning JavaScript before jumping into jQuery and getting StackOverflow to hold your hand – Isaac Nov 02 '16 at 01:12
  • @Derek I thought toString() could convert an equation into a numerical value so long there were no variables? Also I am receiving an error stating "$ is not defined" Do you know why that may be? – flatafor Nov 02 '16 at 01:14
  • 1
    `.toString()` converts a value into a STRING. As the method name obviously says. To perform math calculations on MORE THAN ONE INPUT, you have to catch these numbers separatly. And then perform some sort of calculation of your own... Ensuring you deal with integers or floats, not strings. – Louys Patrice Bessette Nov 02 '16 at 01:18
  • @flatafor You did not include the jQuery library script in your page, so `$` is not defined. And no, `toString` does not evaluate equations. – Bergi Nov 02 '16 at 01:29
  • Are you trying to do this without a jQuery plugin? – react_or_angluar Nov 02 '16 at 01:31
  • 1
    @DanielA.White - Is `eval()` unsafe for this specific purpose? It would only be used on a value just entered in the current session, the value wouldn't be stored anywhere or be evaluated on other users' devices. (Of course, actually parsing the entered string rather than just `eval`ing it would allow graceful error handling if the user typed something invalid.) – nnnnnn Nov 02 '16 at 01:34
  • @nnnnnn yes eval is unsafe in all circumstances. – Daniel A. White Nov 02 '16 at 01:36
  • @DanielA.White - OK, unsafe how in *this* circumstance? What's the worst that could happen? – nnnnnn Nov 02 '16 at 01:37
  • they could do anything. – Daniel A. White Nov 02 '16 at 01:37
  • 1
    @DanielA.White - What "anything" could they do that they couldn't already do via the browser's console? Noting, again, that "anything" that a user could do in this circumstance could not affect other users. – nnnnnn Nov 02 '16 at 01:39

1 Answers1

0

I didn't know about the JavaScript eval() function.
Many thanks to the argumentation between @nnnnnn and @DanielA.White !

About eval() being unsafe:
Here is another SO answer to explain the risks which, in your case, are non-existant.

So here is the calculation function for your HTML:

$(document).ready(function(){
    $('button').click(function(){
        var answer = eval( $("input[name='equation']").val() );
        $('#answer').html(answer);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<input name="equation" value="(5+6) * 7 -2"> = <span id="answer"></span>
<br>
<button>Calculate</button>




EDIT
To make the .val() function safer...
But mostly to prevent impossible calculations, here is an update!

This elongated script filters for "allowed keys" from the keyboard.

Nevertheless, if an impossible calculation is inputted, like 4//(68+(),
it outputs : «Something is wrong in your equation.»

$(document).ready(function(){
    var allowedKeys=[48,49,50,51,52,53,54,55,56,57, // 0 to 9 (keyboard)
                     96,97,98,99,100,101,102,103,104,105, // 0 to 9 (numpad)
                     111,106,109,107,110,    // characters / * - + . (numpad)
                     189,190,8,32,13    // character - . [backspace] [space] [enter] (keyboard)
                    ];
    var allowedShiftKeys=[51,56,57,48,187,57,48,16];  // characters / * + ( ) [shift] (keyboard + shift)

    $("input[name='equation']").on("keydown",function(e){
        // Clear previous answer
        $('#answer').html("");

        // Check for allowed keydown
        if( ($.inArray( e.which,allowedKeys) != -1 && !e.shiftKey) || ($.inArray(e.which,allowedShiftKeys)!=-1 && e.shiftKey) ){
            console.log("Allowed key.");
        }else{
            // Don't print the key in the input field.
            console.log("Disllowed key.");
            e.preventDefault();

            // Helper to find key number
            console.log(e.which);
        }

        // [enter] handler to simulate a button click.
        if(e.which==13){
            $('button').click();
        }
    });

    $('button').click(function(){
        var InputtedValue = $("input[name='equation']").val();
        
        // Remove "//" sequence... Which has the special meaning of a "comment start".
        // Has to be removed before eval() works.
        for(i=0;i<InputtedValue.length;i++){
            var position = InputtedValue.indexOf("//");
            if(position!=-1){
                console.log('Removing "//" occurance.');
                InputtedValue = InputtedValue.replace("//","/");
                // Redo the loop from start.
                i=0;
                $("input[name='equation']").val(InputtedValue);
            }
        }

        // Try the eval() function... And catch the error if any (Error will come from the inputted formula).
        // Prevents the script from just jamming here.
        try{
            var answer = eval( InputtedValue );
        }
        catch(error){
            console.log("ERROR: "+error.message);
        }

        // If there is an answer.
        if(typeof(answer)==="number"){
            $('#answer').html(answer);
        }else{
            $('#answer').html("Something is wrong in your equation.");
        }
        console.log("Answer: "+answer);
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="equation" value="(5+6) * 7 -2"> = <span id="answer"></span>
<br>
<button>Calculate</button>
Community
  • 1
  • 1
Louys Patrice Bessette
  • 33,375
  • 6
  • 36
  • 64
  • Is there any way for it to run with the order of operations if the user does not input parantheses? – flatafor Nov 02 '16 at 18:17
  • I am working on a parenthesis issue right now... But not this one. If there is a missing parenthesis, the eval fails and the script aborts. Now if no parenthesis at all is quite another game!! I didn't notice `eval()` does not "evaluate it" correctly... Will check what I can do, but I will post my actual improvements first (in a couple minutes). – Louys Patrice Bessette Nov 02 '16 at 19:15
  • mmm. From the first test I just made, `eval()` **does** correctly account for operation order when no parenthesis are present. – Louys Patrice Bessette Nov 02 '16 at 19:18
  • I just posted my edit... I hope you will like it! It was fun to code ;) – Louys Patrice Bessette Nov 02 '16 at 19:28