Question

Je souhaite utiliser une entrée numérique formatée pour afficher des milliers de points séparateurs à l'utilisateur lorsqu'il tape de gros nombres.Voici le code de la directive que j'ai utilisé : http://jsfiddle.net/LCZfd/3/

Quand j'utilise input type="text" ça marche, mais quand je veux utiliser input type="number" c'est étrangement un nettoyage par quelque chose lorsque l'utilisateur tape de gros nombres.

Quel est le problème input[number]?

Était-ce utile?

La solution

Comme écrit dans les commentaires, input type="number" ne prend en charge que les chiffres, un séparateur décimal (généralement , ou . selon les paramètres régionaux) et - ou e.Vous pouvez toujours entrer ce que vous voulez, mais le navigateur supprimera tout caractère inconnu/incorrect.

Cela vous laisse 2 options :

  • Utiliser type="text" et validation de modèle comme pattern="[0-9]+([\.,][0-9]+)*" pour limiter ce que l'utilisateur peut saisir tout en formatant automatiquement la valeur comme vous le faites dans ton exemple.
  • Placez une superposition au-dessus du champ de saisie qui restitue les nombres comme vous le souhaitez tout en permettant à l'utilisateur d'utiliser la personnalisation. type="number" contrôles d'entrée, comme démontré ici.

Cette dernière solution utilise un supplément <label> balise qui contient la valeur actuelle et est masquée via CSS lorsque vous concentrez le champ de saisie.

Autres conseils

Vous devez ajouter le step attribuer à votre number saisir.

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

Cela autorisera les points flottants.

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

De plus, je vous recommande de consulter le fil de discussion sur les bugs sur number entrées dans Firefox.Vous voudrez peut-être envisager pas en utilisant ce type d'entrée, car il vient tout juste d'être pris en charge dans ce sortie de FF.

Toutes ces années plus tard, il n’existe toujours pas de solution HTML5 prête à l’emploi pour cela.

j'utilise <input type="tel"> ou <input type="text"> ("tel" fait apparaître un clavier numérique sous Android et iOS, ce qui dans certains cas est un bonus.)

Ensuite, j'avais besoin d'une directive pour :

  • filtrer les caractères non numériques
  • ajouter des virgules de séparateur de milliers au fur et à mesure que l'utilisateur tape
  • utiliser $parsers et keyup mettre en place elem.val() et $formatters pour régler l'affichage...
  • ...dans les coulisses, attribuez ng-model un nombre à virgule flottante

L'exemple de directive ci-dessous fait cela et accepte les nombres négatifs et à virgule flottante, sauf si vous spécifiez que vous ne souhaitez que des nombres positifs ou entiers.

Ce n'est pas la solution complète que j'aimerais, mais je pense qu'elle comble le fossé.

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/

Vous ne pouvez pas utiliser de valeurs avec , parce que type=number ne prend que des nombres, l'ajout d'une virgule en fait une chaîne.

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

Il vaut mieux créer vos propres contrôles si vous voulez des virgules.Un avec une vraie valeur (le nombre) et une valeur d'affichage (la chaîne).

vous pouvez essayer ceci, j'ai modifié la directive que j'ai vue ici...Comment puis-je restreindre une saisie pour n’accepter que des chiffres ? ...

voici la directive modifiée que j'ai faite...Cette directive utilise l'événement keyup pour modifier l'entrée à la volée...

.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();
             }
         }
        });
  }

};

tu l'utilises comme ça...

<input type="text" ng-model="amountallocated" id="amountallocated" numeric-only />
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top