filtros - Entrada formateada de entrada de número AngularJS
filtros angular 4 (5)
Debe agregar el atributo de step
a su entrada de number
.
<input type="number" step="0.01" />
Esto permitirá puntos flotantes.
Además, recomiendo revisar el subproceso de error en las entradas number
en Firefox. Es posible que desee considerar no utilizar este tipo de entrada, ya que finalmente se admitió en esta versión de FF.
Quiero usar una entrada numérica formateada para mostrar mil puntos de separador al usuario cuando escribe números grandes. Aquí está el código de la directiva que utilicé: http://jsfiddle.net/LCZfd/3/
Cuando uso input type="text"
, funciona, pero cuando quiero usar input type="number"
está extrañamente limpio por algo cuando el usuario escribe números grandes.
¿Cuál es el problema sobre la input[number]
?
No puede usar valores con ,
porque type=number
solo toma números, agregar una coma lo convierte en una cadena.
Ver http://jsfiddle.net/LCZfd/5
Es mejor que hagas tus propios controles si quieres comas. Uno con un valor verdadero (el número) y un valor de visualización (la cadena).
Puedes probar esto, modifiqué la directiva que vi aquí ... ¿Cómo restringo una entrada para que solo acepte números? ...
Aquí está la directiva modificada que hice ... Esta directiva usa el evento keyup para modificar la entrada sobre la marcha ...
.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();
}
}
});
}
};
lo usas asi ...
<input type="text" ng-model="amountallocated" id="amountallocated" numeric-only />
Tal como está escrito en los comentarios, input type="number"
no admite nada más que dígitos, un separador decimal (generalmente ,
o .
, Según la configuración regional) y -
o e
. Aún puede ingresar lo que quiera, pero el navegador descartará cualquier carácter desconocido / incorrecto.
Esto te deja con 2 opciones:
- use
type="text"
y la validación de patrón comopattern="[0-9]+([/.,][0-9]+)*"
para limitar lo que el usuario puede ingresar mientras formatea automáticamente el valor como lo hace en tu ejemplo - coloque una superposición en la parte superior del campo de entrada que muestre los números como desee y aún así permita al usuario usar los controles de entrada personalizados de
type="number"
, como se muestra aquí
La última solución utiliza una <label>
adicional que contiene el valor actual y se oculta a través de CSS cuando enfoca el campo de entrada.
Todos estos años después, todavía no hay una solución HTML5 lista para usar para esto.
Estoy usando <input type="tel">
o <input type="text">
("tel" muestra un teclado numérico en Android e iOS, que en algunos casos es una ventaja).
Entonces necesitaba una directiva para:
- filtrar los caracteres no numéricos
- agregue comas de mil separadores según los tipos de usuarios
- use
$parsers
ykeyup
para configurarelem.val()
y$formatters
para configurar la pantalla ... - ... mientras está detrás de escena, asigne a
ng-model
un número de punto flotante
El siguiente ejemplo de directiva hace esto, y acepta números negativos y de punto flotante a menos que especifique que desea solo positivos o enteros.
No es la solución completa que me gustaría, pero creo que cierra la brecha.
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;
}
}
};
});