Autoriser 2 décimales dans <type d'entrée = "nombre">


222

j'ai un <input type="number"> et je veux restreindre la saisie des utilisateurs à des nombres purement ou des nombres avec des décimales jusqu'à 2 décimales.

Fondamentalement, je demande une entrée de prix.

Je voulais éviter de faire des regex. Y a-t-il un moyen de le faire?

<input type="number" required name="price" min="0" value="0" step="any">

2
type = "nombre" ne prend pas en charge un large navigateur. Il est préférable d'utiliser simplement une zone de texte avec du javascript pour vous assurer d'obtenir l'entrée souhaitée.
www139

6
Oui, mais les entrées retombent de type="text"toute façon, alors qu'importe?
Ultimater

Duplication possible de Y a
OhadR

/^\d+\.\d{2,2}$/ a fonctionné pour moi pour exiger 0,00
ZStoneDPM

Réponses:


337

Au lieu de step="any", qui autorise un nombre quelconque de décimales, utilisez step=".01", qui autorise jusqu'à deux décimales.

Plus de détails dans la spécification: https://www.w3.org/TR/html/sec-forms.html#the-step-attribute


38
Ce n'est pas la bonne réponse. l'étape ne régit que ce qui se passe lorsque vous cliquez ou appuyez dessus et ne restreint rien.
Ini

1
@Michael_B indépendamment de ce que la spécification espère, c'est assez trivial à tester: jsfiddle.net/9hvm0b5u autorise toujours plus de 2 décimales à entrer. Les étapes régissent uniquement la manière dont les boutons +/- déplacent le montant. (Chrome)
Nathan

3
@Michael_B l'utilisateur n'est pas empêché de taper un nombre tel que 500.12345dans l'une des entrées, peut-être que notre compréhension des exigences est différente.
Nathan

3
Il convient de noter que, bien que l'utilisateur puisse taper n'importe quel nombre de chiffres après la décimale, la plupart des navigateurs n'autorisent pas la soumission du formulaire avec une valeur non valide et les sélecteurs CSS :validet :invalidsont appliqués comme prévu.
Andrew Dinmore

1
@Nathan, il est également trivial de tester la validation du navigateur. Essayez de soumettre une valeur avec plus de 2 décimales: jsfiddle.net/4yesgn7b
imclean

43

Si quelqu'un recherche une expression régulière qui n'autorise que les nombres avec 2 décimales en option

^\d*(\.\d{0,2})?$

Par exemple, j'ai trouvé la solution ci-dessous assez fiable

HTML:

<input name="my_field" pattern="^\d*(\.\d{0,2})?$" />

JS / JQuery:

$(document).on('keydown', 'input[pattern]', function(e){
  var input = $(this);
  var oldVal = input.val();
  var regex = new RegExp(input.attr('pattern'), 'g');

  setTimeout(function(){
    var newVal = input.val();
    if(!regex.test(newVal)){
      input.val(oldVal); 
    }
  }, 0);
});

2
Quel est le but d'avoir setTimeout ()?
Derek

2
@Derek. Je suppose que c'est pour que le regex.test ne bloque pas le DOM. Recherchez ceci: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
christo8989

2
@Derek Je peux seulement supposer que setTimeout()c'est attendre la fin de l' keydownévénement avant de configurer le newVal(sinon ce sera le même que le oldVal). Cependant, avec un timeout de 0, c'est inutile et ne fonctionne pas car les deux valeurs sont souvent les mêmes (dans Firefox). Si vous le définissez sur 1, par exemple, cela fonctionne très bien.
alstr

Donc, vous avez annulé ma modification dans deux articles différents pour une raison "la modification non approuvée dégrade la qualité de formatage de la réponse". Pouvez-vous expliquer en quoi ma modification n'est pas approuvée et comment cela dégrade-t-il exactement la qualité de la réponse? (IMO, cela l'améliore, car les gens peuvent exécuter le code directement à partir du post et ils n'ont pas besoin d'aller sur JSFiddle).
double bip le

21

Pour la monnaie, je suggère:

<div><label>Amount $
    <input type="number" placeholder="0.00" required name="price" min="0" value="0" step="0.01" title="Currency" pattern="^\d+(?:\.\d{1,2})?$" onblur="
this.parentNode.parentNode.style.backgroundColor=/^\d+(?:\.\d{1,2})?$/.test(this.value)?'inherit':'red'
"></label></div>

Voir http://jsfiddle.net/vx3axsk5/1/

Les propriétés HTML5 "step", "min" et "pattern" seront validées lorsque le formulaire sera envoyé, pas onblur. Vous n'avez pas besoin du stepsi vous en avez un patternet vous n'en avez pas besoin patternsi vous en avez un step. Vous pouvez donc revenir àstep="any" mon code puisque le modèle le validera de toute façon.

Si vous souhaitez valider onblur, je pense que donner à l'utilisateur un repère visuel est également utile, comme colorier l'arrière-plan en rouge. Si le navigateur de l'utilisateur ne le prend pas en charge, type="number"il reviendra à type="text". Si le navigateur de l'utilisateur ne prend pas en charge la validation du modèle HTML5, mon extrait de code JavaScript n'empêche pas la soumission du formulaire, mais il donne un signal visuel. Donc, pour les personnes avec une mauvaise prise en charge HTML5 et les personnes qui tentent de pirater la base de données avec JavaScript désactivé ou qui forgent des demandes HTTP, vous devez de toute façon valider sur le serveur. Le point avec la validation sur le front-end est pour une meilleure expérience utilisateur. Donc, tant que la plupart de vos utilisateurs ont une bonne expérience, il est bon de s'appuyer sur les fonctionnalités HTML5 à condition que le code fonctionne toujours et que vous puissiez valider sur le back-end.


2
Selon MDN , patternne fonctionne pas pour input type=number:<input type="number"> elements do not support use of the pattern attribute for making entered values conform to a specific regex pattern. The rationale for this is that number inputs can't contain anything except numbers, and you can constrain the minimum and maximum number of valid digits using the min and max attributes, as explained above.
izogfif

@izogfif Bonne note. Notez également que j'ai remarqué que vous n'avez pas besoin des deux et que vous avez fourni trois méthodes: étape, motif et onblur. Mon raisonnement à l'époque était que si un navigateur s'étouffe sur l'un pour une raison quelconque, il a l'autre. Il est probablement sûr de s'appuyer sur l'étape de nos jours pour la validation frontale.
Ultimater

16

Étape 1: Accrochez votre zone de saisie de numéro HTML à un événement onchange

myHTMLNumberInput.onchange = setTwoNumberDecimal;

ou dans le code HTML

<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />

Étape 2: Écrivez la setTwoDecimalPlaceméthode

function setTwoNumberDecimal(event) {
    this.value = parseFloat(this.value).toFixed(2);
}

Vous pouvez modifier le nombre de décimales en variant la valeur passée dans la toFixed()méthode. Voir les documents MDN .

toFixed(2); // 2 decimal places
toFixed(4); // 4 decimal places
toFixed(0); // integer

3
parseFloat (parseFloat (this.value) .toFixed (2)); Si vous voulez un type décimal ou numérique, vous pouvez envelopper le tout dans parseFloat () car par défaut la méthode toFixed () renvoie une chaîne.
spacedev

6

J'ai trouvé que l'utilisation de jQuery était ma meilleure solution.

$( "#my_number_field" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});

6

Essayez ceci pour autoriser seulement 2 décimales dans le type d'entrée

<input type="number" step="0.01" class="form-control"  />

Ou utilisez jQuery comme suggéré par @SamohtVII

$( "#ELEMENTID" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});

21
Cela ne limite pas les décimales à 2 places dans Chrome 57
mintedsky

1
Ce n'est pas correct. l'étape ne régit que ce qui se passe lorsque vous cliquez ou appuyez dessus et ne restreint rien.
Ini

Cette étape empêche également la saisie d'un nombre comme 1.000.
Zapnologica

-2

Utilisez ce code

<input type="number" step="0.01" name="amount" placeholder="0.00">

Par défaut, la valeur de l'étape pour les éléments d'entrée HTML5 est step = "1".


-4

Ecrivez

<input type="number" step="0.1" lang="nb">

lang = 'nb "vous permet d'écrire vos nombres décimaux avec une virgule ou un point


"lang = 'nb' vous permet d'écrire vos nombres décimaux avec une virgule ou un point" Je ne peux pas parler d'autre chose, mais cela ne fonctionne pas dans Chrome pour moi.
Andrew Dinmore

-9

En entrée:

step="any"
class="two-decimals"

Sur le script:

$(".two-decimals").change(function(){
  this.value = parseFloat(this.value).toFixed(2);
});

5
Veuillez éviter d'utiliser des insultes dans votre message. Et n'oubliez pas d' être gentil
James
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.