Wie kann man nur eine Zahl (Ziffern und Dezimalpunkt) in eine Eingabe eingeben?

Ich bin neu bei angularjs. Ich frage mich, wie man nur eine gültige Zahl in eine Textbox eingeben kann. Zum Beispiel kann der Benutzer “1.25” eingeben, aber nicht “1.a” oder “1 ..” eingeben. Wenn der Benutzer versucht, das nächste Zeichen einzugeben, das eine ungültige Nummer ergibt, kann er es nicht eingeben.

Danke im Voraus.

Sie könnten diese Direktive versuchen, zu verhindern, dass ungültige Zeichen in ein Eingabefeld eingegeben werden. ( Update : Dies beruht auf expliziter Kenntnis des Modells über die Richtlinie, die für die Wiederverwendbarkeit nicht ideal ist, siehe unten für ein wiederverwendbares Beispiel)

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

Es berücksichtigt auch diese Szenarien:

  1. Von einer nicht leeren gültigen Zeichenfolge zu einer leeren Zeichenfolge wechseln
  2. Negative Werte
  3. Negative Dezimalwerte

Ich habe hier ein jsFiddle erstellt , damit Sie sehen können, wie es funktioniert.

AKTUALISIEREN

Nach dem Feedback von Adam Thomas, dass Modellreferenzen nicht direkt in einer Direktive enthalten sind (was ich auch für den besten Ansatz halte ), habe ich meine jsFiddle aktualisiert, um eine Methode bereitzustellen, die nicht darauf angewiesen ist.

Die Direktive verwendet die bidirektionale Bindung des lokalen Bereichs an den übergeordneten Bereich. Die Änderungen an Variablen innerhalb der Direktive werden im übergeordneten Bereich widergespiegelt und umgekehrt.

HTML:

 

angularcode:

 var app = angular.module('myapp', []); app.controller('Ctrl', function($scope) { $scope.wks = {number: 1, name: 'testing'}; }); app.directive('numberOnlyInput', function () { return { restrict: 'EA', template: '', 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; } }); } }; }); 

Ich habe ein funktionierendes CodePen-Beispiel geschrieben , um eine gute Möglichkeit zum Filtern von numerischen Benutzereingaben zu demonstrieren. Die Direktive erlaubt derzeit nur positive ganze Zahlen, aber die Regex kann leicht aktualisiert werden, um jedes gewünschte numerische Format zu unterstützen.

Meine statement ist einfach zu verwenden:

  

Die Richtlinie ist sehr einfach zu verstehen:

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

Ich möchte betonen, dass es wichtig ist, Modellreferenzen außerhalb der Richtlinie zu halten.

Ich hoffe, Sie finden das hilfreich.

Vielen Dank an Sean Christe und Chris Grimes für die Einführung in den ngModelController

Zuallererst Vielen Dank an Adam thomas Ich habe die gleiche Adamslogik dafür mit einer kleinen Modifikation verwendet, um die Dezimalwerte zu akzeptieren.

Hinweis: Dies ermöglicht Ziffern mit nur 2 Dezimalwerten

Hier ist mein Arbeitsbeispiel

HTML

  

Javascript

  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, ''); var decimalCheck = clean.split('.'); if(!angular.isUndefined(decimalCheck[1])) { decimalCheck[1] = decimalCheck[1].slice(0,2); clean =decimalCheck[0] + '.' + decimalCheck[1]; } if (val !== clean) { ngModelCtrl.$setViewValue(clean); ngModelCtrl.$render(); } return clean; }); element.bind('keypress', function(event) { if(event.keyCode === 32) { event.preventDefault(); } }); } }; }); 

Verwenden Sie das Step-Tag, um den minimalen änderbaren Wert auf eine Dezimalzahl zu setzen:

zB Schritt = “0,01”

  

Es gibt einige Dokumente hier:

http://blog.isotoma.com/2012/03/html5-input-typenumber-de-cimalsfloats-in-chrome/

DEMO – – jsFiddle

Richtlinie

  .directive('onlyNum', function() { return function(scope, element, attrs) { var keyCode = [8,9,37,39,48,49,50,51,52,53,54,55,56,57,96,97,98,99,100,101,102,103,104,105,110]; element.bind("keydown", function(event) { console.log($.inArray(event.which,keyCode)); if($.inArray(event.which,keyCode) == -1) { scope.$apply(function(){ scope.$eval(attrs.onlyNum); event.preventDefault(); }); event.preventDefault(); } }); }; }); 

HTML

   

Hinweis: Vergessen Sie nicht, jQuery mit angular js einzubeziehen

Es gibt eine Eingabe-Nummern-Direktive, von der ich glaube, dass sie genau das tun kann, was Sie wollen.

  

Das offizielle Dokument ist hier: http://docs.angularjs.org/api/ng.directive:input.number

Sie könnten das ng-Muster einfach verwenden.

 ng-pattern="/^[1-9][0-9]{0,2}(?:,?[0-9]{3}){0,3}(?:\.[0-9]{1,2})?$/" 

HTML

   

// Gib einfach 123 ein

  .directive('onlyDigits', 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 !== val) { ctrl.$setViewValue(digits); ctrl.$render(); } return parseInt(digits,10); } return undefined; } ctrl.$parsers.push(inputValue); } }; 

// type: 123 oder 123.45

  .directive('onlyDigits', 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 !== val) { ctrl.$setViewValue(digits); ctrl.$render(); } return parseFloat(digits); } return undefined; } ctrl.$parsers.push(inputValue); } }; 

Ich wollte eine Direktive, die in ihrer Reichweite durch min und max Attribute eingeschränkt werden könnte:

also schrieb ich folgendes:

 .directive('integer', function() { return { restrict: 'A', require: '?ngModel', link: function(scope, elem, attr, ngModel) { if (!ngModel) return; function isValid(val) { if (val === "") return true; var asInt = parseInt(val, 10); if (asInt === NaN || asInt.toString() !== val) { return false; } var min = parseInt(attr.min); if (min !== NaN && asInt < min) { return false; } var max = parseInt(attr.max); if (max !== NaN && max < asInt) { return false; } return true; } var prev = scope.$eval(attr.ngModel); ngModel.$parsers.push(function (val) { // short-circuit infinite loop if (val === prev) return val; if (!isValid(val)) { ngModel.$setViewValue(prev); ngModel.$render(); return prev; } prev = val; return val; }); } }; }); 

Hier ist mein wirklich schnell-n-dreckiger:

     

Numbers only, please.


Text only, please.


// Javascript file var app = angular.module('num', ['ngResource']); app.controller('numCtrl', function($scope, $http){ $scope.digits = {}; });

Dazu müssen Sie die Angular-Resource-Bibliothek für persistente Bindungen den Feldern für validationszwecke hinzufügen.

Arbeitsbeispiel hier

functioniert wie ein Champion in 1.2.0-rc.3 +. Ändern Sie die Regex und Sie sollten alle eingestellt sein. Vielleicht etwas wie /^(\d|\.)+$/ ? Wie immer, überprüfen Sie die Server-Seite, wenn Sie fertig sind.

Dieser scheint mir der einfachste zu sein: http://jsfiddle.net/thomporter/DwKZh/

(Code ist nicht meiner, ich bin zufällig auf ihn gestoßen)

  angular.module('myApp', []).directive('numbersOnly', function(){ return { require: 'ngModel', link: function(scope, element, attrs, modelCtrl) { modelCtrl.$parsers.push(function (inputValue) { // this next if is necessary for when using ng-required on your input. // In such cases, when a letter is typed first, this parser will be called // again, and the 2nd time, the value will be undefined if (inputValue == undefined) return '' var transformedInput = inputValue.replace(/[^0-9]/g, ''); if (transformedInput!=inputValue) { modelCtrl.$setViewValue(transformedInput); modelCtrl.$render(); } return transformedInput; }); } }; }); 

Ich habe Alans obige Antwort modifiziert, um die Anzahl auf das angegebene Minimum / Maximum zu beschränken. Wenn Sie eine Zahl außerhalb des Bereichs eingeben, wird der Mindest- oder Höchstwert nach 1500 ms festgelegt. Wenn Sie das Feld vollständig löschen, wird nichts gesetzt.

HTML:

  

Javascript:

 var app = angular.module('myApp', []); app.controller('MainCtrl', function($scope) {}); app.directive('validNumber', function($timeout) { return { require: '?ngModel', link: function(scope, element, attrs, ngModelCtrl) { if (!ngModelCtrl) { return; } var min = +attrs.min; var max = +attrs.max; var lastValue = null; var lastTimeout = null; var delay = 1500; ngModelCtrl.$parsers.push(function(val) { if (angular.isUndefined(val)) { val = ''; } if (lastTimeout) { $timeout.cancel(lastTimeout); } if (!lastValue) { lastValue = ngModelCtrl.$modelValue; } if (val.length) { var value = +val; var cleaned = val.replace( /[^0-9]+/g, ''); // This has no non-numeric characters if (val.length === cleaned.length) { var clean = +cleaned; if (clean < min) { clean = min; } else if (clean > max) { clean = max; } if (value !== clean || value !== lastValue) { lastTimeout = $timeout(function () { lastValue = clean; ngModelCtrl.$setViewValue(clean); ngModelCtrl.$render(); }, delay); } // This has non-numeric characters, filter them out } else { ngModelCtrl.$setViewValue(lastValue); ngModelCtrl.$render(); } } return lastValue; }); element.bind('keypress', function(event) { if (event.keyCode === 32) { event.preventDefault(); } }); element.on('$destroy', function () { element.unbind('keypress'); }); } }; }); 

Ich hatte ein ähnliches Problem und aktualisiere das input[type="number"] Beispiel für eckige Dokumente für Arbeiten mit Dezimalstellen und ich verwende diesen Ansatz, um es zu lösen.

PS: Eine kurze Erinnerung ist, dass der Browser die Zeichen ‘e’ und ‘E’ in der Eingabe [type = “number”] unterstützt, da das keypress Ereignis erforderlich ist.

 angular.module('numfmt-error-module', []) .directive('numbersOnly', function() { return { require: 'ngModel', scope: { precision: '@' }, link: function(scope, element, attrs, modelCtrl) { var currencyDigitPrecision = scope.precision; var currencyDigitLengthIsInvalid = function(inputValue) { return countDecimalLength(inputValue) > currencyDigitPrecision; }; var parseNumber = function(inputValue) { if (!inputValue) return null; inputValue.toString().match(/-?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?/g).join(''); var precisionNumber = Math.round(inputValue.toString() * 100) % 100; if (!!currencyDigitPrecision && currencyDigitLengthIsInvalid(inputValue)) { inputValue = inputValue.toFixed(currencyDigitPrecision); modelCtrl.$viewValue = inputValue; } return inputValue; }; var countDecimalLength = function (number) { var str = '' + number; var index = str.indexOf('.'); if (index >= 0) { return str.length - index - 1; } else { return 0; } }; element.on('keypress', function(evt) { var charCode, isACommaEventKeycode, isADotEventKeycode, isANumberEventKeycode; charCode = String.fromCharCode(evt.which || event.keyCode); isANumberEventKeycode = '0123456789'.indexOf(charCode) !== -1; isACommaEventKeycode = charCode === ','; isADotEventKeycode = charCode === '.'; var forceRenderComponent = false; if (modelCtrl.$viewValue != null && !!currencyDigitPrecision) { forceRenderComponent = currencyDigitLengthIsInvalid(modelCtrl.$viewValue); } var isAnAcceptedCase = isANumberEventKeycode || isACommaEventKeycode || isADotEventKeycode; if (!isAnAcceptedCase) { evt.preventDefault(); } if (forceRenderComponent) { modelCtrl.$render(modelCtrl.$viewValue); } return isAnAcceptedCase; }); modelCtrl.$render = function(inputValue) { return element.val(parseNumber(inputValue)); }; modelCtrl.$parsers.push(function(inputValue) { if (!inputValue) { return inputValue; } var transformedInput; modelCtrl.$setValidity('number', true); transformedInput = parseNumber(inputValue); if (transformedInput !== inputValue) { modelCtrl.$viewValue = transformedInput; modelCtrl.$commitViewValue(); modelCtrl.$render(transformedInput); } return transformedInput; }); } }; }); 

Und in Ihrem HTML können Sie diesen Ansatz verwenden

  

Hier ist der Plünderer mit diesem Ausschnitt

Erweiterung von gordys Antwort:

Gute Arbeit übrigens. Aber es erlaubt auch + in der Front. Dies wird es entfernen.

  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; } if (arr.length > 0) { if (arr[0] === "+") { scope.inputValue = oldValue; } } }); 

Hier ist eine Ableitung, die auch den zweimal einzugebenden Dezimalpunkt blockiert

HTML

   

Eckig

  var app = angular.module("myApp", []); app.directive('numbersOnly', function() { return { require : 'ngModel', link : function(scope, element, attrs, modelCtrl) { modelCtrl.$parsers.push(function(inputValue) { if (inputValue == undefined) { return ''; //If value is required } // Regular expression for everything but [.] and [1 - 10] (Replace all) var transformedInput = inputValue.replace(/[az!@#$%^&*()_+\-=\[\]{};':"\\|,<>\/?]/g, ''); // Now to prevent duplicates of decimal point var arr = transformedInput.split(''); count = 0; //decimal counter for ( var i = 0; i < arr.length; i++) { if (arr[i] == '.') { count++; // how many do we have? increment } } // if we have more than 1 decimal point, delete and leave only one at the end while (count > 1) { for ( var i = 0; i < arr.length; i++) { if (arr[i] == '.') { arr[i] = ''; count = 0; break; } } } // convert the array back to string by relacing the commas transformedInput = arr.toString().replace(/,/g, ''); if (transformedInput != inputValue) { modelCtrl.$setViewValue(transformedInput); modelCtrl.$render(); } return transformedInput; }); } }; }); 

Erweitern Adam Thomas Antwort können Sie leicht diese Richtlinie allgemeiner machen, indem Sie Eingabeargument mit benutzerdefinierten Regexp hinzufügen:

 var app = angular.module('myApp', []); app.controller('MainCtrl', 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(); } }); } }}); 

HTML

   

Live auf CodePen

Bitte überprüfen Sie meine Komponente, die Ihnen hilft, nur einen bestimmten Datentyp zuzulassen. Derzeit unterstützt Integer, Dezimal, String und Zeit (HH: MM).

  • string – String ist mit optionaler maximaler Länge erlaubt
  • integer – Ganzzahl nur mit optionalem Maximalwert zulässig
  • decimal – Dezimal nur erlaubt mit optionalen Dezimalpunkten und Max-Wert (standardmäßig 2 Dezimalpunkte)
  • time – 24 Stunden time (HH: MM) nur erlaubt

https://github.com/ksnimmy/txDataType

Ich hoffe, das hilft.

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

angularanweisungen für validationsnummern