Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow only a number (digits and decimal point) to be typed in an input?

I am new to angularjs. I am wondering what is the way to allow only a valid number typed into a textbox. For example, user can type in "1.25", but cannot type in "1.a" or "1..". When user try to type in the next character which will make it an invalid number, he cannot type it in.

Thanks in advance.

like image 567
user1669811 Avatar asked Sep 26 '13 18:09

user1669811


People also ask

How do you restrict input box to allow only numbers and decimals?

To restrict input to allow only numbers and decimal point in a textbox with JavaScript, we can call the string match method to validate the input value. form. onsubmit = () => { return textarea. value.

How do I restrict only input numbers?

To limit an HTML input box to accept numeric input, use the <input type="number">. With this, you will get a numeric input field.

How do I allow only numbers in a text box?

The standard solution to restrict a user to enter only numeric values is to use <input> elements of type number. It has built-in validation to reject non-numerical values.

Does input type number allow decimal?

You can also use a decimal value: for example, a step of 0.3 will allow values such as 0.3, 0.6, 0.9 etc, but not 1 or 2. Now you don't get a validation error. Yay! Also note that if you only want to accept positive numbers, you'll want to add min=”0″.


2 Answers

I wrote a working CodePen example to demonstrate a great way of filtering numeric user input. The directive currently only allows positive integers, but the regex can easily be updated to support any desired numeric format.

My directive is easy to use:

<input type="text" ng-model="employee.age" valid-number /> 

The directive is very easy to understand:

var app = angular.module('myApp', []);  app.controller('MainCtrl', function($scope) { });  app.directive('validNumber', function() {   return {     require: '?ngModel',     link: function(scope, element, attrs, ngModelCtrl) {       if(!ngModelCtrl) {         return;        }        ngModelCtrl.$parsers.push(function(val) {         if (angular.isUndefined(val)) {             var val = '';         }         var clean = val.replace( /[^0-9]+/g, '');         if (val !== clean) {           ngModelCtrl.$setViewValue(clean);           ngModelCtrl.$render();         }         return clean;       });        element.bind('keypress', function(event) {         if(event.keyCode === 32) {           event.preventDefault();         }       });     }   }; }); 

I want to emphasize that keeping model references out of the directive is important.

I hope you find this helpful.

Big thanks to Sean Christe and Chris Grimes for introducing me to the ngModelController

like image 178
Adam Avatar answered Sep 20 '22 08:09

Adam


You could try this directive to stop any invalid characters from being entered into an input field. (Update: this relies on the directive having explicit knowledge of the model, which is not ideal for reusability, see below for a re-usable example)

app.directive('isNumber', function () {     return {         require: 'ngModel',         link: function (scope) {                 scope.$watch('wks.number', function(newValue,oldValue) {                 var arr = String(newValue).split("");                 if (arr.length === 0) return;                 if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;                 if (arr.length === 2 && newValue === '-.') return;                 if (isNaN(newValue)) {                     scope.wks.number = oldValue;                 }             });         }     }; }); 

It also accounts for these scenarios:

  1. Going from a non-empty valid string to an empty string
  2. Negative values
  3. Negative decimal values

I have created a jsFiddle here so you can see how it works.

UPDATE

Following Adam Thomas' feedback regarding not including model references directly inside a directive (which I also believe is the best approach) I have updated my jsFiddle to provide a method which does not rely on this.

The directive makes use of bi-directional binding of local scope to parent scope. The changes made to variables inside the directive will be reflected in the parent scope, and vice versa.

HTML:

<form ng-app="myapp" name="myform" novalidate>      <div ng-controller="Ctrl">         <number-only-input input-value="wks.number" input-name="wks.name"/>     </div> </form> 

Angular code:

var app = angular.module('myapp', []);  app.controller('Ctrl', function($scope) {     $scope.wks =  {number: 1, name: 'testing'}; }); app.directive('numberOnlyInput', function () {     return {         restrict: 'EA',         template: '<input name="{{inputName}}" ng-model="inputValue" />',         scope: {             inputValue: '=',             inputName: '='         },         link: function (scope) {             scope.$watch('inputValue', function(newValue,oldValue) {                 var arr = String(newValue).split("");                 if (arr.length === 0) return;                 if (arr.length === 1 && (arr[0] == '-' || arr[0] === '.' )) return;                 if (arr.length === 2 && newValue === '-.') return;                 if (isNaN(newValue)) {                     scope.inputValue = oldValue;                 }             });         }     }; }); 
like image 28
GordyD Avatar answered Sep 19 '22 08:09

GordyD