1

Im trying to make a formula dynamic and also the input fields. First problem is to change the (c1 + d2) into values like (1 + 2) depending on what is the value in input. consider that tdinput is dynamic so I can add as many as I can and formula can change anytime.

<input class="tdinput" type="text" data-key="c1">
<input class="tdinput" type="text" data-key="d2">

<input type="text" data-formula="(c1 + d2)">

<script>
    $('.tdinput').on('change', function() { 
        var key = $(this).attr('data-key');
        $('[data-formula*="+key+"]').each(function() { 
            //now here goes to change the data-formula by inputted values
            //calculate using eval()
        });
    });

</script>
0

2 Answers 2

2

You need to make a more modular approach with this. And make good use of the javascript jquery api you're using.

When a variable is defined by data-something-something you can access it by jQuerySelectedElement.data('something-something')

Now, eval is evil, but when you sanitise your input variables(in this case by parseInt) you should be relatively save from xss inputs etc..

What happens is, all the variables are inserted as an property in an object t. then eval will call and and access all the objects in t and do the calculation.

Only requirement is that you define all the variables not as just c2, but as t.c2 in your key definition properties.

have a look below at the play with the data properties and the eval.

When using eval ALWAYS make sure you only eval 'safe' data! Don't eval strings if you plan to safe user input! you open your site for XSS attacks then.

$('[data-formula]').on('keyup', function() { 
        var $this = $(this);
        var formulaName = $this.data('formula');
        var $output = $('[data-formula-name="'+formulaName+'"]');
        var formula = $output.data('formula-calc');
        
        var t = {};
        var keys = [];
        $select = $('[data-formula="'+formulaName+'"]');
        $select.each(function(index,elem) {
             var $elem = $(elem);
             var key = $elem.data('key');
             t[key] = parseFloat($elem.val());
             keys.push(key);
             if(isNaN(t[key])) {
                t[key]=0;
             }
        });
        for(var c=0;c<keys.length;c++) {
            formula = formula.replace(new RegExp(keys[c],'g'),'t.'+keys[c]);
        }
        var result = 0;
        eval('result = '+formula)
        $output.val(result)
        
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
sum:
<input class="tdinput" type="text" data-formula="sum" data-key="c1">
<input class="tdinput" type="text" data-formula="sum" data-key="d2">
<input type="text" data-formula-name="sum" data-formula-calc="(c1 + d2)" disabled>
<BR/>
xor
<input class="tdinput" type="text" data-formula="pow" data-key="c1">
<input class="tdinput" type="text" data-formula="pow" data-key="d2">
<input type="text" data-formula-name="pow" data-formula-calc="(c1 ^ d2)" disabled>
<BR/>
sub
<input class="tdinput" type="text" data-formula="sub" data-key="c1">
<input class="tdinput" type="text" data-formula="sub" data-key="d2">
<input type="text" data-formula-name="sub" data-formula-calc="(c1 - d2)" disabled>
<BR/>
silly
<input class="tdinput" type="text" data-formula="silly" data-key="c1">
<input class="tdinput" type="text" data-formula="silly" data-key="d2">
<input type="text" data-formula-name="silly" data-formula-calc="(c1 / d2 * 3.14567891546)" disabled>

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

3 Comments

thank you for letting me understanding the concept of eval. i just notice that it cuts the processing of eval when you put non numeric values.
you don't want to input non numeric values. that will open you up to xss attacks, well, the ability to input non numeric values, that will be shared with others possibly, opens your site to xss attacks. I just added a isnan filter that only allows numeric input
Also made keys fluid ;-) no more need for adding t. manually before it :-)
1

You can use eval().

Logic

  • Fetch formula and save it in string
  • Get all valid keys
  • Replace keys with value in formula
  • Use eval() to process it

Sample

JSFiddle

$("#btnCalculate").on("click", function() {
   var $f = $("input[data-formula]");
   var formula = $f.data("formula");
   formula.split(/[^a-z0-9]/gi)
      .forEach(function(el) {
         if (el) {
            let v = $("[data-key='" + el + "']").val();
            formula = formula.replace(el, v);
         }
      });

   var result = eval(formula);
   console.log(result)
   $f.val(result)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input class="tdinput" type="text" data-key="c1">
<input class="tdinput" type="text" data-key="d2">
<br/>
<input type="text" data-formula="(c1 + d2)">
<button id="btnCalculate">calculate</button>

Reference

Comments

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.