web-dev-qa-db-fra.com

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

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

Comment couvrir tout ce gâchis avec des points et des virgules?

Mes découvertes:

Desktop Chrome

  • Type d'entrée = nombre
  • L'utilisateur entre "4,55" dans le champ de saisie
  • $("#my_input").val(); renvoie "455"
  • Je ne peux pas obtenir la valeur correcte de l'entrée

Desktop Firefox

  • Type d'entrée = nombre
  • L'utilisateur entre "4,55" dans le champ de saisie
  • $("#my_input").val(); renvoie "4,55"
  • Ça va, je peux remplacer une virgule par un point et obtenir un float correct

navigateur Android

  • Type d'entrée = nombre
  • L'utilisateur entre "4,55" dans le champ de saisie
  • Lorsque l'entrée perd le focus, la valeur est tronquée à "4"
  • Déroutant pour l'utilisateur

Windows Phone 8

  • Type d'entrée = nombre
  • L'utilisateur entre "4,55" dans le champ de saisie
  • $("#my_input").val(); renvoie "4,55"
  • Ça va, je peux remplacer une virgule par un point et obtenir un float 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 sous forme de nombre, pour offrir une meilleure expérience utilisateur?

Puis-je convertir une virgule en point "à la volée", en reliant les événements clés, fonctionne-t-il avec des entrées numériques?

MODIFIER

Currenlty Je n'ai pas de solution, comment obtenir une valeur float (sous forme de chaîne ou nombre) à partir d'une entrée dont le type est défini sur nombre. Si l'utilisateur final entre "4,55", Chrome renvoie toujours "455", Firefox renvoie "4,55", ce qui est correct.

En outre, il est assez ennuyant que dans Android (émulateur testé 4.2), lorsque je saisis "4,55" dans le champ de saisie et que je change le focus, le nombre entré est tronqué à "4".

118
devha

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 en virgule flottante, spécifiez une étape en conséquence.

Par exemple, je voulais des montants en dollars, alors 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 trouverez utile d'utiliser l'API DOM directement pour obtenir la propriété validity.valid de l'élément.

J'avais un problème similaire avec le point décimal, mais la raison pour laquelle j'ai compris qu'il y avait un problème était dû au style que Twitter Bootstrap ajoute à une entrée numérique avec une valeur non valide.

Voici un violon démontrant que l'ajout de l'attribut step le fait fonctionner et testant également la validité de la valeur actuelle:

TL; DR: Définit l'attribut a step sur une valeur à virgule flottante, car sa valeur par défaut est 1.

NOTE: la virgule ne se valide pas pour moi, mais je soupçonne que si je règle la langue/la région de mon système d'exploitation paramètres à un endroit qui utilise une virgule comme séparateur décimal, cela fonctionnerait. * note en note *: ce n'était pas le cas pour les paramètres de langue/clavier du système d'exploitation * allemand * dans Ubuntu/Gnome 14.04.

102
natchiketa

Selon w3.org, l'attribut valeur de entrée de nombre 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 vous être utiles:

1. Utiliser l'attribut pattern

Avec l'attribut motif, vous pouvez spécifier le format autorisé avec une expression régulière de manière compatible avec HTML5. Ici, vous pouvez spécifier que la virgule est autorisée et un message de retour d'information utile en cas d'échec du modèle.

<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."/>

Remarque: La prise en charge multi-navigateurs varie beaucoup. Il peut être complet, partiel ou inexistant.

2. Validation JavaScript

Vous pouvez essayer de lier un simple rappel à, par exemple, l'événement onchange (et/ou flo) qui remplacerait la virgule ou validerait l'ensemble.

3. Désactiver la validation du navigateur ##

Troisièmement, vous pouvez essayer d'utiliser l'attribut 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."/>
22
kjetilh

L'utilisation de virgules ou de points pour le séparateur décimal dépend entièrement du navigateur. Le navigateur prend sa décision en fonction des paramètres régionaux du système d'exploitation ou du navigateur, ou certains navigateurs s'inspirent du site Web. J'ai fait un tableau de comparaison de navigateurs montrant comment différents navigateurs prennent en charge différentes méthodes de localisation. Safari étant le seul navigateur qui gère les virgules et les points de manière interchangeable.

En tant qu'auteur Web, vous ne pouvez vraiment pas contrôler cela. Certains contournements impliquent l’utilisation de deux champs d’entrée avec des entiers. Cela permet à chaque utilisateur de saisir les données comme vous le souhaitez. Ce n'est pas particulièrement sexy, mais cela fonctionnera dans tous les cas pour tous les utilisateurs.

8
Aeyoun

Utilisez valueAsNumber au lieu de .val().

contribution . valueAsNumber [= valeur]

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.
Envoie une exception INVALID_STATE_ERR si le contrôle n'est pas basé sur la date ou l'heure, ni numérique.

7
Mike Samuel

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

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

Si l'utilisateur met une virgule, il l'utilisera dans tous les navigateurs modernes que j'ai essayés (derniers fichiers FF, IE, Edge, Opéra, Chrome, Bureau Safari, Android Chrome).

Le problème principal est:

  • Les utilisateurs mobiles verront le clavier de leur téléphone qui peut être différent du clavier numérique.
  • Pire encore, le clavier du téléphone peut même ne pas avoir de clé pour une virgule.

Pour mon cas d'utilisation, je n'avais qu'à:

  • Afficher la valeur initiale avec une virgule (firefox la supprime pour type = nombre)
  • Ne ratez pas la validation html5 (s'il y a une virgule)
  • Avoir le champ lu exactement comme entrée (avec une virgule possible)

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

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

3
Bolo

utilise un type de texte mais force l'apparition du clavier numérique

<input value="12,4" type="text" inputmode="numeric" pattern="[-+]?[0-9]*[.,]?[0-9]+">

la balise inputmode est la solution

2
David Navarro

Lorsque vous appelez $("#my_input").val();, il renvoie une variable chaîne. Donc, utilisez parseFloat et parseInt pour la conversion. Lorsque vous utilisez parseFloat votre bureau ou votre téléphone LUI-MÊME comprend la signification de variable.

Et en plus, vous pouvez convertir un float en chaîne en utilisant toFixed qui a comme argument le nombre de chiffres indiqué ci-dessous:

var i = 0.011;
var ss = i.toFixed(2); //It returns 0.01
1
user3511843

On dirait que vous voudriez 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 utilisation.

La localisation des nombres dans JS est également couverte par Internationalisation (le formatage de nombre "num.toLocaleString ()") ne fonctionne pas pour chrome

0
stackasec

Ma recommandation? N'utilisez pas du tout jQuery. J'ai eu le même problème que toi. J'ai trouvé que $('#my_input').val() renvoie toujours des résultats étranges.

Essayez d'utiliser document.getElementById('my_input').valueAsNumber au lieu de $("#my_input").val();, puis 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 est que lorsque vous écrivez un nombre sur l’entrée, celle-ci accepte presque tous les caractères (je peux écrire le symbole de l’euro, un dollar et tous les autres caractères spéciaux). Il est donc préférable de récupérer la valeur à l’aide de .valueAsNumber au lieu d'utiliser jQuery.

Oh, et BTW, cela permet à vos utilisateurs d’ajouter une internationalisation (par exemple: des virgules de support au lieu de points pour créer des nombres décimaux). Laissez simplement l'objet Number() créer quelque chose pour vous et il sera décimal-safe, pour ainsi dire.

0