wake-up-neo.com

Wie beschränke ich eine Eingabe darauf, nur Zahlen zu akzeptieren?

Ich verwende ngChange in AngularJS, um eine benutzerdefinierte Funktion auszulösen, die alle Buchstaben entfernt, die der Benutzer der Eingabe hinzufügt.

<input type="text" name="inputName" data-ng-change="numbersOnly()"/>

Das Problem ist, dass ich auf die Eingabe zielen muss, die numbersOnly() ausgelöst hat, damit ich die eingegebenen Buchstaben entfernen kann. Ich habe lange und intensiv bei Google nachgesehen und konnte diesbezüglich nichts finden.

Was kann ich tun?

80
Chris Bier

Einfacher Weg , verwenden Sie Typ = "Zahl" wenn es für Ihren Anwendungsfall funktioniert:

<input type="number" ng-model="myText" name="inputName">

Ein weiterer einfacher Weg: ng-pattern kann auch verwendet werden, um einen regulären Ausdruck zu definieren, der die im Feld zulässigen Werte einschränkt. Siehe auch die Seite "Kochbuch" über Formulare .

Hackish? So , $ schau dir das ng-Modell in deinem Controller an:

<input type="text"  ng-model="myText" name="inputName">

Regler:

$scope.$watch('myText', function() {
   // put numbersOnly() logic here, e.g.:
   if ($scope.myText  ... regex to look for ... ) {
      // strip out the non-numbers
   }
})

Verwenden Sie am besten einen $ -Parser in einer Direktive. Ich werde die bereits gute Antwort von @ pkozlowski.opensource nicht wiederholen, daher hier der Link: https://stackoverflow.com/a/14425022/215945

Alle oben genannten Lösungen beinhalten die Verwendung von ng-model, wodurch das Auffinden von this unnötig wird.

Die Verwendung von ng-change führt zu Problemen. Siehe AngularJS - Zurücksetzen von $ scope.value ändert den Wert in der Vorlage nicht (zufälliges Verhalten)

96
Mark Rajcok

Mit ng-pattern im Textfeld:

<input type="text"  ng-model="myText" name="inputName" ng-pattern="onlyNumbers">

Fügen Sie dies dann in Ihren Controller ein

$scope.onlyNumbers = /^\d+$/;
65
MarkJ

Keine der vorgeschlagenen Lösungen funktionierte gut für mich und nach ein paar Stunden fand ich endlich den Weg.

Dies ist die angular Direktive:

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();
                }
            });
        }
    }
});

Und die Eingabe würde so aussehen:

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

Der reguläre Ausdruck wertet die gedrückte Taste aus, nicht den Wert.

Es funktioniert auch perfekt mit Eingaben type="number" weil verhindert, dass der Wert geändert wird, so dass der Schlüssel nie angezeigt wird und sich nicht mit dem Modell verwechselt.

18
ragnar

Hier ist meine Implementierung der $parser - Lösung, die @ Mark Rajcok als beste Methode empfiehlt. Es ist im Wesentlichen @ pkozlowski.opensource's ausgezeichneter $ Parser für Textantworten , aber umgeschrieben, um nur numerische Werte zuzulassen. Ihm gebührt alles, nur um Ihnen die 5 Minuten zu ersparen, in denen Sie diese Antwort gelesen und dann Ihre eigene Antwort neu geschrieben haben:

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;
            });
        }
    };
});

Und du würdest es so benutzen:

<input type="text" name="number" ng-model="num_things" numeric-only>

Interessanterweise gelangen Leerzeichen nur dann zum Parser, wenn sie von einem alphanumerischen Zeichen umgeben sind. Sie müssten also nach Bedarf .trim(). Außerdem funktioniert dieser Parser [~ # ~] nicht [~ # ~] mit <input type="number">. Aus irgendeinem Grund schaffen es Nicht-Numerische niemals in den Parser, in dem sie entfernt werden würden, aber sie schaffen es in das Eingabesteuerelement selbst.

16
Mordred

Hierfür gibt es verschiedene Möglichkeiten.

Du könntest benutzen type="number":

<input type="number" />

Alternativ habe ich eine wiederverwendbare Direktive erstellt, die einen regulären Ausdruck verwendet.

Html

<div ng-app="myawesomeapp">
    test: <input restrict-input="^[0-9-]*$" maxlength="20" type="text" class="test" />
</div>

Javascript

;(function(){
    var app = angular.module('myawesomeapp',[])
    .directive('restrictInput', [function(){

        return {
            restrict: 'A',
            link: function (scope, element, attrs) {
                var ele = element[0];
                var regex = RegExp(attrs.restrictInput);
                var value = ele.value;

                ele.addEventListener('keyup',function(e){
                    if (regex.test(ele.value)){
                        value = ele.value;
                    }else{
                        ele.value = value;
                    }
                });
            }
        };
    }]);    
}());
4
Peter Rasmussen

Hier ist ein Plunker Umgang mit jeder Situation über Satz nicht behandeln.
Indem Sie die Pipeline $ formaters und $ parsers verwenden und type = "number" vermeiden

Und hier die Erklärung der Probleme/Lösungen (auch im Plunker verfügbar):

/*
 *
 * Limit input text for floating numbers.
 * It does not display characters and can limit the Float value to X numbers of integers and X numbers of decimals.
 * min and max attributes can be added. They can be Integers as well as Floating values.
 *
 * value needed    |    directive
 * ------------------------------------
 * 55              |    max-integer="2"
 * 55.55           |    max-integer="4" decimal="2" (decimals are substracted from total length. Same logic as database NUMBER type)
 *
 *
 * Input type="number" (HTML5)
 *
 * Browser compatibility for input type="number" :
 * Chrome : - if first letter is a String : allows everything
 *          - if first letter is a Integer : allows [0-9] and "." and "e" (exponential)
 * Firefox : allows everything
 * Internet Explorer : allows everything
 *
 * Why you should not use input type="number" :
 * When using input type="number" the $parser pipeline of ngModel controller won't be able to access NaN values.
 * For example : viewValue = '1e'  -> $parsers parameter value = "".
 * This is because undefined values are not allowes by default (which can be changed, but better not do it)
 * This makes it impossible to modify the view and model value; to get the view value, pop last character, apply to the view and return to the model.
 *
 * About the ngModel controller pipelines :
 * view value -> $parsers -> model value
 * model value -> $formatters -> view value
 *
 * About the $parsers pipeline :
 * It is an array of functions executed in ascending order.
 * When used with input type="number" :
 * This array has 2 default functions, one of them transforms the datatype of the value from String to Number.
 * To be able to change the value easier (substring), it is better to have access to a String rather than a Number.
 * To access a String, the custom function added to the $parsers pipeline should be unshifted rather than pushed.
 * Unshift gives the closest access to the view.
 *
 * About the $formatters pipeline :
 * It is executed in descending order
 * When used with input type="number"
 * Default function transforms the value datatype from Number to String.
 * To access a String, Push to this pipeline. (Push brings the function closest to the view value)
 *
 * The flow :
 * When changing ngModel where the directive stands : (In this case only the view has to be changed. $parsers returns the changed model)
 *     -When the value do not has to be modified :
 *     $parsers -> $render();
 *     -When the value has to be modified :
 *     $parsers(view value) --(does view needs to be changed?) -> $render();
 *       |                                  |
 *       |                     $setViewValue(changedViewValue)
 *       |                                  |
 *       --<-------<---------<--------<------
 *
 * When changing ngModel where the directive does not stand :
 *     - When the value does not has to be modified :
 *       -$formatters(model value)-->-- view value
 *     -When the value has to be changed
 *       -$formatters(model vale)-->--(does the value has to be modified) -- (when loop $parsers loop is finished, return modified value)-->view value
 *                                              |
 *                                  $setViewValue(notChangedValue) giving back the non changed value allows the $parsers handle the 'bad' value
 *                                               |                  and avoids it to think the value did not changed
 *                Changed the model <----(the above $parsers loop occurs)
 *
 */
2
gr3g

Alle oben genannten Lösungen sind ziemlich groß, ich wollte meine 2 Cent darauf geben.

Ich überprüfe nur, ob der eingegebene Wert eine Zahl ist oder nicht, und überprüfe, ob er nicht leer ist, das ist alles.

Hier ist der HTML-Code:

<input type="text" ng-keypress="CheckNumber()"/>

Hier ist der JS:

$scope.CheckKey = function () {
    if (isNaN(event.key) || event.key === ' ' || event.key === '') {
        event.returnValue = '';
    }
};

Es ist ganz einfach.

Ich glaube, das funktioniert nicht mit Paste tho, nur damit es bekannt ist.

Zum Einfügen müssten Sie das onChange -Ereignis verwenden und die gesamte Zeichenfolge analysieren, ein ganz anderes Biest das tamme. Dies ist spezifisch für die Eingabe.

PDATE for Paste: füge einfach diese JS-Funktion hinzu:

$scope.CheckPaste = function () {
    var paste = event.clipboardData.getData('text');

    if (isNaN(paste)) {
        event.preventDefault();
        return false;
    }
};

Und die HTML-Eingabe fügt den Trigger hinzu:

<input type="text" ng-paste="CheckPaste()"/>

Ich hoffe das hilft o /

2
Zorkind

DEZIMAL

directive('decimal', function() {
                return {
                    require: 'ngModel',
                    restrict: 'A',
                    link: function(scope, element, attr, ctrl) {
                        function inputValue(val) {
                            if (val) {
                                var digits = val.replace(/[^0-9.]/g, '');

                                if (digits.split('.').length > 2) {
                                    digits = digits.substring(0, digits.length - 1);
                                }

                                if (digits !== val) {
                                    ctrl.$setViewValue(digits);
                                    ctrl.$render();
                                }
                                return parseFloat(digits);
                            }
                            return "";
                        }
                        ctrl.$parsers.Push(inputValue);
                    }
                };
            });

Ziffern

directive('entero', function() {
            return {
                require: 'ngModel',
                restrict: 'A',
                link: function(scope, element, attr, ctrl) {
                    function inputValue(val) {
                        if (val) {
                            var value = val + ''; //convert to string
                            var digits = value.replace(/[^0-9]/g, '');

                            if (digits !== value) {
                                ctrl.$setViewValue(digits);
                                ctrl.$render();
                            }
                            return parseInt(digits);
                        }
                        return "";
                    }
                    ctrl.$parsers.Push(inputValue);
                }
            };
        });

Winkelanweisungen für die Validierung von Zahlen

1
Angeldev

Grundlegende und saubere HTML-Art und Weise

<input type="number" />
0
Amr Ibrahim

Ich weiß, dass dies alt ist, aber ich habe zu diesem Zweck eine Richtlinie erstellt, falls jemand nach einer einfachen Lösung sucht. Sehr einfach zu bedienen.

Sie können es überprüfen hier .

0
cohenadair
   <input type="text" name="profileChildCount" id="profileChildCount" ng-model="profile.ChildCount" numeric-only maxlength="1" />

sie können nur numerische Attribute verwenden.

0
tahsin ilhan

Versuche dies,

<input ng-keypress="validation($event)">

 function validation(event) {
    var theEvent = event || window.event;
    var key = theEvent.keyCode || theEvent.which;
    key = String.fromCharCode(key);
    var regex = /[0-9]|\./;
    if (!regex.test(key)) {
        theEvent.returnValue = false;
        if (theEvent.preventDefault) theEvent.preventDefault();
    }

}
0
Joee

Hier ist eine ziemlich gute Lösung, um nur die Eingabe einer Zahl für das input zuzulassen:

<input type="text" ng-model="myText" name="inputName" onkeypress='return event.charCode >= 48 && event.charCode <= 57'/>
0
Raniys

LÖSUNG: Ich schreibe eine Anweisung für alle Eingaben, Zahlen, Texte oder andere in der App, damit Sie einen Wert eingeben und das Ereignis ändern können. Machen Sie für 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
Seba Arce

vielleicht möchten Sie auch die 0 am Anfang der Eingabe entfernen ... Ich füge oben einfach einen if-Block zu Mordreds Antwort hinzu, da ich noch keinen Kommentar abgeben kann ...

  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();
              }
              //clear beginning 0
              if(transformedInput == 0){
                modelCtrl.$setViewValue(null);
                modelCtrl.$render();
              }
              return transformedInput;
          });
      }
    };
  })
0
sireken