Як обробляти поплавці та десяткові роздільники за допомогою номера типу введення html5


128

Я будую веб-додаток, в основному для мобільних браузерів. Я використовую поля введення з типом номера, тому (більшість) мобільних браузерів використовує лише цифрову клавіатуру для кращого користування. Цей веб-додаток використовується в основному в регіонах, де десятковий роздільник є комою, а не крапкою, тому мені потрібно обробляти обидва десяткових роздільника.

Як прикрити весь цей безлад крапкою і комою?

Мої висновки:

Настільний Chrome

  • Тип вводу = число
  • Користувач вводить "4,55" у поле введення
  • $("#my_input").val(); повертає "455"
  • Я не можу отримати правильне значення з введення

Настільний Firefox

  • Тип вводу = число
  • Користувач вводить "4,55" у поле введення
  • $("#my_input").val(); повертає "4,55"
  • Це добре, я можу замінити кому крапкою і отримати правильний поплавок

Браузер Android

  • Тип вводу = число
  • Користувач вводить "4,55" у поле введення
  • Коли вхід втрачає фокус, значення скорочується до "4"
  • Конфуз для користувача

Windows Phone 8

  • Тип вводу = число
  • Користувач вводить "4,55" у поле введення
  • $("#my_input").val(); повертає "4,55"
  • Це добре, я можу замінити кому крапкою і отримати правильний поплавок

Які "найкращі практики" в подібних ситуаціях, коли користувач може використовувати коску або крапку як десятковий роздільник, і я хочу зберегти тип введення html як число, щоб забезпечити кращу роботу користувачів?

Чи можу я перетворити кому в крапку "на льоту", прив'язуючи ключові події, чи працює вона з введеннями чисел?

EDIT

Currenlty У мене немає рішення, як отримати значення float (як рядок або число) з введення, тип якого встановлений на число. Якщо ендузер вводить "4,55", Chrome повертає завжди "455", Firefox повертає "4,55", що нормально.

Також дуже дратує те, що в Android (перевірений емулятор 4.2), коли я ввожу "4,55" для поля введення та змінюю фокус на інше, введене число стає усіченим на "4".


Моя здогадка, що є першопричиною деяких ваших проблем, полягає в тому, що браузери встановлені на місцевості в США, яка використовує крапку як десятковий роздільник. Схоже, що Chrome і Android через це плутають різні способи - Chrome трактує кому як роздільник цифр, потім перетворює вхід у число, потім знову перетворює його на рядок .val(), а Android робить щось дивне. Чи можете ви перевірити, чи поводяться вони однаково, коли ви встановите системну мову на щось відповідне?
мільмозу

1
Nvm опублікував це як відповідь
kjetilh

Дивіться також тут: stackoverflow.com/a/24423879/196210
Revious

Ситуація ще гірша, ніж ви зображували: ви отримуєте десяткову крапку або кому на цифровій панелі WP залежно від мови, на якій ви вибрали клавіатуру. Також немає способу дізнатися, яка була вхідна мова (не обов'язково бажана мова браузера) ... Тож найкраще, що я міг би придумати (і що для мене досить добре), це: var number = $(...).get(0).valueAsNumber; if (isNaN(number)) number = parseFloat($(...).val().replace(',', '.'); Але це рішення працює лише в тому випадку, коли число, яке було введено, містить лише 1
коску,

Відповіді:


107

Я думаю, що у відповідях вище не вистачає необхідності вказати інше значення для stepатрибута, яке має значення за замовчуванням 1. Якщо ви хочете, щоб алгоритм перевірки на вході дозволяв значення з плаваючою комою, відповідно вкажіть крок.

Наприклад, я хотів суми в доларах, тому я вказав такий крок:

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

Немає нічого поганого в тому, щоб використовувати jQuery для отримання значення, але вам буде корисно використовувати API DOM безпосередньо для отримання validity.validвластивості елементів .

У мене була схожа проблема з десятковою крапкою, але причина, коли я зрозумів, що виникла проблема, пов’язана із стилем, який Twitter Bootstrap додає до введення числа з недійсним значенням.

Ось загадка, яка демонструє, що додавання stepатрибуту змушує його працювати, а також перевіряє, чи є поточне значення дійсним:

TL; DR: встановіть stepатрибут на значення з плаваючою комою, оскільки він за замовчуванням 1.

ПРИМІТКА . Кома для мене не підтверджується, але я підозрюю, що якби я встановив налаштування мови / регіону ОС десь, де використовується кома як десятковий роздільник, вона буде працювати. * Примітка у примітці *: це не стосувалося мови / налаштувань клавіатури * Німецька * в Ubuntu / Gnome 14.04.


8
Якщо ви хочете дозволити довільно багато десяткових знаків, вкажіть stepатрибут як, "any"наприклад, "0.01"як показано тут. Дивіться цю перероблену версію загадки nathciketa для демонстрації.
Марк Амері

4
Я також стикався з проблемами з комами, що не підтверджують, хоча я вводив "1,234,56" <input type="number" step="any">. Мені не вдалося знайти спосіб вимкнути перевірку HTML5. Я можу вимкнути або налаштувати повідомлення про помилку, але отримання значень із вхідних даних - це завжди crapshoot. Будь-які ідеї?
Нік Г.

5
This attribute applies when the value of the type attribute is text, search, tel, url, email, or password, otherwise it is ignored.Тож візерунок марнийtype="number"
Майкл Лаффарг

як сказав Майкл, будь ласка, змініть typeна text, інакше ваша відповідь не має сенсу.
phil294

23

Відповідно до w3.org атрибут значення вводу числа визначається як число з плаваючою комою . Синтаксис числа з плаваючою комою, здається, приймає лише крапки як десяткові роздільники.

Я перерахував кілька варіантів нижче, які можуть бути корисними для вас:

1. Використання атрибута шаблону

За допомогою атрибуту шаблону ви можете вказати дозволений формат із регулярним виразом сумісним чином HTML5. Тут ви можете вказати, що символ кома дозволений і корисне повідомлення зворотного зв’язку, якщо шаблон не вдається.

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

Примітка. Підтримка крос-браузера дуже різниться Він може бути повним, частковим або неіснуючим ..

2. Перевірка JavaScript

Ви могли б спробувати пов'язати простий зворотний виклик, наприклад , на OnChange (і / або розмитість події ), яка б замінила кому або перевірила всі разом.

3. Вимкнути перевірку браузера ##

По-третє, ви можете спробувати використовувати атрибут formnovalidate на числових введеннях з метою вимкнути перевірку веб-переглядача для цього поля разом.

<input type="number" formnovalidate />

4. Комбінація ..?

<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
input.valueAsNumber - Немає допомоги, оскільки це працює лише з крапками в якості десяткового роздільника, і в моєму випадку enduser може використовувати крапку або кому. Тег форми недійсний - Не знайшли жодного впливу на це.
devha

На жаль, у мене не вистачає ідей, тому я не впевнений, чи зможете ви зробити цю роботу крос-браузером без рішення рішення. Я оновив свою відповідь, щоб включити атрибут шаблону. Я також виявив, що можна використовувати атрибут formnovalidate безпосередньо у полях введення. Я знаю, що вам це не сподобається, але якщо все не вдасться і вам абсолютно потрібні коми, то введення = "текст" може бути єдиним способом ..
kjetilh

Схоже, що номер типу вводу створює більше проблем, ніж насправді покращує користувацький досвід. У мобільному пристрої було б чудово, якщо я можу відкрити користувачеві лише цифрову клавіатуру, якщо хочу, щоб вони вводили просто цифри. У будь-якому разі мені потрібно це ще раз подумати ...
devha

Оскільки нам також потрібно підтримувати використання як крапки, так і коми через десятковий роздільник, ми плануємо використовувати шаблон для перевірки на робочому столі в поєднанні з type = "text". Тоді ми додамо функцію виявлення функцій для виявлення мобільного пристрою та використовуватимемо type = "number", коли це застосовується.
трепет

9

Чи використовувати коску або крапку для десяткового роздільника, повністю залежить від браузера. Веб-переглядач приймає рішення на основі локальної операційної системи чи браузера, або деякі браузери беруть підказки з веб-сайту. Я зробив діаграму порівняння браузера, яка показує, як різні веб-переглядачі підтримують різні методи локалізації. Safari є єдиним браузером, який обробляє коми та крапки взаємозамінно.

По суті, ви як веб-автор справді не можете це контролювати. Деякі робочі кола передбачають використання двох полів введення з цілими числами. Це дозволяє кожному користувачеві вводити дані так, як очікували. Це не особливо сексуально, але він буде працювати у кожному випадку для всіх користувачів.


7

Використовуйте valueAsNumberзамість .val().

вхід. valueAsNumber [= значення]

Повертає число, що представляє значення контролю форми, якщо це застосовується; в іншому випадку повертається null.
Можна встановити, змінити значення.
Викидає виняток INVALID_STATE_ERR, якщо елемент керування не є ні датою, ні часом, ні числовим числом.


2
Проблема полягає в тому, що він хоче підтримувати кому як десятковий роздільник, а використовуючи type = "number" на вході, завжди призначає недійсне число під час написання коми.
трепет

Здається, не працює стабільно на Windows Phone; завжди повертається NaN.
bert bruynooghe

@bertbruynooghe, що ви призначаєте як значення?
Майк Самуель

Схоже, це не працює, як із «9», «9,1», «9.1». Телефон налаштований як американський, розкладені клавіатури в США, nl-BE.
bert bruynooghe

4

використовує тип тексту, але змушує виглядати цифрову клавіатуру

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

рішення тегу inputmode - це рішення


Але це не сумісно з усіма браузерами, лише з останніми версіями iOS Safari, Chrome, Chromium, Opera ... caniuse.com/#feat=input-inputmode :(
pgarciacamou

Крім того, ви не отримуєте цю акуратну клавіатуру на мобільних пристроях.
WoIIe

3

Я не знайшов ідеального рішення, але найкраще, що я міг би зробити, це використовувати type = "tel" та відключити перевірку html5 (formnovalidate):

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

Якщо користувач введе кому, він виводитиме кому з кожного сучасного браузера, який я пробував (останні FF, IE, край, опера, хром, сафарі на робочому столі, андроїд хром).

Основна проблема:

  • Користувачі мобільних пристроїв побачать клавіатуру телефону, яка може відрізнятися від цифрової клавіатури.
  • Ще гірше, що клавіатура телефону може навіть не мати клавіші для коми.

Для мого використання я повинен був:

  • Показуйте початкове значення комою (firefox викреслює його для типу = число)
  • Не пропустити перевірку html5 (якщо є кома)
  • Нехай поле читається точно як вхідне (з можливою комою)

Якщо у вас є подібні вимоги, це повинно працювати для вас.

Примітка: мені не сподобалася підтримка атрибута шаблону. Здається, формановалідат працює набагато краще.


1

При виклику $("#my_input").val();він повертається у вигляді змінної рядка. Тож використовуйте parseFloatі parseIntдля перетворення. Під час використання parseFloatробочого столу чи телефону ITSELF розуміє значення змінної.

І плюс ви можете перетворити поплавок на рядок, використовуючи toFixedякий має аргумент кількість цифр, як показано нижче:

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

Не працює. Спробуйте parseFloat ("1,5") в IE11. Повернення 1. Мова є німецькою і для ОС, і для IE.
T3rm1

1

У веб-переглядачів, як і раніше, виникають проблеми (хоча Chrome і Firefox Nightly працюють нормально). У мене є хиткий підхід до людей, яким дійсно доведеться використовувати числове поле (можливо, через маленькі стрілки, яких не мають текстові поля).

Моє рішення

Я додав keyupобробник подій до введення форми і відстежував стан і встановлював значення, як тільки воно знову стає дійсним.

Чистий JS Snippet JSFIDDLE

Кутовий 9 знімок


0

Моя рекомендація? Не використовуйте jQuery взагалі. У мене була така ж проблема, як у вас. Я виявив, що $('#my_input').val()завжди повертає якийсь дивний результат.

Спробуйте використовувати document.getElementById('my_input').valueAsNumberзамість, $("#my_input").val();а потім, використовуйте, Number(your_value_retrieved)щоб спробувати створити число. Якщо значення NaN, ви точно знаєте, що це не число.

Одне, що потрібно додати, - це коли ви пишете число на вході, фактично буде приймати практично будь-який символ (я можу написати знак євро, долар та всі інші спеціальні символи), тому найкраще отримати значення за допомогою .valueAsNumberзамість використання jQuery.

О, і BTW, що дозволяє вашим користувачам додавати інтернаціоналізацію (тобто: підтримувати коми замість крапок для створення десяткових чисел). Просто дозвольте Number()об'єкту створити щось для вас, і це буде безпечно для десятків, так би мовити.


Проблема не викликана jQuery, і я вважаю, що valueAsNumberвона також не працює послідовно у веб-переглядачах.
bert bruynooghe

0

Здається, ви хочете використовувати toLocaleString () на цифрових входах.

Див. Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString щодо його використання.

Локалізація чисел у JS також охоплюється в інтернаціоналізації (форматування чисел "num.toLocaleString ()"), що не працює для хромування


2
Зазвичай, щоб дати більше пояснень для рішення, навіть якщо відповідь, якщо повністю охоплена пов'язаним вмістом.
ІванХ

Цей підхід здається кращим, ніж інші підходи, якщо сервер із зворотним кінцем визначає локаль, а не сам браузер. На жаль, toLocaleStringне є надійним для всіх платформ.
bert bruynooghe

Підтримка крос-платформи здається мені досить широкою у 2015 році, див., Наприклад, Mozillas Devnet . Однак якщо це все ще хвилює вас, знайдіть можливі рішення тут.
stackasec

Mozillas Devnet майже не демонструє сумісності для мобільних браузерів, і саме там числове текстове поле може запропонувати більшість переваг. (Див. Оригінальне запитання.)
bert bruynooghe

... і було запропоновано та посилається більше, ніж достатньо альтернатив. Весело.
stackasec
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.