Comment manipuler les flotteurs et les séparateurs décimaux avec le numéro de type d'entrée html5

Im construire application web qui est principalement pour les navigateurs mobiles. Im utilisant des champs d'entrée avec le type de numéro, si (la plupart) les navigateurs mobiles invoque seulement le clavier de numéro pour une meilleure expérience de l'utilisateur. Cette application web est principalement utilisée dans les régions où le séparateur décimal est virgule, Pas point, donc je dois gérer les deux séparateurs décimaux.

comment couvrir tout ce bazar avec dot et virgule?

Mes conclusions:

Chrome De Bureau

  • Input type="numéro de 1519150920"
  • L'utilisateur inscrit "4,55" au champ d'entrée
  • $("#my_input").val(); renvoie "455"
  • je ne peux pas obtenir la bonne valeur de l'entrée

"1519100920 De Bureau" Firefox

  • Input type="numéro de 1519150920"
  • L'utilisateur inscrit "4,55" au champ d'entrée
  • $("#my_input").val(); renvoie "4,55"
  • Thats fine, je peux remplacer la virgule par point et d'obtenir de bons float

Android browser

  • Input type="numéro de 1519150920"
  • L'utilisateur inscrit "4,55" au champ d'entrée
  • lorsque l'entrée perd sa focalisation, la valeur est tronquée à "4"
  • déroutant pour l'utilisateur

Windows Phone 8

  • Input type="numéro de 1519150920"
  • L'utilisateur inscrit "4,55" au champ d'entrée
  • $("#my_input").val(); renvoie "4,55"
  • Thats fine, je peux remplacer la virgule par point et d'obtenir de bons float

Quelles sont les "meilleures pratiques" dans ce genre de situations où l'utilisateur peut utiliser la virgule ou le point comme séparateur décimal et je veux garder html type d'entrée comme numéro, pour fournir une meilleure expérience utilisateur?

puis-je convertir virgule en point "à la volée", liant les événements clés, fonctionne-t-il avec des entrées de nombre?

EDIT

a ce stade je n'ai pas de solution, comment faire pour obtenir la valeur flottante (comme une chaîne de caractères ou un nombre) d'entrée type de numéro. Si enduser entre "4,55", Chrome renvoie toujours "455", Firefox renvoie" 4,55 " ce qui est très bien.

aussi il est tout à fait ennuyeux que dans Android (testé 4.2 émulateur), lorsque j'entre "4,55" à champ d'entrée et de changer de focus à un autre endroit, le nombre entré obtenir tronqué à "4".

110
demandé sur devha 2013-03-09 01:50:39

8 réponses

je pense que ce qui manque dans les réponses ci-dessus 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 voulez que l'algorithme de validation de l'entrée permette des valeurs à virgule flottante, spécifiez une étape en conséquence.

par exemple, je voulais des montants en dollars, donc j'ai 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 trouvez utile d'utiliser l'API DOM directement pour obtenir la propriété validity.valid des elements.

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 en raison du style que Twitter Bootstrap ajoute à un nombre d'entrée avec une valeur invalide.

voici un violon qui démontre que l'ajout de l'attribut step le fait fonctionner, et qui vérifie également si la valeur actuelle est valide:

TL;DR: définir l'attribut 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 mets mes paramètres de langue/Région de système D'exploitation quelque part qui utilise une virgule comme le séparateur décimal, il pourrait fonctionner. * note dans la note*: ce n'était pas le cas pour les paramètres de langue/clavier OS *allemand* dans Ubuntu/Gnome 14.04.

95
répondu natchiketa 2015-11-27 14:36:50

selon w3.org l'attribut valeur du nombre d'entrée est défini comme un nombre à virgule flottante . La syntaxe du nombre à virgule flottante semble n'accepter que les points comme séparateurs décimaux.

j'ai énuméré quelques options ci-dessous qui pourraient être utiles pour vous:

1. En utilisant l'attribut pattern

avec le pattern attribut vous pouvez spécifier le format autorisé avec une expression régulière d'une manière compatible HTML5. Ici, vous pouvez spécifier que le caractère virgule est autorisé et un message de rétroaction 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 de l'ensemble du navigateur varie beaucoup. Il peut être complète, partielle ou nulle..

2. Validation JavaScript

vous pourriez essayez de lier un simple rappel à l'événement onchange (et/ou flou ) qui remplacerait la virgule ou validerait tout ensemble.

3. Désactiver la validation du navigateur # #

Troisièmement, vous pouvez essayer d'utiliser l'attribut formnovalidate sur les entrées de nombre avec l'intention de désactiver la validation de navigateur pour ce champ tous ensemble.

<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."/>
19
répondu kjetilh 2013-03-09 08:22:25

l'utilisation de virgule ou de période pour le séparateur décimal dépend entièrement du navigateur. Le navigateur prend la décision en fonction de la localisation du système d'exploitation ou du navigateur, ou certains navigateurs prennent des conseils à partir du site web. J'ai fait un tableau de comparaison de navigateur montrant comment les différents navigateurs prennent en charge différentes méthodes de localisation. Safari étant le seul navigateur qui traite les virgules et les périodes de façon interchangeable.

en gros, vous comme un auteur web ne peut pas vraiment contrôler. Certaines solutions impliquent l'utilisation de deux champs d'entrée avec des entiers. Cela permet à chaque utilisateur de saisir les données comme prévu. Ses pas particulièrement sexy, mais il devrait fonctionner dans tous les cas, pour tous les utilisateurs.

7
répondu Aeyoun 2015-11-19 19:17:11

utiliser valueAsNumber au lieu de .val() .

"151970920 d'entrée". valueAsNumber [=value ]

renvoie un nombre représentant la valeur du contrôle de formulaire, s'il y a lieu; sinon, renvoie null.

Peut être défini, pour modifier la valeur.

Lance une exception INVALID_STATE_ERR si le contrôle n'est ni basé sur la date, ni sur le temps, ni numérique.

6
répondu Mike Samuel 2013-03-08 21:55:25

Je n'ai pas trouvé de solution parfaite mais le mieux que je pouvais faire était d'utiliser type="tel" et désactiver la validation html5 (formnovalidate):

<input name="txtTest" type="tel" value="1,200.00" formnovalidate="formnovalidate" />

si l'utilisateur met dans une virgule, Il sortira avec la virgule dans chaque navigateur moderne que j'ai essayé (dernier FF, IE, edge, opera, chrome, safari desktop, Android chrome).

le problème principal est:

  • les utilisateurs mobiles verront leur clavier de téléphone qui peut être différent que le nombre de clavier.
  • pire encore, le clavier du téléphone peut ne pas avoir de clé pour une virgule.

pour mon cas d'utilisation j'ai seulement eu à:

  • afficher la valeur initiale avec une virgule (firefox la supprime pour type=Nombre)
  • Pas l'échec de la validation html5 (si il y a une virgule)
  • faire lire le champ exactement comme entrée (avec une virgule possible)

Si vous avez une exigence semblable, cela devrait fonctionner pour vous.

Note: Je n'ai pas aimé le support de l'attribut pattern. Le formnovalidate semble fonctionner beaucoup mieux.

2
répondu Bolo 2016-04-05 23:14:58

quand vous appelez $("#my_input").val(); il retourne comme variable string. Ainsi, utilisez parseFloat et parseInt pour la conversion. Lorsque vous utilisez parseFloat votre bureau ou téléphone lui-même comprend le sens de variable.

et plus vous pouvez convertir un flottant en chaîne en utilisant toFixed qui a un argument le nombre de chiffres comme ci-dessous:

var i = 0.011;
var ss = i.toFixed(2); //It returns 0.01
1
répondu 2015-12-17 08:53:29

ma recommandation? Ne pas utiliser jQuery. J'ai eu le même problème que vous. J'ai trouvé que $('#my_input').val() donne toujours des résultats bizarres.

essayez d'utiliser document.getElementById('my_input').valueAsNumber au lieu de $("#my_input").val(); et ensuite, utilisez 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, c'est quand vous écrivez un numéro à l'entrée, l'entrée de l'accepter 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, qui permet à vos utilisateurs d'ajouter l'internationalisation (i.e.: des virgules au lieu de points pour créer des nombres décimaux). Il suffit de laisser l'objet Number() créer quelque chose pour vous et il sera décimal-sûr, pour ainsi dire.

0
répondu Patrick D'appollonio 2013-04-04 21:33:02

sonne comme si vous vouliez utiliser toLocaleString() sur vos entrées numériques.

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

de la Localisation des numéros dans le JS est également couvert de l'Internationalisation(Numéro de mise en forme "num.toLocaleString ()") non travaillé pour chrome

0
répondu stackasec 2017-05-23 12:18:07