How do I restrict an input to only accept numbers?

前端 未结 17 1222
感情败类
感情败类 2020-12-07 09:28

I am using ngChange in AngularJS to trigger a custom function that will remove any letters the user adds to the input.



        
相关标签:
17条回答
  • 2020-12-07 10:00

    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.

    0 讨论(0)
  • 2020-12-07 10:00
    <input type="text" ng-model="employee.age" valid-input input-pattern="[^0-9]+" placeholder="Enter an age" />
    
    <script>
    var app = angular.module('app', []);
    
    app.controller('dataCtrl', function($scope) {
    });
    
    app.directive('validInput', function() {
      return {
        require: '?ngModel',
        scope: {
          "inputPattern": '@'
        },
        link: function(scope, element, attrs, ngModelCtrl) {
    
          var regexp = null;
    
          if (scope.inputPattern !== undefined) {
            regexp = new RegExp(scope.inputPattern, "g");
          }
    
          if(!ngModelCtrl) {
            return;
          }
    
          ngModelCtrl.$parsers.push(function(val) {
            if (regexp) {
              var clean = val.replace(regexp, '');
              if (val !== clean) {
                ngModelCtrl.$setViewValue(clean);
                ngModelCtrl.$render();
              }
              return clean;
            }
            else {
              return val;
            }
    
          });
    
          element.bind('keypress', function(event) {
            if(event.keyCode === 32) {
              event.preventDefault();
            }
          });
        }
    }}); </script>
    
    0 讨论(0)
  • 2020-12-07 10:01

    SOLUTION: I make a directive for all inputs, number, text, or any, in the app, so you can input a value and change the event. Make for angular 6

     import { Directive, ElementRef, HostListener, Input } from '@angular/core';
    
     @Directive({
    // tslint:disable-next-line:directive-selector
    selector: 'input[inputType]'
    })
      export class InputTypeDirective {
     constructor(private _el: ElementRef) {}
    
     @Input() inputType: string;
     // tipos: number, letter, cuit, tel
    
    @HostListener('input', ['$event']) onInputChange(event) {
    if (!event.data) {
      return;
    }
    
    switch (this.inputType) {
      case 'number': {
        const initalValue = this._el.nativeElement.value;
        this._el.nativeElement.value = initalValue.replace(/[^0-9]*/g, '');
        if (initalValue !== this._el.nativeElement.value) {
          event.stopPropagation();
        }
         break;
              }
           case 'text': {
            const result = event.data.match(/[^a-zA-Z Ññ]*/g);
            if (result[0] !== '') {
               const initalValue = this._el.nativeElement.value;
               this._el.nativeElement.value = initalValue.replace(
              /[^a-zA-Z Ññ]*/g,
               ''
             );
               event.stopPropagation();
            }
            break;
        }
            case 'tel':
              case 'cuit': {
             const initalValue = this._el.nativeElement.value;
          this._el.nativeElement.value = initalValue.replace(/[^0-9-]*/g, '');
           if (initalValue !== this._el.nativeElement.value) {
             event.stopPropagation();
           }
         }
       }
      }
       }
    

    HTML

         <input matInput inputType="number" [formControlName]="field.name" [maxlength]="field.length" [placeholder]="field.label | translate"  type="text" class="filter-input">
    
    0 讨论(0)
  • 2020-12-07 10:02

    None of the solutions proposed worked fine for me, and after a couple of hours I finally found the way.

    This is the angular directive:

    angular.module('app').directive('restrictTo', function() {
        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var re = RegExp(attrs.restrictTo);
                var exclude = /Backspace|Enter|Tab|Delete|Del|ArrowUp|Up|ArrowDown|Down|ArrowLeft|Left|ArrowRight|Right/;
    
                element[0].addEventListener('keydown', function(event) {
                    if (!exclude.test(event.key) && !re.test(event.key)) {
                        event.preventDefault();
                    }
                });
            }
        }
    });
    

    And the input would look like:

    <input type="number" min="0" name="inputName" ng-model="myModel" restrict-to="[0-9]">
    

    The regular expression evaluates the pressed key, not the value.

    It also works perfectly with inputs type="number" because prevents from changing its value, so the key is never displayed and it does not mess with the model.

    0 讨论(0)
  • 2020-12-07 10:02

    Basic HTML

    <input type="number" />
    

    Basic bootstrap

    <input class="form-control" type="number" value="42" id="my-id">
    
    0 讨论(0)
  • 2020-12-07 10:03

    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+$/;
    
    0 讨论(0)
提交回复
热议问题