Pregunta

Quiero usar una entrada numérica formateada para mostrarle mil puntos separadores al usuario cuando escribe números grandes.Aquí está el código de directiva que utilicé: http://jsfiddle.net/LCZfd/3/

cuando uso input type="text" funciona, pero cuando quiero usarlo input type="number" Algo se limpia extrañamente cuando el usuario escribe números grandes.

¿De qué se trata el problema? input[number]?

¿Fue útil?

Solución

Como está escrito en los comentarios, input type="number" no admite nada más que dígitos, un separador decimal (generalmente , o . dependiendo de la localidad) y - o e.todavía puedes ingresar lo que quieras, pero el navegador descartará cualquier carácter desconocido/incorrecto.

Esto te deja con 2 opciones:

  • Usar type="text" y validación de patrones como pattern="[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 represente los números como desee y aún permita al usuario usar la configuración personalizada. type="number" controles de entrada, como demostrado aquí.

La última solución utiliza un adicional <label> etiqueta que contiene el valor actual y se oculta mediante CSS cuando enfoca el campo de entrada.

Otros consejos

Necesitas agregar el step atribuye a tu number aporte.

<input type="number" step="0.01" />

Esto permitirá puntos flotantes.

http://jsfiddle.net/LCZfd/1/

Además, recomendaría revisar el hilo de errores en number entradas en Firefox.Quizás quieras considerar no usando este tipo de entrada, ya que finalmente fue admitido en este liberación de FF.

Todos estos años después, todavía no existe 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, lo que en algunos casos es una ventaja).

Entonces necesitaba una directiva para:

  • filtrar caracteres no numéricos
  • agregue comas de separador de mil a medida que el usuario escribe
  • usar $parsers y keyup establecer elem.val() y $formatters para configurar la pantalla...
  • ...mientras detrás de escena, asigna ng-model un número de coma flotante

El siguiente ejemplo de directiva hace esto y acepta números negativos y de punto flotante a menos que especifique que desea solo números 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;
      }
    }
  };
});

https://jsfiddle.net/benlk/4dto9738/

No puedes 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 crees 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, modificé la directiva que vi aquí ... ¿Cómo restringo una entrada para solo¿Aceptar números? ...

Aquí está la directiva modificada que hice ... Esta directiva utiliza el evento de KeyUp para modificar la entrada en la mosca ...

.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 así ...

<input type="text" ng-model="amountallocated" id="amountallocated" numeric-only />

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top