Skip to content

Commit

Permalink
fix(uiPercentageMask): fix value update when using dynamic decimals
Browse files Browse the repository at this point in the history
  • Loading branch information
assisrafael committed Oct 27, 2017
1 parent 6609f19 commit 4543e0e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 37 deletions.
54 changes: 23 additions & 31 deletions src/global/percentage/percentage.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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));
});
}

Expand Down
12 changes: 6 additions & 6 deletions src/global/percentage/percentage.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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();
Expand All @@ -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('<input ng-model="model" ui-percentage-mask="decimals">', {
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 %');
Expand Down Expand Up @@ -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 %');
Expand Down

0 comments on commit 4543e0e

Please sign in to comment.