SMH
SMH

Reputation: 1099

How to display number in 2 decimal place but store it in 4 decimal place in Angular

I am working on a project where we need to do some accurate number calculation but also we have to display the numbers in nice format to the users.

Here is HTML code


 <span> {{ getTotalStocksValue() }} %</span>   
    <button data-ng-click="redistribute()">Redistribute</button>
    <form action="">
        <input type="text" data-numeric-input-directive   data-ng-repeat="stock in stocks" data-ng-model="stock.value">
    </form>

We display some stocks with their values and the value of a stock can be changed manually. we display the total of stocks values in the span using getTotalStocksValue() function. And the redistribute button redistributes the stocks value so the total value will be 100%.

The requirement is to display the stocks values in the inputs in 2 decimal place but we should also keep the stocks values in 4 decimal palace as we need that to perform a more accurate calculation in the getTotalStocksValue function. for example if we have 3 stocks and each stock has 33.33 as value the total is 99.99, while if the user change the stocks value to 33.3333 for each stock then the total should be rounded to 100 if it was 99.9999. I don't know if implementing this is possible in Angular. the only idea I have is to display in the stocks values in the inputs as 4 decimal place and also display them in a span or div in 2 decimal place. Any ideas or advice?

Upvotes: 2

Views: 1753

Answers (3)

davidkonrad
davidkonrad

Reputation: 85528

I think it calls for a directive that handle the values as a copy.

You could have a <stock-value value="stock.value"></stock-value> that is replaced with your above <input> markup where a local fixed decimal ng-model is injected :

<div ng-repeat="stock in stocks">
  <stock-value value="stock.value"></stock-value>
</div>

directive :

.directive('stockValue', function($compile) {
   return {
     restrict: 'E',
     template: '<input type="text" data-numeric-input-directive>',
     replace: true,
     scope: {
       value: '='
     },
     controller: function($scope) {
       $scope.localModel = undefined
     },
     link: function link(scope, element, attrs) {
       scope.localModel = parseFloat(scope.value || 0).toFixed(2);
       if (!element.attr('ng-model')) {
         element.attr('ng-model', 'localModel');
         $compile(element)(scope);
       }
       scope.$watch('localModel', function(newVal, oldVal) {
         if (!oldVal || newVal === oldVal) return
         scope.value = parseFloat(newVal).toFixed(4);
       })
     }
   }
});

see this plunkr -> http://plnkr.co/edit/P9uHZwTzgK9mJkRHRrl9?p=preview

The user see a two decimal fixed value, the original value is not truncated, but if user enters a new value the old value will be overwritten to max 4 decimals.

Upvotes: 1

Vivek P Rajeev
Vivek P Rajeev

Reputation: 86

Try using

let parsedValue = parseFloat(number).toFixed(4);

now the value in number will be rounded off to 4 decimal places and show "number" in the view using angular decimal pipe like

number | number:'1.2-2' 

Hope this helps

Upvotes: 1

bugs
bugs

Reputation: 15313

Simply use the official angular DecimalPipe.

yourNumber | number:'1.2-2' will always display the number with at least one integer digit, and always 2 decimals.

Upvotes: 0

Related Questions