Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issue #305 - error on android with chrome #331

Closed
wants to merge 6 commits into from
61 changes: 31 additions & 30 deletions src/global/money/money.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,41 +171,42 @@ describe('ui-money-mask', function() {
$rootScope.$digest();
expect(model.$viewValue).toBe(test.viewValue);
});
}));

it('should return null if $isEmpty value', function() {
var input = TestUtil.compile('<input ng-model="model" ui-money-mask>', {});
var model = input.controller('ngModel');
var tests = [
{modelValue: '', viewValue: ''},
{modelValue: null, viewValue: null},
{modelValue: NaN, viewValue: NaN}
];

tests.forEach(function(test) {
$rootScope.model = test.modelValue;
$rootScope.$digest();
expect(model.$viewValue).toBe(null);
});
});
it('should return null if $isEmpty value', angular.mock.inject(function($rootScope) {
var input = TestUtil.compile('<input ng-model="model" ui-money-mask>', {});
var model = input.controller('ngModel');
var tests = [
{modelValue: '', viewValue: ''},
{modelValue: null, viewValue: null},
{modelValue: NaN, viewValue: NaN}
];

it('should ignore non digits', function() {
var input = TestUtil.compile('<input ng-model="model" ui-money-mask>', {});
var model = input.controller('ngModel');

var tests = [
{value: '@', viewValue: '', modelValue: ''},
{},
{value: null, viewValue: null, modelValue: null},
];

tests.forEach(function(test) {
input.val(test.value).triggerHandler('input');
expect(model.$viewValue).toBe(test.viewValue);
expect(model.$modelValue).toBe(test.modelValue);
});
tests.forEach(function(test) {
$rootScope.model = test.modelValue;
$rootScope.$digest();
expect(model.$viewValue).toBe(null);
});
}));

it('should ignore non digits', function() {
var input = TestUtil.compile('<input ng-model="model" ui-money-mask>', {});
var model = input.controller('ngModel');

var tests = [
{value: '@', viewValue: '', modelValue: ''},
{},
{value: null, viewValue: null, modelValue: null},
];

tests.forEach(function(test) {
input.val(test.value).triggerHandler('input');
expect(model.$viewValue).toBe(test.viewValue);
expect(model.$modelValue).toBe(test.modelValue);
});
});


it('should convert invalid values to zero', function() {
var input = TestUtil.compile('<input ng-model="model" ui-money-mask>', {});
var model = input.controller('ngModel');
Expand Down
82 changes: 69 additions & 13 deletions src/helpers/mask-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@

module.exports = function maskFactory(maskDefinition) {
return function MaskDirective() {

var caret = {
set : function caretSet(element, currentPos, pos) {

if (element[0].setSelectionRange) {
element[0].focus();
window.setTimeout(function() {
if(currentPos!==element[0].selectionStart){
currentPos=element[0].selectionStart;
}
pos=currentPos+pos;
element[0].setSelectionRange(pos, pos);
}, 0);


} else if (element[0].createTextRange) {
pos=currentPos+pos;
var range = element[0].createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
},
get : function caretGet(element) {
var iCaretPos = 0;
if (document.selection) {
element[0].focus();
var oSel = document.selection.createRange();
oSel.moveStart('character', -element[0].value.length);
iCaretPos = oSel.text.length;
} else if (
element[0].selectionStart || element[0].selectionStart === '0'
) {
iCaretPos = element[0].selectionStart;
}
return iCaretPos;
}
};

return {
restrict: 'A',
require: 'ngModel',
Expand All @@ -11,7 +51,7 @@ module.exports = function maskFactory(maskDefinition) {
return value;
}

var cleanValue = maskDefinition.clearValue(value.toString());
var cleanValue = maskDefinition.clearValue(value);
return maskDefinition.format(cleanValue);
});

Expand All @@ -20,20 +60,36 @@ module.exports = function maskFactory(maskDefinition) {
return value;
}

var cleanValue = maskDefinition.clearValue(value.toString());
var formattedValue = maskDefinition.format(cleanValue);

if (ctrl.$viewValue !== formattedValue) {
ctrl.$setViewValue(formattedValue);
ctrl.$render();
}
var cleanValue = maskDefinition.clearValue(value);
var formattedValue = maskDefinition.format(cleanValue);

if (angular.isUndefined(maskDefinition.getModelValue)) {
return cleanValue;
}
var currentCaretPosition = caret.get(element),
lengthBefore = ctrl.$viewValue.length,
lengthAfter = 0;

if (ctrl.$viewValue !== formattedValue) {
ctrl.$setViewValue(formattedValue);
ctrl.$render();

lengthAfter = ctrl.$viewValue.length;
}

var caretFormatDiffer = (lengthAfter - lengthBefore) < 0
? 0
: lengthAfter - lengthBefore;

caret.set(element, currentCaretPosition, caretFormatDiffer);

if (angular.isUndefined(maskDefinition.getModelValue)) {
return cleanValue;
}

var actualModelType = typeof ctrl.$modelValue;
return maskDefinition.getModelValue(formattedValue, actualModelType);


var actualModelType = typeof ctrl.$modelValue;
return maskDefinition.getModelValue(formattedValue, actualModelType);

});

angular.forEach(maskDefinition.validations, function(validatorFn, validationErrorKey) {
Expand All @@ -44,4 +100,4 @@ module.exports = function maskFactory(maskDefinition) {
}
};
};
};
};