From 6609f19e2f22b9945fc8f6b5868897c5c6c1b52e Mon Sep 17 00:00:00 2001 From: Mariano Benedettini Date: Thu, 26 Oct 2017 00:53:01 +0300 Subject: [PATCH] feat(uiMoneyMask): format and parse integer models * New attr ui-integer-model: convert from and to integer model It's quite common to store money values as integers: storing money as decimal will likely lead to rounding errors. It esentially will divide model value by the number of decimals when formatting it and perform the equivalent multiplication when parsing it. * Add a couple of tests --- src/global/money/money.js | 13 ++++++++++++- src/global/money/money.test.js | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/global/money/money.js b/src/global/money/money.js index 78ead721..5016249a 100644 --- a/src/global/money/money.js +++ b/src/global/money/money.js @@ -64,6 +64,9 @@ function MoneyMaskDirective($locale, $parse) { if (ctrl.$isEmpty(value)) { return value; } + if (angular.isDefined(attrs.uiIntegerModel)) { + value = value / Math.pow(10, decimals); + } var prefix = (angular.isDefined(attrs.uiNegativeNumber) && value < 0) ? '-' : ''; var valueToFormat = PreFormatters.prepareNumberToFormatter(value, decimals); if (angular.isDefined(attrs.uiCurrencyAfter)) { @@ -109,7 +112,15 @@ function MoneyMaskDirective($locale, $parse) { ctrl.$render(); } - return formatedValue ? parseInt(formatedValue.replace(/[^\d\-]+/g,''))/Math.pow(10,decimals) : null; + var retValue = parseInt(formatedValue.replace(/[^\d\-]+/g,'')); + if (!isNaN(retValue)) { + if (!angular.isDefined(attrs.uiIntegerModel)) { + retValue = retValue / Math.pow(10, decimals); + } + return retValue; + } else { + return null; + } } ctrl.$formatters.push(formatter); diff --git a/src/global/money/money.test.js b/src/global/money/money.test.js index eadc5cf1..d9358a32 100644 --- a/src/global/money/money.test.js +++ b/src/global/money/money.test.js @@ -269,4 +269,22 @@ describe('ui-money-mask', function() { var model = input.controller('ngModel'); expect(model.$viewValue).toBe('345.00 EUR'); }); + + it('should format integer models', function() { + var input = TestUtil.compile('', { + model: 12345 + }); + + var model = input.controller('ngModel'); + expect(model.$viewValue).toBe('$ 123.45'); + }); + + it('should parse integer models', function() { + var input = TestUtil.compile('', {}); + var model = input.controller('ngModel'); + + input.val('123.45').triggerHandler('input'); + expect(model.$viewValue).toBe('$ 123.45'); + expect(model.$modelValue).toBe(12345); + }); });