Estoy construyendo una aplicación web que es principalmente para navegadores móviles. Estoy usando campos de entrada con tipo de número, por lo que (la mayoría) los navegadores móviles invocan solo el teclado numérico para una mejor experiencia del usuario. Esta aplicación web se usa principalmente en regiones donde el separador decimal es una coma, no un punto, por lo que necesito manejar ambos separadores decimales.
¿Cómo cubrir todo este desastre con punto y coma?
Mis hallazgos:
Chrome de escritorio
- Tipo de entrada = número
- El usuario ingresa "4,55" al campo de entrada
$("#my_input").val();
devuelve "455"- No puedo obtener el valor correcto de la entrada
Desktop Firefox
- Tipo de entrada = número
- El usuario ingresa "4,55" al campo de entrada
$("#my_input").val();
devuelve "4,55"- Está bien, puedo reemplazar la coma con un punto y obtener el flotador correcto
Navegador de Android
- Tipo de entrada = número
- El usuario ingresa "4,55" al campo de entrada
- Cuando la entrada pierde el foco, el valor se trunca a "4"
- Confuso para el usuario
Windows Phone 8
- Tipo de entrada = número
- El usuario ingresa "4,55" al campo de entrada
$("#my_input").val();
devuelve "4,55"- Está bien, puedo reemplazar la coma con un punto y obtener el flotador correcto
¿Cuáles son las "mejores prácticas" en este tipo de situaciones en las que el usuario puede usar coma o punto como separador decimal y quiero mantener el tipo de entrada html como número, para proporcionar una mejor experiencia de usuario?
¿Puedo convertir una coma en punto "sobre la marcha", vinculando eventos clave, ¿funciona con entradas numéricas?
EDITAR
Actualmente no tengo ninguna solución, cómo obtener un valor flotante (como cadena o número) de la entrada cuyo tipo se establece en número. Si el usuario final ingresa "4,55", Chrome devuelve siempre "455", Firefox devuelve "4,55", lo cual está bien.
También es bastante molesto que en Android (probado el emulador 4.2), cuando ingreso "4,55" para ingresar el campo y cambio el foco a otro lugar, el número ingresado se trunca a "4".
.val()
y Android hace algo extraño. ¿Puede verificar si se comportan igual cuando configura el idioma del sistema en algo apropiado?var number = $(...).get(0).valueAsNumber;
if (isNaN(number)) number = parseFloat($(...).val().replace(',', '.');
Pero esa solución solo funciona si el el número que se ha introducido solo contiene 1 coma y ningún punto extra ...Respuestas:
Creo que lo que falta en las respuestas anteriores es la necesidad de especificar un valor diferente para el
step
atributo, que tiene un valor predeterminado de1
. Si desea que el algoritmo de validación de entrada permita valores de punto flotante, especifique un paso en consecuencia.Por ejemplo, quería cantidades en dólares, así que especifiqué un paso como este:
No hay nada de malo en usar jQuery para recuperar el valor, pero le resultará útil usar la API DOM directamente para obtener la
validity.valid
propiedad de los elementos .Tuve un problema similar con el punto decimal, pero la razón por la que me di cuenta de que había un problema fue por el estilo que Twitter Bootstrap agrega a una entrada de número con un valor no válido.
Aquí hay un violín que demuestra que la adición del
step
atributo lo hace funcionar y también prueba si el valor actual es válido:TL; DR: establece el
step
atributo a un valor de punto flotante, ya que su valor predeterminado es1
.NOTA : La coma no es válida para mí, pero sospecho que si configuro la configuración de idioma / región del sistema operativo en algún lugar que use una coma como separador decimal, funcionaría. * nota en nota *: ese no era el caso para la configuración del idioma / teclado del sistema operativo * alemán * en Ubuntu / Gnome 14.04.
fuente
step
atributo como en"any"
lugar de, por ejemplo,"0.01"
como se muestra aquí. Vea esta versión modificada del violín de nathciketa para una demostración.<input type="number" step="any">
. No he podido encontrar una manera de desactivar la validación HTML5. Puedo desactivar o personalizar el mensaje de error, pero recuperar el valor de la entrada siempre es una trampa. ¿Algunas ideas?This attribute applies when the value of the type attribute is text, search, tel, url, email, or password, otherwise it is ignored.
Así que el patrón no sirve para nadatype="number"
type
atext
, de lo contrario su respuesta no tiene sentido.Según w3.org, el atributo de valor de la entrada numérica se define como un número de coma flotante . La sintaxis del número de coma flotante parece aceptar solo puntos como separadores decimales.
He enumerado algunas opciones a continuación que pueden serle útiles:
1. Usando el atributo de patrón
Con el atributo de patrón , puede especificar el formato permitido con una expresión regular de manera compatible con HTML5. Aquí puede especificar que el carácter de coma está permitido y un mensaje de respuesta útil si el patrón falla.
Nota: la compatibilidad entre navegadores varía mucho. Puede ser completo, parcial o inexistente.
2. Validación de JavaScript
Podría intentar vincular una devolución de llamada simple, por ejemplo, al evento onchange (y / o blur ) que reemplazaría la coma o la validaría por completo.
3. Deshabilitar la validación del navegador ##
En tercer lugar, podría intentar utilizar el atributo formnovalidate en las entradas numéricas con la intención de deshabilitar la validación del navegador para ese campo por completo.
4. Combinación ..?
fuente
El uso de coma o punto para el separador decimal depende completamente del navegador. El navegador toma una decisión basada en la configuración regional del sistema operativo o navegador, o algunos navegadores toman pistas del sitio web. Hice una tabla de comparación de navegadores que muestra cómo los diferentes navegadores admiten diferentes métodos de localización. Safari es el único navegador que maneja comas y puntos de manera intercambiable.
Básicamente, usted como autor web no puede controlar esto realmente. Algunas soluciones implican el uso de dos campos de entrada con enteros. Esto permite que cada usuario ingrese los datos como espera. No es particularmente sexy, pero funcionará en todos los casos para todos los usuarios.
fuente
Usar en
valueAsNumber
lugar de.val()
.fuente
NaN
.usa un tipo de texto pero fuerza la apariencia del teclado numérico
la etiqueta inputmode es la solución
fuente
No he encontrado una solución perfecta, pero lo mejor que pude hacer fue usar type = "tel" y deshabilitar la validación html5 (formnovalidate):
Si el usuario pone una coma, saldrá con la coma en todos los navegadores modernos que probé (último FF, IE, edge, opera, chrome, safari desktop, android chrome).
El problema principal es:
Para mi caso de uso solo tuve que:
Si tiene un requisito similar, esto debería funcionar para usted.
Nota: no me gustó el soporte del atributo de patrón. El formnovalidate parece funcionar mucho mejor.
fuente
Cuando lo llamas
$("#my_input").val();
vuelve como variable de cadena. Así que usaparseFloat
yparseInt
para convertir. Cuando usaparseFloat
su computadora de escritorio o teléfono, SÍ MISMO comprende el significado de variable.Y además, puede convertir un flotador en una cadena mediante el
toFixed
cual tiene un argumento el recuento de dígitos como se muestra a continuación:fuente
Aparentemente, los navegadores todavía tienen problemas (aunque Chrome y Firefox Nightly funcionan bien). Tengo un enfoque hacky para las personas que realmente tienen que usar un campo numérico (tal vez debido a las pequeñas flechas que los campos de texto no tienen).
Mi solución
Agregué un
keyup
controlador de eventos a la entrada del formulario y rastreé el estado y configuré el valor una vez que vuelve a ser válido.Fragmento JS puro JSFIDDLE
Mostrar fragmento de código
Fragmento angular 9
Mostrar fragmento de código
fuente
¿Mi recomendación? No use jQuery en absoluto. Yo tenía el mismo problema que tú. Encontré que
$('#my_input').val()
siempre devuelve algún resultado extraño.Intente usar en
document.getElementById('my_input').valueAsNumber
lugar de$("#my_input").val();
y luego, useNumber(your_value_retrieved)
para intentar crear un Número. Si el valor es NaN, seguramente sabe que no es un número.Una cosa para agregar es que cuando escribe un número en la entrada, la entrada aceptará casi cualquier carácter (puedo escribir el símbolo del euro, un dólar y todos los demás caracteres especiales), por lo que es mejor recuperar el valor usando
.valueAsNumber
en lugar de usar jQuery.Ah, y por cierto, eso permite a sus usuarios agregar internacionalización (es decir: admite comas en lugar de puntos para crear números decimales). Simplemente deje que el
Number()
objeto cree algo para usted y será decimal seguro, por así decirlo.fuente
valueAsNumber
tampoco funciona de manera consistente en los navegadores.Parece que le gustaría usar toLocaleString () en sus entradas numéricas.
Ver https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString para su uso.
La localización de números en JS también está cubierta en Internacionalización (el formato de número "num.toLocaleString ()") no funciona para Chrome
fuente
toLocaleString
no es confiable en todas las plataformas.