AngularJS handle formatted number input
Problem Description:
How can I allow values like “1,200” in a number field in angular?
My users do a lot of copy/pasting of values, and they like the number formatting throughout. The problem is that the default setup for angular input[type=number]
will throw an error when one of these formatted values is pasted back in.
Here is a plunk forked from this page:
http://plnkr.co/edit/rcTrGHb9asRu4tIKPou8?p=preview
Notice that when you copy a formatted value (like the 1,200 it starts with) and paste it back into the input box it breaks.
How can I best handle this? It seems like this is something that would have been handled before, but I am having a hard time tracking anything down. I do not need anything robust. I am fine with modifying the input text to remove formatting, and I can assume a standard en-us format.
Solution – 1
You can have a custom directive on a regular input(type=text) field to format the data as a number always
Your directive would look something like
angular.module('myApp').directive('myDirective', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelController) {
ngModelController.$parsers.push(function(data) {
//convert data from view format to model format
return data; //converted
});
ngModelController.$formatters.push(function(data) {
//convert data from model format to view format
return data; //converted
});
}
}
});
Solution – 2
Here is the solution I went with:
app.directive('appType', function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
// Custom number validation logic.
if (attrs.appType === 'number') {
return ctrl.$parsers.push(function (value) {
var v = value.replace(/,/g,''),
valid = v == null || isFinite(v);
ctrl.$setValidity('number', valid);
return valid && v != null ? Number(v) : undefined;
});
}
}
};
});
This is thanks to the link I found using all your feedback: http://blakeembrey.com/articles/angular-js-number-validation-bug/
Updated plunker: http://plnkr.co/edit/rcTrGHb9asRu4tIKPou8?p=preview