Formatierte Ansicht mit AngularJS-Zahleneingabe
-
20-12-2019 - |
Frage
Ich möchte eine formatierte Zahleneingabe verwenden, um dem Benutzer tausend Trennpunkte anzuzeigen, wenn er große Zahlen eingibt.Hier ist der Direktivencode, den ich verwendet habe: http://jsfiddle.net/LCZfd/3/
Wenn ich es benutze input type="text"
Es funktioniert, aber wenn ich es verwenden möchte input type="number"
Es kommt seltsamerweise zu einer Bereinigung, wenn der Benutzer große Zahlen eingibt.
Worum geht es? input[number]
?
Lösung
Wie in den Kommentaren geschrieben, input type="number"
unterstützt nichts anderes als Ziffern, ein Dezimaltrennzeichen (normalerweise). ,
oder .
je nach Standort) und -
oder e
.Sie können immer noch eingeben was auch immer Sie wollen, aber der Browser verwirft alle unbekannten/falschen Zeichen.
Damit haben Sie zwei Möglichkeiten:
- Verwenden
type="text"
und Mustervalidierung wiepattern="[0-9]+([\.,][0-9]+)*"
um einzuschränken, was der Benutzer eingeben kann, während der Wert automatisch formatiert wird, wie Sie es tun Dein Beispiel. - Platzieren Sie ein Overlay über dem Eingabefeld, das die Zahlen wie gewünscht darstellt und es dem Benutzer dennoch ermöglicht, die benutzerdefinierten Werte zu verwenden
type="number"
Eingabesteuerungen, wie hier demonstriert.
Die letztere Lösung verwendet eine zusätzliche <label>
Tag, das den aktuellen Wert enthält und per CSS ausgeblendet wird, wenn Sie den Fokus auf das Eingabefeld richten.
Andere Tipps
Sie müssen das hinzufügen step
Attribut zu Ihrem number
Eingang.
<input type="number" step="0.01" />
Dies ermöglicht Gleitkommazahlen.
Außerdem würde ich empfehlen, den Bug-Thread auf zu lesen number
Eingaben in Firefox.Vielleicht möchten Sie darüber nachdenken nicht Verwendung dieses Eingabetyps, da er gerade endlich unterstützt wurde Das Veröffentlichung von FF.
All diese Jahre später gibt es dafür immer noch keine fertige HTML5-Lösung.
ich benutze <input type="tel">
oder <input type="text">
(„tel“ ruft eine numerische Tastatur in Android und iOS auf, was in manchen Fällen ein Bonus ist.)
Dann brauchte ich eine Anweisung, um:
- Nicht-numerische Zeichen herausfiltern
- Fügen Sie bei der Eingabe durch den Benutzer Tausender-Trennzeichen hinzu
- verwenden
$parsers
Undkeyup
einstellenelem.val()
Und$formatters
um die Anzeige einzustellen... - ...während Sie hinter den Kulissen zuweisen
ng-model
eine Gleitkommazahl
Das folgende Direktivenbeispiel erledigt dies und akzeptiert negative Zahlen und Gleitkommazahlen, es sei denn, Sie geben an, dass Sie nur positive oder ganze Zahlen wünschen.
Es ist nicht die vollständige Lösung, die ich mir wünschen würde, aber ich denke, dass sie die Lücke schließt.
HTML
<input type="text" ng-model="someNumber" number-input />
JAVASCRIPT
myApp.directive('numberInput', function($filter) {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
ngModelCtrl.$formatters.push(function(modelValue) {
return setDisplayNumber(modelValue, true);
});
// it's best to change the displayed text using elem.val() rather than
// ngModelCtrl.$setViewValue because the latter will re-trigger the parser
// and not necessarily in the correct order with the changed value last.
// see http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/
// for an explanation of how ngModelCtrl works.
ngModelCtrl.$parsers.push(function(viewValue) {
setDisplayNumber(viewValue);
return setModelNumber(viewValue);
});
// occasionally the parser chain doesn't run (when the user repeatedly
// types the same non-numeric character)
// for these cases, clean up again half a second later using "keyup"
// (the parser runs much sooner than keyup, so it's better UX to also do it within parser
// to give the feeling that the comma is added as they type)
elem.bind('keyup focus', function() {
setDisplayNumber(elem.val());
});
function setDisplayNumber(val, formatter) {
var valStr, displayValue;
if (typeof val === 'undefined') {
return 0;
}
valStr = val.toString();
displayValue = valStr.replace(/,/g, '').replace(/[A-Za-z]/g, '');
displayValue = parseFloat(displayValue);
displayValue = (!isNaN(displayValue)) ? displayValue.toString() : '';
// handle leading character -/0
if (valStr.length === 1 && valStr[0] === '-') {
displayValue = valStr[0];
} else if (valStr.length === 1 && valStr[0] === '0') {
displayValue = '';
} else {
displayValue = $filter('number')(displayValue);
}
// handle decimal
if (!attrs.integer) {
if (displayValue.indexOf('.') === -1) {
if (valStr.slice(-1) === '.') {
displayValue += '.';
} else if (valStr.slice(-2) === '.0') {
displayValue += '.0';
} else if (valStr.slice(-3) === '.00') {
displayValue += '.00';
}
} // handle last character 0 after decimal and another number
else {
if (valStr.slice(-1) === '0') {
displayValue += '0';
}
}
}
if (attrs.positive && displayValue[0] === '-') {
displayValue = displayValue.substring(1);
}
if (typeof formatter !== 'undefined') {
return (displayValue === '') ? 0 : displayValue;
} else {
elem.val((displayValue === '0') ? '' : displayValue);
}
}
function setModelNumber(val) {
var modelNum = val.toString().replace(/,/g, '').replace(/[A-Za-z]/g, '');
modelNum = parseFloat(modelNum);
modelNum = (!isNaN(modelNum)) ? modelNum : 0;
if (modelNum.toString().indexOf('.') !== -1) {
modelNum = Math.round((modelNum + 0.00001) * 100) / 100;
}
if (attrs.positive) {
modelNum = Math.abs(modelNum);
}
return modelNum;
}
}
};
});
Sie können keine Werte mit verwenden ,
Weil type=number
Nimmt nur Zahlen auf, das Hinzufügen eines Kommas macht es zu einer Zeichenfolge.
Sehen http://jsfiddle.net/LCZfd/5
Wenn Sie Kommas wünschen, ist es besser, Ihre eigenen Steuerelemente zu erstellen.Eines mit einem wahren Wert (der Zahl) und einem Anzeigewert (der Zeichenfolge).
Sie können es versuchen. Ich habe die Anweisung, die ich hier gesehen habe, geändert ...Wie schränke ich eine Eingabe so ein, dass nur Zahlen akzeptiert werden? ...
Hier ist die geänderte Anweisung, die ich gemacht habe ...Diese Direktive verwendet das Keyup-Ereignis, um die Eingabe im laufenden Betrieb zu ändern ...
.directive('numericOnly', function($filter) {
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
element.bind('keyup', function (inputValue, e) {
var strinput = modelCtrl.$$rawModelValue;
//filter user input
var transformedInput = strinput ? strinput.replace(/[^,\d.-]/g,'') : null;
//remove trailing 0
if(transformedInput.charAt(0) <= '0'){
transformedInput = null;
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}else{
var decimalSplit = transformedInput.split(".")
var intPart = decimalSplit[0];
var decPart = decimalSplit[1];
//remove previously formated number
intPart = intPart.replace(/,/g, "");
//split whole number into array of 3 digits
if(intPart.length > 3){
var intDiv = Math.floor(intPart.length / 3);
var strfraction = [];
var i = intDiv,
j = 3;
while(intDiv > 0){
strfraction[intDiv] = intPart.slice(intPart.length-j,intPart.length - (j - 3));
j=j+3;
intDiv--;
}
var k = j-3;
if((intPart.length-k) > 0){
strfraction[0] = intPart.slice(0,intPart.length-k);
}
}
//join arrays
if(strfraction == undefined){ return;}
var currencyformat = strfraction.join(',');
//check for leading comma
if(currencyformat.charAt(0)==','){
currencyformat = currencyformat.slice(1);
}
if(decPart == undefined){
modelCtrl.$setViewValue(currencyformat);
modelCtrl.$render();
return;
}else{
currencyformat = currencyformat + "." + decPart.slice(0,2);
modelCtrl.$setViewValue(currencyformat);
modelCtrl.$render();
}
}
});
}
};
Du benutzt es so ...
<input type="text" ng-model="amountallocated" id="amountallocated" numeric-only />