How do I restrict an input to only accept numbers?
Easy way, use type="number" if it works for your use case:
<input type="number" ng-model="myText" name="inputName">
Another easy way: ng-pattern can also be used to define a regex that will limit what is allowed in the field. See also the "cookbook" page about forms.
Hackish? way, $watch the ng-model in your controller:
<input type="text" ng-model="myText" name="inputName">
Controller:
$scope.$watch('myText', function() {
// put numbersOnly() logic here, e.g.:
if ($scope.myText ... regex to look for ... ) {
// strip out the non-numbers
}
})
Best way, use a $parser in a directive. I'm not going to repeat the already good answer provided by @pkozlowski.opensource, so here's the link: https://stackoverflow.com/a/14425022/215945
All of the above solutions involve using ng-model, which make finding this
unnecessary.
Using ng-change will cause problems. See AngularJS - reset of $scope.value doesn't change value in template (random behavior)
Using ng-pattern
on the text field:
<input type="text" ng-model="myText" name="inputName" ng-pattern="onlyNumbers">
Then include this on your controller
$scope.onlyNumbers = /^\d+$/;
Here's my implementation of the $parser
solution that @Mark Rajcok recommends as the best method. It's essentially @pkozlowski.opensource's excellent $parser for text answer but rewritten to only allow numerics. All credit goes to him, this is just to save you the 5 minutes of reading that answer and then rewriting your own:
app.directive('numericOnly', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
var transformedInput = inputValue ? inputValue.replace(/[^\d.-]/g,'') : null;
if (transformedInput!=inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
And you'd use it like this:
<input type="text" name="number" ng-model="num_things" numeric-only>
Interestingly, spaces never reach the parser unless surrounded by an alphanumeric, so you'd have to .trim()
as needed. Also, this parser does NOT work on <input type="number">
. For some reason, non-numerics never make it to the parser where they'd be removed, but they do make it into the input control itself.