1

I have a which has a default value declared in the controller and passed 'val:1.81' by ng-model. Such input must be numeric (type: number). By angular filters, managed to print only two decimal places on the next line by the filter 'number 2'. In addition, I need to include a couple of buttons to add or subtract '0.01' like a counter value input.

Is there any way to filter the input also with only two decimals? I mention this because as I sum by clicking the button, there comes a time that the input print eg '1.8800000000000001'.

Original JS Bin

var app = angular.module('myApp', []);

app.controller("mainCtrl", function($scope)
{
  $scope.val = 1.80;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="myApp" ng-controller="mainCtrl">
  <br/><br/>
  <div>
    <span style="color: red">Val input:</span>
  <input type="number" ng-model="val"/>
  <button ng-click="val = val - 0.01">-0.01</button>
  <button ng-click="val = val + 0.01">+0.01</button>
  </div>
  <div>Val: {{val | number:2}}</div>
  
  <hr>
  
  Val2 (val + 20): {{ val2 = val + 20 | number:2 }}
  
  <hr>
  
  Val2 input:
  <input type="number" ng-model="val2"/>
  
</div>
rene
  • 41,474
  • 78
  • 114
  • 152

3 Answers3

0

Please refer to https://stackoverflow.com/a/4640423 for reference about decimal precision on floats.

For your particular example something like this should be enough:

$scope.val = parseFloat(($scope.val - 0.01).toFixed(2));

Similarly, you can also use .toPrecision(3) instead.

EDIT: I saw you also ask about how to filter user input to 2 decimal cases. For that case the best option is to watch changes in the value and round accordingly as @alesc suggested.

EDIT2: I'd suggest that you leave the logic in the controller as good practice:

$scope.increment = function(increment) {
    $scope.val = parseFloat(($scope.val + increment).toFixed(2));
};

and then call in the html:

<button ng-click="increment(-0.01)">-0.01</button>
<button ng-click="increment(0.01)">0.01</button>
Community
  • 1
  • 1
Filipe Pereira
  • 198
  • 1
  • 10
  • Hello, thanks for the refer, I understand the reference, but I'm trying to apply your example and does not add or subtract me with the buttons. I'm writing something wrong? http://jsbin.com/gijejo/2/edit?html,js,output – maestro mutenrroy Jun 10 '15 at 12:31
  • Strange that it doesn't work, but check the edit for a cleaner way to solve it :) – Filipe Pereira Jun 10 '15 at 12:44
  • Edited the answer to remove the wrong piece of code. Refer to http://stackoverflow.com/a/23725364/1933561 to know why parseFloat is not available on the scope. – Filipe Pereira Jun 10 '15 at 12:51
0

One (IMO dirty) solution would be to watch for changes over $scope.val and round the number to 2-digits as it happens.

You just modify your controller as follows:

app.controller("mainCtrl", function($scope)
{
    $scope.val = 1.80;
    $scope.$watch(
      function(scope) { 
        return scope.val; 
      },
      function(num) {
        $scope.val = Math.round(num * 100) / 100;
      }
  );
});

This way, whenever a change happens, you overwrite the value with the 2-digit rounded value. No other HTML and/or template changes are necessary.

JS Bin example: http://jsbin.com/viyixofova/1/ (only the first input has the rounding implemented).

alesc
  • 2,776
  • 3
  • 27
  • 45
-1

Ok thanks for the help, finally I use this: http://jsbin.com/gijejo/9/edit

Last question, Is there a way to unify the increment and decrement function for any value of the input ng-model by not to repeat the parseFloat by value?

Thanks again