From 4543e0e5e925c0b395853f66ed2fe6b4b34eb441 Mon Sep 17 00:00:00 2001 From: Igor Rafael Date: Fri, 27 Oct 2017 08:44:33 -0200 Subject: [PATCH] fix(uiPercentageMask): fix value update when using dynamic decimals --- src/global/percentage/percentage.js | 54 ++++++++++-------------- src/global/percentage/percentage.test.js | 12 +++--- 2 files changed, 29 insertions(+), 37 deletions(-) diff --git a/src/global/percentage/percentage.js b/src/global/percentage/percentage.js index 4d8a7c14..f859fe1b 100644 --- a/src/global/percentage/percentage.js +++ b/src/global/percentage/percentage.js @@ -4,51 +4,48 @@ var validators = require('../../helpers/validators'); var NumberMasks = require('../../helpers/number-mask-builder'); var PreFormatters = require('../../helpers/pre-formatters'); -function PercentageMaskDirective($locale) { - function preparePercentageToFormatter(value, decimals, modelMultiplier) { - return PreFormatters.clearDelimitersAndLeadingZeros((parseFloat(value)*modelMultiplier).toFixed(decimals)); - } +function preparePercentageToFormatter(value, decimals, modelMultiplier) { + return PreFormatters.clearDelimitersAndLeadingZeros((parseFloat(value)*modelMultiplier).toFixed(decimals)); +} +function PercentageMaskDirective($locale) { return { restrict: 'A', require: 'ngModel', link: function(scope, element, attrs, ctrl) { - var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP, - thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP, - percentageSymbol = ' %', - decimals = parseInt(attrs.uiPercentageMask), - backspacePressed = false; + var decimalDelimiter = $locale.NUMBER_FORMATS.DECIMAL_SEP; + var backspacePressed = false; element.bind('keydown keypress', function(event) { backspacePressed = event.which === 8; }); - var modelValue = { - multiplier : 100, - decimalMask: 2 - }; - + var thousandsDelimiter = $locale.NUMBER_FORMATS.GROUP_SEP; if (angular.isDefined(attrs.uiHideGroupSep)) { thousandsDelimiter = ''; } - if (angular.isDefined(attrs.uiHideSpace)) { + var percentageSymbol = ' %'; + if (angular.isDefined(attrs.uiHidePercentageSign)) { + percentageSymbol = ''; + } else if (angular.isDefined(attrs.uiHideSpace)) { percentageSymbol = '%'; } - if (angular.isDefined(attrs.uiHidePercentageSign)) { - percentageSymbol = ''; + var decimals = parseInt(attrs.uiPercentageMask); + if (isNaN(decimals)) { + decimals = 2; } + var modelValue = { + multiplier : 100, + decimalMask: 2 + }; if (angular.isDefined(attrs.uiPercentageValue)) { modelValue.multiplier = 1; modelValue.decimalMask = 0; } - if (isNaN(decimals)) { - decimals = 2; - } - var numberDecimals = decimals + modelValue.decimalMask; var viewMask = NumberMasks.viewMask(decimals, decimalDelimiter, thousandsDelimiter), modelMask = NumberMasks.modelMask(numberDecimals); @@ -57,14 +54,14 @@ function PercentageMaskDirective($locale) { if (ctrl.$isEmpty(value)) { return value; } - var prefix = (angular.isDefined(attrs.uiNegativeNumber) && value < 0) ? '-' : ''; var valueToFormat = preparePercentageToFormatter(value, decimals, modelValue.multiplier); + var formatedValue = prefix + viewMask.apply(valueToFormat) + percentageSymbol; - return prefix + viewMask.apply(valueToFormat) + percentageSymbol; + return formatedValue; } - function parse(value) { + function parser(value) { if (ctrl.$isEmpty(value)) { return null; } @@ -102,22 +99,17 @@ function PercentageMaskDirective($locale) { } ctrl.$formatters.push(formatter); - ctrl.$parsers.push(parse); + ctrl.$parsers.push(parser); if (attrs.uiPercentageMask) { scope.$watch(attrs.uiPercentageMask, function(_decimals) { decimals = isNaN(_decimals) ? 2 : _decimals; - if (angular.isDefined(attrs.uiPercentageValue)) { - modelValue.multiplier = 1; - modelValue.decimalMask = 0; - } - numberDecimals = decimals + modelValue.decimalMask; viewMask = NumberMasks.viewMask(decimals, decimalDelimiter, thousandsDelimiter); modelMask = NumberMasks.modelMask(numberDecimals); - parse(ctrl.$viewValue); + parser(formatter(ctrl.$modelValue)); }); } diff --git a/src/global/percentage/percentage.test.js b/src/global/percentage/percentage.test.js index 8e17d922..caf3745f 100644 --- a/src/global/percentage/percentage.test.js +++ b/src/global/percentage/percentage.test.js @@ -61,7 +61,7 @@ describe('ui-percentage-mask', function() { }); var model = input.controller('ngModel'); - expect(model.$viewValue).toBe('100%'); + expect(model.$viewValue).toBe('1%'); }); it('should hide space before "%" after a model change if ui-hide-space is present', angular.mock.inject(function($rootScope) { @@ -71,7 +71,7 @@ describe('ui-percentage-mask', function() { }); var model = input.controller('ngModel'); - expect(model.$viewValue).toBe('100%'); + expect(model.$viewValue).toBe('1%'); $rootScope.model = 50; //When accessing via rootScope, update model to 50 not 0.5 to represent 50% $rootScope.$digest(); @@ -94,14 +94,14 @@ describe('ui-percentage-mask', function() { it('should allow changing the number of decimals', angular.mock.inject(function($rootScope) { var input = TestUtil.compile('', { model: '12.345', - decimals: 2 + decimals: 1 }); var model = input.controller('ngModel'); - expect(model.$viewValue).toBe('1,234.50 %'); + expect(model.$viewValue).toBe('1,234.5 %'); $rootScope.decimals = 3; $rootScope.$digest(); - expect(model.$viewValue).toBe('123.450 %'); + expect(model.$viewValue).toBe('1,234.500 %'); $rootScope.decimals = 'invalid value'; $rootScope.$digest(); expect(model.$viewValue).toBe('1,234.50 %'); @@ -196,7 +196,7 @@ describe('ui-percentage-mask', function() { expect(model.$viewValue).toBe('1,234.50 %'); $rootScope.decimals = 3; $rootScope.$digest(); - expect(model.$viewValue).toBe('123.450 %'); + expect(model.$viewValue).toBe('1,234.501 %'); $rootScope.decimals = 'invalid value'; $rootScope.$digest(); expect(model.$viewValue).toBe('1,234.50 %');