Reputation: 120
I am trying to make a currency/number input/output without rounding.
The issue I come across with using currency is two-fold, (1) it rounds the second decimal once a third number has been entered, (2) that it even allows a third number to be entered. If you notice my del() function, it deletes the end of the number, but while the display might be: $27.46. The string could actually be 27.45606020, and backspacing would delete numbers the user can't even see.
At the moment I have some hacky code that doesn't even bother with AngularJS currency or number and uses a filter to prevent digits after two decimal places, as well when a decimal is added, I have it so it can only be added once.
{{checkTotal | dropDigits}
.filter('dropDigits', function() {
return function(floatNum) {
return String(floatNum)
.split('.')
.map(function (d, i) { return i ? d.substr(0, 2) : d; })
.join('.');
};
})
.
.controller('tipController', function($scope) {
// Numpad
$scope.checkTotal = '0.00';
$scope.clicked = function (label) {
if($scope.checkTotal === '0.00') {
$scope.checkTotal = label;
} else {
$scope.checkTotal += label;
}
};
// Prevent multiple decimals
$scope.clickedDot = function() {
if (($scope.checkTotal.indexOf('.') < 0) || ($scope.checkTotal === '0.00')) {
if (($scope.checkTotal === '0.00') || ($scope.checkTotal === '')) {
$scope.checkTotal = '0.';
} else {
$scope.checkTotal += '.';
}
}
};
$scope.del = function () {
$scope.checkTotal = $scope.checkTotal.slice(0, -1);
};
});
Upvotes: 0
Views: 2011
Reputation: 120
I was able to fix my issue with another if statement
$scope.clicked = function(label) {
if ($scope.checkTotal === '0.00') {
$scope.checkTotal = label;
} else {
if (($scope.checkTotal.indexOf('.') != -1) && ($scope.checkTotal.substring($scope.checkTotal.indexOf('.')).length > 2)) { //if there is a decimal point, and there are more than two digits after the decimal point
label.preventDefault();
} else {
$scope.checkTotal += label;
}
}
};
Upvotes: 0
Reputation: 8980
You could use Math.floor
to cut the decimal places with-out rounding. Just multiply the value inside floor
by 100 and do the required math inside and then afterwards divide by 100 to have the correct result size.
Please have a look at the demo below or this fiddle.
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController($timeout) {
var vm = this;
angular.extend(vm, {
input: 10.25,
total: 0,
calcTip: function() {
// 10% tip // 2 decimal places no rounding.
// floor calc. from this SO answer
// http://stackoverflow.com/questions/4187146/display-two-decimal-places-no-rounding
vm.total = Math.floor(vm.input * 1.1 * 100) / 100;
}
});
vm.calcTip(); // initial calc.
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as mainCtrl">
<input ng-model="mainCtrl.input" ng-change="mainCtrl.calcTip()"/>
<br/>
<strong>{{mainCtrl.total | currency}}</strong>
</div>
Upvotes: 1