146 votes

Comment gérer les flottants et les séparateurs décimaux avec le type d'entrée html5 "number" ?

Je construis une application web qui est principalement destinée aux navigateurs mobiles. J'utilise des champs de saisie de type numérique, de sorte que (la plupart) des navigateurs mobiles n'invoquent que le clavier numérique pour une meilleure expérience utilisateur. Cette application web est principalement utilisée dans des régions où le séparateur décimal est une virgule, et non un point, donc je dois gérer les deux séparateurs décimaux.

Comment couvrir tout ce désordre avec le point et la virgule ?

Mes conclusions :

Chrome de bureau

  • Type d'entrée=numéro
  • L'utilisateur saisit "4,55" dans le champ de saisie.
  • $("#my_input").val(); renvoie "455"
  • Je n'arrive pas à obtenir la valeur correcte de l'entrée

Desktop Firefox

  • Type d'entrée=numéro
  • L'utilisateur saisit "4,55" dans le champ de saisie.
  • $("#my_input").val(); retourne "4,55"
  • C'est bien, je peux remplacer la virgule par un point et obtenir un flotteur correct.

Navigateur Android

  • Type d'entrée=numéro
  • L'utilisateur saisit "4,55" dans le champ de saisie.
  • Lorsque l'entrée perd le focus, la valeur est tronquée à "4".
  • Confusion pour l'utilisateur

Windows Phone 8

  • Type d'entrée=numéro
  • L'utilisateur saisit "4,55" dans le champ de saisie.
  • $("#my_input").val(); retourne "4,55"
  • C'est bien, je peux remplacer la virgule par un point et obtenir un flotteur correct.

Quelles sont les "meilleures pratiques" dans ce type de situation, lorsque l'utilisateur peut utiliser une virgule ou un point comme séparateur décimal et que je souhaite conserver le type d'entrée html comme nombre, afin de fournir une meilleure expérience utilisateur ?

Puis-je convertir les virgules en points "à la volée", en liant les événements de touche, cela fonctionne-t-il avec les entrées numériques ?

EDITAR

Actuellement, je n'ai pas de solution pour obtenir une valeur flottante (sous forme de chaîne ou de nombre) à partir d'une entrée dont le type est défini comme un nombre. Si l'utilisateur saisit "4,55", Chrome renvoie toujours "455", Firefox renvoie "4,55", ce qui est correct.

Il est également assez ennuyeux que dans Android (émulateur 4.2 testé), lorsque je saisis "4,55" dans le champ de saisie et que je change le focus sur autre chose, le nombre saisi est tronqué à "4".

0 votes

Je pense que la cause première de certains de vos problèmes est que les navigateurs sont réglés sur une locale américaine qui utilise le point comme séparateur décimal. Il semble que Chrome et Android s'y perdent de différentes manières : Chrome traite la virgule comme un séparateur de chiffres, puis convertit l'entrée en un nombre, avant de la convertir à nouveau en une chaîne de caractères pour .val() et Android fait quelque chose de bizarre. Pouvez-vous vérifier s'ils se comportent de la même manière lorsque vous définissez la langue du système sur quelque chose d'approprié ?

1 votes

Nvm a posté ceci comme une réponse

0 votes

118voto

natchiketa Points 1483

Je pense que ce qui manque dans les réponses ci-dessus, c'est la nécessité de spécifier une valeur différente pour l'attribut step qui a une valeur par défaut de 1 . Si vous souhaitez que l'algorithme de validation de l'entrée autorise les valeurs à virgule flottante, spécifiez un pas en conséquence.

Par exemple, je voulais des montants en dollars, j'ai donc spécifié une étape comme celle-ci :

 <input type="number" name="price"
           pattern="[0-9]+([\.,][0-9]+)?" step="0.01"
            title="This should be a number with up to 2 decimal places.">

Il n'y a rien de mal à utiliser jQuery pour récupérer la valeur, mais vous trouverez utile d'utiliser directement l'API DOM pour obtenir la valeur de l'élément. validity.valid propriété.

J'ai eu un problème similaire avec le point décimal, mais la raison pour laquelle j'ai réalisé qu'il y avait un problème était le style que Twitter Bootstrap ajoute à une entrée numérique avec une valeur invalide.

Voici un bidouillage démontrant que l'ajout de l'option step le fait fonctionner et vérifie également si la valeur actuelle est valide :

TL;DR : Définir l'a step à une valeur à virgule flottante, parce qu'il est par défaut à 1 .

NOTE : La virgule ne valide pas pour moi, mais je soupçonne que si je configure mes paramètres de langue/région OS à quelque part qui utilise une virgule comme séparateur décimal, cela fonctionnerait. *Note dans la note* : ce n'était pas le cas pour les paramètres de langue/clavier de l'OS *Allemand* dans Ubuntu/Gnome 14.04.

10 votes

Si vous souhaitez autoriser un nombre arbitraire de décimales, spécifiez le paramètre step comme "any" au lieu de, par exemple "0.01" comme indiqué ici. Voir cette version modifiée du violon de nathciketa pour une démo.

4 votes

J'ai également rencontré des problèmes avec les virgules qui n'étaient pas validées, alors que j'entrais "1 234,56" dans le champ <input type="number" step="any"> . Je n'ai pas réussi à trouver un moyen de désactiver la validation HTML5. Je peux désactiver ou personnaliser le message d'erreur, mais la récupération de la valeur à partir de l'entrée est toujours aléatoire. Avez-vous une idée ?

5 votes

This attribute applies when the value of the type attribute is text, search, tel, url, email, or password, otherwise it is ignored. Le motif est donc inutile avec type="number"

26voto

kjetilh Points 2979

Selon le site w3.org, le valeur de l'attribut saisie de chiffres est défini comme un nombre flottant . La syntaxe du nombre à virgule flottante semble n'accepter que les points comme séparateurs décimaux.

Je vous propose ci-dessous quelques options qui pourraient vous être utiles :

1. Utilisation de l'attribut de motif

Avec le motif vous pouvez spécifier le format autorisé à l'aide d'une expression régulière d'une manière compatible avec HTML5. Ici, vous pouvez spécifier que le caractère virgule est autorisé et un message de retour utile si le modèle échoue.

<input type="number" pattern="[0-9]+([,\.][0-9]+)?" name="my-num"
           title="The number input must start with a number and use either comma or a dot as a decimal character."/>

Note : La prise en charge des navigateurs varie beaucoup. Elle peut être complète, partielle ou inexistante

2. Validation JavaScript

Vous pouvez essayer de lier une simple fonction de rappel à l'interface de l'utilisateur. onchange (et/ou flou ) qui remplacerait la virgule ou validerait l'ensemble.

3. Désactiver la validation du navigateur ###

Troisièmement, vous pouvez essayer d'utiliser le formnovalidate sur les entrées numériques dans le but de désactiver la validation du navigateur pour ce champ.

<input type="number" formnovalidate />

4. Combinaison ?

<input type="number" pattern="[0-9]+([,\.][0-9]+)?" 
           name="my-num" formnovalidate
           title="The number input must start with a number and use either comma or a dot as a decimal character."/>

2 votes

input.valueAsNumber - Cela ne m'aide pas car cela ne fonctionne qu'avec des points comme séparateur décimal et dans mon cas, l'utilisateur final pourrait utiliser un point ou une virgule. Étiquette de forme novalidate - Je n'ai pas trouvé d'effet à ce sujet.

0 votes

Malheureusement, je suis à court d'idées, donc je ne suis pas sûr que vous soyez en mesure de faire fonctionner cette fonctionnalité sur plusieurs navigateurs sans solution de contournement. J'ai mis à jour ma réponse pour inclure le motif J'ai également découvert que l'on peut utiliser l'attribut formnovalidate directement sur les champs de saisie. Je sais que cela ne vous plaira pas, mais si tout échoue et que vous avez absolument besoin de virgules, alors input="texte" C'est peut-être le seul moyen

0 votes

Il semble que le numéro du type d'entrée génère plus de problèmes qu'il n'améliore réellement l'expérience de l'utilisateur. Sur un appareil mobile, ce serait génial si je pouvais ouvrir uniquement le clavier numérique à l'utilisateur si je veux qu'il saisisse uniquement des chiffres. Quoi qu'il en soit, je dois repenser à tout cela une fois de plus...

7voto

Mike Samuel Points 54712

Utilice valueAsNumber au lieu de .val() .

input . valueAsNumber [ = value ]

Renvoie un nombre représentant la valeur du contrôle de formulaire, le cas échéant ; sinon, renvoie null.
Peut être réglé, pour changer la valeur.
Lance une exception INVALID_STATE_ERR si le contrôle n'est ni basé sur la date ou l'heure, ni numérique.

3 votes

Le problème est qu'il veut prendre en charge la virgule comme séparateur décimal, et l'utilisation de type="nombre" sur l'entrée donne toujours un nombre invalide lors de l'écriture de la virgule.

0 votes

Il semble que cela ne fonctionne pas de manière cohérente sur Windows Phone ; il y a toujours des retours. NaN .

0 votes

@bertbruynooghe, Qu'est-ce que vous assignez comme valeur ?

0voto

Ma recommandation ? N'utilisez pas du tout jQuery. J'ai eu le même problème que vous. J'ai trouvé que $('#my_input').val() renvoient toujours un résultat bizarre.

Essayez d'utiliser document.getElementById('my_input').valueAsNumber au lieu de $("#my_input").val(); et ensuite, utiliser Number(your_value_retrieved) pour essayer de créer un nombre. Si la valeur est NaN, vous savez certainement que ce n'est pas un nombre.

Une chose à ajouter est que lorsque vous écrivez un nombre sur l'entrée, l'entrée accepte en fait presque n'importe quel caractère (je peux écrire le signe euro, un dollar, et tous les autres caractères spéciaux), il est donc préférable de récupérer la valeur en utilisant .valueAsNumber au lieu d'utiliser jQuery.

Oh, et BTW, cela permet à vos utilisateurs d'ajouter l'internationalisation (c'est-à-dire : prendre en charge les virgules au lieu des points pour créer des nombres décimaux). Il suffit de laisser le Number() pour créer quelque chose pour vous et ce sera sécurisé par les décimales, pour ainsi dire.

0 votes

Le problème n'est pas causé par jQuery, et je trouve que valueAsNumber ne fonctionne pas non plus de manière cohérente avec les navigateurs.

0voto

stackasec Points 40

Il semble que vous souhaitiez utiliser toLocaleString() sur vos entrées numériques.

Ver https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString pour son utilisation.

La localisation des nombres en JS est également traitée dans le document Internationalisation (formatage des nombres "num.toLocaleString()") ne fonctionne pas pour chrome

2 votes

Il est habituel de donner plus d'explications sur la solution même si la réponse est entièrement couverte par le contenu lié.

0 votes

Cette approche semble être meilleure que les autres approches si le serveur dorsal détermine la locale plutôt que le navigateur lui-même. Malheureusement, toLocaleString n'est pas fiable sur toutes les plateformes.

0 votes

Le support multiplateforme me semble suffisamment large en 2015, voir par exemple Mozillas Devnet . Toutefois, si cela vous préoccupe toujours, trouver des solutions possibles ici.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X