12

I want to set the html input[number] <input type="number" /> to allow only integer input (not float).

Basically, the html input[number] allow '.' to be entered for float input and I don't want that.

Is there a quick way to accomplish it in AngularJS?

Cheetah Felidae
  • 999
  • 2
  • 7
  • 14
  • 2
    Possible duplicate of [angularjs: allows only numbers to be typed into a text box](http://stackoverflow.com/questions/16091218/angularjs-allows-only-numbers-to-be-typed-into-a-text-box) – Mudassir Hasan Dec 01 '15 at 05:36
  • 2
    Note that the question is asking about _integers_, not _numbers_. – Adam Zerner Dec 01 '15 at 05:41

7 Answers7

21

Here is how this can be achieved.

  1. With input type - 'text'

    Directive:

    app.directive('onlyNumbers', function () {
        return  {
            restrict: 'A',
            link: function (scope, elm, attrs, ctrl) {
                elm.on('keydown', function (event) {
                    if(event.shiftKey){event.preventDefault(); return false;}
                    //console.log(event.which);
                    if ([8, 13, 27, 37, 38, 39, 40].indexOf(event.which) > -1) {
                        // backspace, enter, escape, arrows
                        return true;
                    } else if (event.which >= 48 && event.which <= 57) {
                        // numbers 0 to 9
                        return true;
                    } else if (event.which >= 96 && event.which <= 105) {
                        // numpad number
                        return true;
                    } 
                    // else if ([110, 190].indexOf(event.which) > -1) {
                    //     // dot and numpad dot
                    //     return true;
                    // }
                    else {
                        event.preventDefault();
                        return false;
                    }
                });
            }
        }
    });
    

    HTML:

    <input type="text" only-numbers>
    
  2. With input type - 'number'

    Directive:

    app.directive('noFloat', function () {
    return  {
        restrict: 'A',
        link: function (scope, elm, attrs, ctrl) {
            elm.on('keydown', function (event) {
              if ([110, 190].indexOf(event.which) > -1) {
                    // dot and numpad dot
                    event.preventDefault();
                    return false;
                }
                else{
                  return true;
                }
            });
        }
    }
    });
    

    HTML: <input type="number" step="1" no-float>

Check out the Plunker

Rohan Pawar
  • 1,875
  • 22
  • 40
Shyamal Parikh
  • 2,988
  • 4
  • 37
  • 78
3

Use pattern property:

<input type="number" ng-model="price" name="price_field" ng-pattern="/^[0-9]{1,7}$/" required>

please see the demo : https://jsfiddle.net/JBalu/vfbgrd5n/

may help.

Jinna Balu
  • 6,747
  • 38
  • 47
2

Please find the fiddle http://jsfiddle.net/8a4sg0mo/

angular.module('myApp', []).directive('numbersOnly', function(){
   return {
     require: 'ngModel',
     link: function(scope, element, attrs, modelCtrl) {
       modelCtrl.$parsers.push(function (inputValue) {

       if (inputValue == undefined) return '' 
       var transformedInput = inputValue.replace(/[^0-9]/g, ''); 
       if (transformedInput!=inputValue) {
          modelCtrl.$setViewValue(transformedInput);
          modelCtrl.$render();
       }         

       return transformedInput;         
   });
 }
   };
});

function MyCtrl($scope) {
    $scope.number = ''
}

It will allow only numbers to be entered, purely done using angular js.

AurA
  • 12,135
  • 7
  • 46
  • 63
  • Yeah the code is work. Unfortunately, if I use it inside my directive, I'll get an error "inputValue.replace is not a function". Did I miss something? – Cheetah Felidae Dec 01 '15 at 06:23
1

I have looked for this many times, I had used directives in previous projects, but have finally founded a way that angular js provides by itself and hence can get rid of directives. Take a look at this code given at this link angularJs

The code shown there is as follows :

<script>
  angular.module('numberExample', [])
    .controller('ExampleController', ['$scope', function($scope) {
      $scope.example = {
        value: 12
      };
    }]);
</script>
<form name="myForm" ng-controller="ExampleController">
  <label>Number:
    <input type="number" name="input" ng-model="example.value"
           min="0" max="99" required>
 </label>
  <div role="alert">
    <span class="error" ng-show="myForm.input.$error.required">
      Required!</span>
    <span class="error" ng-show="myForm.input.$error.number">
      Not valid number!</span>
  </div>
  <tt>value = {{example.value}}</tt><br/>
  <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br/>
  <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br/>
  <tt>myForm.$valid = {{myForm.$valid}}</tt><br/>
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
 </form>
Yagnesh Khamar
  • 184
  • 3
  • 8
1

(function () {
    angular
    .module('urModule').directive('numbersOnly', numbersOnly);
    function numbersOnly() {
        return {
            require: 'ngModel',
            link: function (scope, element, attr, ngModelCtrl) {
                function fromUser(text) {
                    if (text) {
                        var transformedInput = text.replace(/[^0-9]/g, '');

                        if (transformedInput !== text) {
                            ngModelCtrl.$setViewValue(transformedInput);
                            ngModelCtrl.$render();
                        }
                        return transformedInput;
                    }
                    return undefined;
                }
                ngModelCtrl.$parsers.push(fromUser);
            }
        };
    }
})();
0

Full working Sample:Custom Directive The below works just fine

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<body ng-app="myApp" ng-controller="AppCtrl">

  <input type="text" allow-numbers-only />

  <script>
    var app = angular.module("myApp", []);

    app.controller("AppCtrl", function($scope) {
      $scope.title = "App"
    })



    app.directive("allowNumbersOnly", function() {
      return {
        restrict: "A",
        link: function(scope, element, attrs) {
          element.bind("keydown", function(event) {
            if (event.keyCode == 8) {
              return false;
            } else if (!(event.keyCode > 47 && event.keyCode < 58) || event.shiftKey) {
              event.preventDefault();
              return false;
            }
          });



        }
      }
    });
  </script>

</body>

</html>
-3

input[type=number] by definition only accepts integers as input. Try it out yourself. Try typing in letters and it won't allow you.

There's no need for JavaScript as it's already built in. Did you perhaps mean input[type=text]?

You can accomplish that via angular directives. It would look something like this (not sure about my syntax though)

app.directive('onlyNumbers', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind("keydown", function(event) {
                if ((event.keyCode > 47 && event.keyCode < 58) && !event.shiftKey) {
                    event.preventDefault();
                    return false;
                }
            });
        }
    });

The syntax might have a few errors, but I will break down the basic formula.

Since we are working with an input element, it makes sense that we use an attribute directive. We can do this, by setting the restrict property to A.

Since we will be listening for keypress events, we should use the link function. We want to listen for the keydown event, to detect when a key is starting to be pressed.

To find if the user typed a number, we will use keyCodes, for which the number keys are 48 through 57 representing 0 through 9 respectively. However, we didn't account for special characters, which require hitting the number keys. So we make sure the shift key isn't being pressed either.

Then we can add this directive as an attribute on our input element.

<input type="text" only-numbers />
Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87