Domanda

Voglio utilizzare un input number formattato per mostrare mille punti separatorie all'utente quando tipi numeri grandi.Ecco il codice direttivo che ho usato: http://jsfiddle.net/lczfd/3/ .

Quando utilizzo input type="text" funziona, ma quando voglio usare input type="number" è una pulizia stranamente con qualcosa quando l'utente digita numeri grandi.

Qual è il problema su input[number]?

È stato utile?

Soluzione

Come scritto nei commenti, input type="number" non supporta nulla ma cifre, un separatore decimale (di solito , o . a seconda delle impostazioni locali) e - o e. Puoi ancora Inserisci Qualunque cosa tu voglia, ma il browser scarterà qualsiasi carattere sconosciuto / errato.

Questo ti lascia con 2 opzioni:

    .
  • Utilizzare type="text" e convalida del modello come pattern="[0-9]+([\.,][0-9]+)*" per limitare ciò che l'utente può inserire durante la formattazione del valore come si esegue automaticamente il valore come si esegue in Il tuo esempio .
  • Metti una sovrapposizione sulla parte superiore del campo di input che rende i numeri come si desidera e consente comunque all'utente di utilizzare i controlli di ingresso personalizzati type="number", come dimostrato qui .

Quest'ultima soluzione utilizza un tag <label> aggiuntivo che contiene il valore corrente ed è nascosto tramite CSS quando si focalizza il campo di input.

Altri suggerimenti

È necessario aggiungere l'attributo step all'ingresso number.

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

Ciò consentirà i punti flottanti.

http://jsfiddle.net/lczfd/1/

Inoltre, consiglierei di rivedere il filo del bug su ingressi number in Firefox.Si consiglia di considerare non usando questo tipo di ingresso, poiché è stato appena supportato in rilascio di ff.

Tutti questi anni dopo, non c'è ancora una soluzione HTML5 fuori dalla scatola per questo.

Sto usando <input type="tel"> o <input type="text"> ("Tel" offre una tastiera numerica in Android e IOS, che in alcuni casi è un bonus.)

Allora avevo bisogno di una direttiva su:

    .
  • Filtrare i caratteri non numerici
  • Aggiungere mille virgolette come tipo utente
  • Utilizzare $parsers e keyup per impostare elem.val() e $formatters per impostare il display ...
  • ... Mentre dietro le quinte, assegna ng-model un numero punto di galleggiamento

L'esempio della direttiva seguente è questo, e accetta negativi e numeri del punto flottante a meno che non si specifichi di volere solo positivi o numeri interi.

Non è la soluzione completa che vorrei, ma penso che colpisca il divario.

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/

Non è possibile utilizzare i valori con , perché type=number prende solo numeri, aggiungendo una virgola lo rende una stringa.

Vedi http://jsfiddle.net/lczfd/5

Stai meglio a creare i tuoi controlli se vuoi virgole.Uno con un valore reale (il numero) e un valore di visualizzazione (la stringa).

Puoi provare questo, ho modificato la direttiva che ho visto qui ... Come posso limitare un input soloAccetta numeri? ...

Ecco la Direttiva modificata che ho fatto ... Questa direttiva utilizza l'evento Keyup per modificare l'ingresso sul volo ...

.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 usi come questo ...

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top