Как обрабатывать поплавки и десятичные разделители с номером типа ввода html5

Im создание веб-приложения, которое в основном предназначено для мобильных браузеров. Im использует поля ввода с типом номера, поэтому (большинство) мобильных браузеров вызывают только цифровую клавиатуру для лучшего удобства пользователя. Это веб-приложение в основном используется в регионах, где десятичный разделитель является запятой, а не точкой, поэтому мне нужно обрабатывать оба десятичных разделителя.

Как покрыть весь этот беспорядок точкой и запятой?

Мои выводы:

Настольный Chrome

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

Настольный Firefox

  • Тип ввода = номер
  • Пользователь вводит "4,55" для ввода поля
  • $("#my_input").val(); возвращает "4,55"
  • Thats fine, я могу заменить запятую точкой и получить правильный float

Android-браузер

  • Тип ввода = номер
  • Пользователь вводит "4,55" для ввода поля
  • Когда вход теряет фокус, значение усекается до "4"
  • Смущение пользователю

Телефон Windows 8

  • Тип ввода = номер
  • Пользователь вводит "4,55" для ввода поля
  • $("#my_input").val(); возвращает "4,55"
  • Thats fine, я могу заменить запятую точкой и получить правильный float

Каковы "лучшие практики" в таких ситуациях, когда пользователь может использовать запятую или точку в качестве разделителя десятичных чисел, и я хочу сохранить тип ввода html как число, чтобы обеспечить лучший пользовательский интерфейс?

Могу ли я преобразовать запятую в точку "на лету", связав ключевые события, работает ли она с вводами цифр?

ИЗМЕНИТЬ

Currenlty У меня нет никакого решения, как получить значение float (как строку или число) от ввода, тип которого установлен в число. Если enduser входит в "4,55" , Chrome возвращается всегда "455", Firefox возвращает "4,55" , что хорошо.

Также довольно неприятно, что в Android (протестированный 4.2 эмулятор), когда я ввожу "4,55" в поле ввода и меняю фокус на другое место, введенное число обрезается до "4".

Ответ 1

Я думаю, что в приведенных выше ответах нет необходимости указывать другое значение для атрибута 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 для извлечения значения, но вам будет полезно использовать DOM API напрямую, чтобы получить свойство validity.valid.

У меня была аналогичная проблема с десятичной точкой, но причина, по которой я понял, что проблема была связана с тем, что Twitter Bootstrap добавляет номер ввода с недопустимым значением.

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

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

ПРИМЕЧАНИЕ: запятая не проверяет для меня, но я подозреваю, что если я установил настройки языка/региона ОС где-нибудь, где используется запятая в качестве разделителя с разделителями, это сработает. * примечание в примечании *: это не относится к настройкам языка ОС и клавиатуры * Немецкий * в Ubuntu/Gnome 14.04.

Ответ 2

Согласно w3.org атрибут value ввода номера определяется как число с плавающей запятой. Синтаксис числа с плавающей запятой, по-видимому, принимает только точки в виде десятичных разделителей.

Я привел несколько вариантов ниже, которые могут вам помочь:

1. Использование атрибута pattern

С помощью атрибута pattern вы можете указать разрешенный формат с регулярным выражением в формате 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."/>

Ответ 3

Используйте valueAsNumber вместо .val().

вход. valueAsNumber [= значение]

Возвращает число, представляющее значение управления формой, если это применимо; в противном случае возвращает null.
Может быть установлено, чтобы изменить значение.
Выдает исключение INVALID_STATE_ERR, если элемент управления не имеет ни даты, ни времени, ни числа.

Ответ 4

Использовать ли запятую или период для десятичного разделителя полностью зависит от браузера. Браузер принимает решение на основе локали операционной системы или браузера, или некоторые браузеры получают подсказки с веб-сайта. Я сделал сравнительная таблица браузера, в которой показано, как разные браузеры поддерживают различные методы локализации. Safari является единственным браузером, который обрабатывает запятые и периоды взаимозаменяемо.

В принципе, вы, как автор сети, не можете это контролировать. Некоторые работы включают использование двух полей ввода с целыми числами. Это позволяет каждому пользователю вводить данные как ожидаемые. Это не особая сексуальность, но она будет работать в каждом случае для всех пользователей.

Ответ 5

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

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

Если пользователь помещает в запятую, он будет выводиться с запятой в каждом современном браузере, который я пробовал (последние FF, IE, край, опера, хром, рабочий стол для сафари, android chrome).

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

  • Мобильные пользователи будут видеть свою телефонную клавиатуру, которая может быть разной чем клавиатура с номером.
  • Еще хуже, что клавиатура телефона даже не имеет ключа для запятой.

В моем случае использования я должен был:

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

Если у вас есть аналогичное требование, это должно сработать для вас.

Примечание. Мне не понравилась поддержка атрибута pattern. Формановалид, кажется, работает намного лучше.

Ответ 6

Когда вы вызываете $("#my_input").val();, он возвращается как строковая переменная. Поэтому используйте parseFloat и parseInt для преобразования. Когда вы используете parseFloat, ваш рабочий стол или телефон ITSELF понимает значение переменной.

И плюс вы можете преобразовать float в строку с помощью toFixed, у которого есть аргумент, количество цифр, как показано ниже:

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

Ответ 7

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

Попробуйте использовать document.getElementById('my_input').valueAsNumber вместо $("#my_input").val();, а затем используйте Number(your_value_retrieved), чтобы попытаться создать Number. Если значение NaN, вы наверняка знаете, что это не номер.

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

Oh и BTW, что позволяет вашим пользователям добавлять интернационализацию (например: вспомогательные запятые вместо точек для создания десятичных чисел). Просто пусть объект Number() создает что-то для вас, и он будет, следовательно, десятичным.

Ответ 8

Похоже, вы хотели бы использовать toLocaleString() на числовых входах.

См. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString для его использования.

Локализация чисел в JS также рассматривается в Интернационализация (форматирование номера "num.toLocaleString()" ) не работает для chrome

Ответ 9

использует тип текста, но вызывает появление цифровой клавиатуры

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

тег inputmode является решением