Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
130
WebPercentEditor truncating, not rounding properly when set_value() client-side
posted

Our application uses a lot of javascript to calculate values before saving them.  In a couple of cases, I set the initial value of a WebPercentEditor to the result of a javascript calculation.  I discovered that when the value assigned has more digits than the value displayed, there are two issues regarding rounding.

1) The value assigned is being truncated, not rounded.  (We desire rounding anything up where the first hidden/truncated digit is 5 or higher.)  I am guessing set_value(x) is acting as if the value of x is being typed in.  Thus any digits after those displayed are ignored.  (Although I do not know for certain if this is the cause.)

So for a WebPercentEditor with MinDecimalPlaces = 4, DisplayFactor = 100, DataMode = Double:

ctrl.set_value(0.15529855694106875); should show 15.5299 %.  It currently shows 15.5298 %.  Although intriguingly I notice the mouse-over tooltip correctly shows 15.5299 %. 

2) If DisplayFactor is 100 (the default, and our desired value) and again MinDecimalPlaces = 4,

ctrl.set_value(0.000298); should show 0.0298 %.  It currently shows 0.0297 %.  (As does the mouse-over.)

I think this is because, due to javascript’s limitations, after the following calculation is done

var temp = 0.000298 * 100;

temp has a value of  0.029799999999999996.

This is probably what the WebPercentEditor is doing internally before truncating the digits.

 

I’ve come up with a workaround for us to assign values that assigns and rounds values for us as desired.  It is shown below.  But ideally the client-side set_value() method (or maybe a set_number() method) would do this for us.  Or is there some combination of settings I am missing that would cause the desired behavior?

 

            //Round a number more cleanly, with less floating point precision errors from Javascript

            function roundNumber(number, precision) {

                precision = Math.abs(parseInt(precision)) || 0;

                var multiplier = Math.pow(10, precision);

                return (Math.round(number * multiplier) / multiplier);

            }

 

            //Set the value of a WebPercentEditor or WebNumericEditor so that it will round and display appropriately.

            //Replace calls of "ctrl.set_value(val);" with "setEditorNumber(ctrl, val)" when rounding might be an issue.

            function setEditorNumber(ctrl, val) {

                var decimals = ctrl.get_minDecimals();

                if (ctrl._factor == 100) {

                    decimals += 2;

                }

                //The buffer is a small number to add before rounding to prevent something like 0.000298 to become

                //something like 0.029799999999999996 when the control changes to % and then 0.0297 % when it truncates

                //(assuming 4 decimal places displayed).

                var buffer = Math.pow(10, -(decimals + 1));

                ctrl.set_value(roundNumber(val, decimals) + buffer);

            }

 

Anyway, thanks in advance.

Trevor

Parents
  • 130
    posted

    Correction to my workaround code to fix rounding negative numbers:

     

     //Round a number more cleanly, with less floating point precision errors from Javascript  function roundNumber(number, precision) {

          precision = Math.abs(parseInt(precision)) || 0;

          var multiplier = Math.pow(10, precision);

          return (Math.round(number * multiplier) / multiplier);

      }

     //Set the value of a WebPercentEditor or WebNumericEditor so that it will round and display appropriately.

      //Replace calls of "ctrl.set_value(val);" with "setEditorNumber(ctrl, val)" when rounding might be an issue.  function setEditorNumber(ctrl, val) {

          var decimals = ctrl.get_minDecimals();

          if (ctrl._factor == 100) {

              decimals += 2;

          }

          //The buffer is a small number to add before rounding to prevent something like 0.000298 to become

          //something like 0.029799999999999996 when the control changes to % and then 0.0297 % when it truncates

          //(assuming 4 decimal places displayed).

          var buffer = Math.pow(10, -(decimals + 1));

          if (val < 0) {

              ctrl.set_value(roundNumber(val, decimals) - buffer);

          }

          else {

              ctrl.set_value(roundNumber(val, decimals) + buffer);

          }

      }

     

Reply Children