Pergunta

Eu quero usar um número formatado de entrada para mostrar separador de milhares de pontos para o usuário quando ele tipos de números grandes.Aqui é a directiva de código que eu usei: http://jsfiddle.net/LCZfd/3/

Quando eu uso input type="text" ele funciona, mas quando eu quero usar input type="number" é muito estranho, limpeza por algo ao usuário a digitação de números grandes.

O que é um problema sobre o input[number]?

Foi útil?

Solução

Como está escrito nos comentários, input type="number" não suporta nada, mas dígitos, um separador decimal (normalmente , ou . dependendo da localidade) e - ou e.Você ainda pode entrar tudo o que você quiser, mas o navegador irá descartar qualquer desconhecido / caractere incorreto.

Isso deixa você com 2 opções:

  • Utilização type="text" e o padrão de validação como pattern="[0-9]+([\.,][0-9]+)*" para limitar o que o usuário pode inserir automaticamente a formatação do valor em o seu exemplo.
  • Colocar uma sobreposição na parte superior do campo de entrada o que torna os números de como você deseja e ainda permite que o usuário utilize o custom type="number" os controles de entrada, como demonstrado aqui.

A última solução utiliza um adicional de <label> tag que contém o valor atual e está oculto via CSS quando você se concentrar o campo de entrada.

Outras dicas

Você precisa adicionar o step atributo para o seu number entrada.

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

Isto irá permitir que pontos flutuantes.

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

Também, eu recomendo rever o erro thread em number entradas no Firefox.Você pode querer considerar não usando este tipo de entrada, assim como foi, finalmente, com suporte no este versão do FF.

Todos estes anos depois, ainda não existe uma HTML5 solução fora da caixa para isso.

Eu estou usando <input type="tel"> ou <input type="text"> ("tel" traz um teclado numérico no Android e iOS, que, em alguns casos, é um bônus.)

Então eu precisava de uma directiva para:

  • filtrar caracteres não numéricos
  • adicione mil-separador de vírgulas como os tipos de usuário
  • utilização $parsers e keyup para definir elem.val() e $formatters para definir a apresentação...
  • ...enquanto nos bastidores, atribuir ng-model um número de ponto flutuante

A directiva exemplo abaixo faz isso, e ele aceita negativos e números de ponto flutuante, a menos que você especifique que você quer apenas positivo ou inteiros.

Não é a solução completa que eu gostaria, mas eu acho que ele preenche a lacuna.

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/

Você não pode usar valores com , porque type=number leva apenas números, adicionar uma vírgula torna uma seqüência de caracteres.

Ver http://jsfiddle.net/LCZfd/5

Você é melhor fora de fazer seus próprios controles se você deseja vírgulas.Um com um valor true (o número) e um valor de exibição (seqüência de caracteres).

você pode tentar isso, eu modifiquei a directiva eu vi aqui...Como faço para restringir a entrada para aceitar apenas números? ...

aqui está a alteração da directiva que eu fiz...Esta directiva usa o evento keyup para modificar a entrada na 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();
             }
         }
        });
  }

};

você usá-lo como este ...

<input type="text" ng-model="amountallocated" id="amountallocated" numeric-only />
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top