-
Notifications
You must be signed in to change notification settings - Fork 27.4k
input type="number" does not allow numbers with leading decimals on some browsers #5680
Comments
add check for leading decimal. Some browsers swallow leading decimals on input type="number". fixes angular#5680
Instead of modifying the angular source, I'm using a custom validator that I attach to number fields to work around this issue. This appears to consistently mark the field as invalid until a valid number is entered, cross-browser. This also seems to address the issue in IE9 where leading decimals are removed. module.directive('tolerantNumber', function() {
return {
require: 'ngModel',
priority: 1,
link: function(scope, element, attrs, ctrl) {
var ngNumberParser = ctrl.$parsers.splice(0, 1)[0];
ctrl.$parsers.push(function(value) {
if (value === '.') {
ctrl.$setValidity('number', false);
return undefined;
}
return ngNumberParser(value);
});
}
};
}); Use: <input type="number" tolerant-number> I'm not sold on the directive name though. Oh well. |
After closer inspection, the above code doesn't solve additional problems I'm seeing in IE10+. I just ended up contributing my own number validator directive and switched to a text input. This appears to be the only obvious way to properly validate numbers cross-browser. |
Ray, can you reference the commit with your number validator? I'd like to take a look at it. |
The commit is in a private project, but I'll post it below. I wrote a few unit tests that seem to verify it, and some brief cross-browser testing looks good: module.directive('numberValidator', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ctrl) {
ctrl.$parsers.push(function(value) {
if (ctrl.$isEmpty(value)) {
ctrl.$setValidity('number', true);
return null;
}
// http://stackoverflow.com/a/1830844/486979
else if (!isNaN(parseFloat(value)) && isFinite(value)) {
ctrl.$setValidity('number', true);
return value;
}
else {
ctrl.$setValidity('number', false);
}
});
}
};
}); |
Here are my tests: describe('number validator', function() {
var $scope, $compile, el;
beforeEach(function() {
module('module');
module('test.templates');
inject(function(_$rootScope_, _$translate_, _$compile_) {
$scope = _$rootScope_.$new();
$compile = _$compile_;
$scope.test = {num: null};
el = '<input type="text" ng-model="test.num" number-validator>';
el = $compile(el)($scope);
$scope.$digest();
});
});
it('declares valid numbers to be valid', function() {
el.val('1').trigger('input');
expect(el.hasClass('ng-valid')).toBe(true);
el.val('.1').trigger('input');
expect(el.hasClass('ng-valid')).toBe(true);
el.val('1.0').trigger('input');
expect(el.hasClass('ng-valid')).toBe(true);
el.val('-1.0').trigger('input');
expect(el.hasClass('ng-valid')).toBe(true);
});
it('declares invalid numbers to be invalid', function() {
el.val('-').trigger('input');
expect(el.hasClass('ng-invalid')).toBe(true);
el.val('.').trigger('input');
expect(el.hasClass('ng-invalid')).toBe(true);
el.val('abc').trigger('input');
expect(el.hasClass('ng-invalid')).toBe(true);
});
}); |
+1 |
I had a similar problem and update the ...
.directive('stringToNumber', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var decimalPrecision = attrs.decimalPrecision || 0;
ngModel.$parsers.push(function(value) {
return value;
});
function updateElementValue() {
var viewValue = parseFloat(ngModel.$viewValue || 0);
element.val(decimalPrecision !== null ? viewValue.toFixed(decimalPrecision) : viewValue);
}
ngModel.$formatters.push(function(value) {
return parseFloat(value, 10);
});
ngModel.$viewChangeListeners.push(updateElementValue);
ngModel.$render = function() {
updateElementValue();
}
}
};
}); <input type="number"
string-to-number
decimal-precision="2"
ng-model="model.value"
step="0.10" /> |
Fiddle: http://jsfiddle.net/NEhG9/3/
The fiddle uses 1.2.1, however, I have reproduced it using 1.2.6
It affects IE9 and Firefox
It does not affect Chrome or Safari
I haven't tested IE8- or IE10+
The desired behavior is to allow the leading decimal to be entered, but do not update the model or set the input element's validation to valid until a valid number is entered.
Users can enter numbers with leading decimals by entering the number first, then scrolling back and entering the decimal.
The text was updated successfully, but these errors were encountered: