Как получить необработанное значение поля <input type = «number»>?

117

Как я могу получить «реальное» значение <input type="number">поля?


У меня есть inputкоробка, и я использую новый тип ввода HTML5 number:

<input id="edQuantity" type="number">

В основном это поддерживается в Chrome 29:

введите описание изображения здесь

Что мне теперь нужно, так это возможность читать «сырое» значение, введенное пользователем в поле ввода. Если пользователь ввел номер:

введите описание изображения здесь

тогда edQuantity.value = 4и все хорошо.

Но если пользователь вводит недопустимый текст, я хочу покрасить поле ввода красным цветом:

введите описание изображения здесь

К сожалению, для type="number"поля ввода, если значение в текстовом поле не является числом, valueвозвращается пустая строка:

edQuantity.value = "" (String);

(как минимум в Chrome 29)

Как я могу получить "сырое" значение элемента <input type="number">управления?

Я попытался просмотреть список других свойств поля ввода Chrome:

введите описание изображения здесь

я не видел ничего похожего на фактический ввод.

Я также не мог найти способ узнать, «пусто» ли поле или нет. Возможно, я мог предположить:

value          isEmpty        Conclusion
=============  =============  ================
"4"            false          valid number
""             true           empty box; not a problem
""             false          invalid text; color it red

Примечание . Все, что находится после горизонтальной линейки, можно игнорировать; это просто наполнитель для обоснования вопроса. Также: не путайте пример с вопросом. Люди могли бы ответить на этот вопрос , по причинам , другие , чем окрашивать коробки красных (один пример: преобразование текста "four"в латинском "4"символ во время мероприятия ONBLUR)

Как я могу получить "сырое" значение элемента <input type="number">управления?

Бонусное чтение

Ян Бойд
источник
2
«Настоящее» значение числового поля ввода должно быть числом. Если вы хотите разрешить ввод, отличный от числовых значений, то numberэто не тот тип ввода, который вы ищете; используйте обычный textввод.
robertc
7
@robertc Chrome - это агент, позволяющий вводить кроме чисел; мне просто нужно знать, что они ввели не цифры.
Ian Boyd
1
Проверьте поле в validityсостоянии - я бы ожидать , typeMismatchно я не проверял сам.
robertc
2
@ int32_t Прочтите шестую строчку вниз (т.е. «Но если пользователь войдет ...» )
Ян Бойд
6
Мой вариант использования ... У меня есть два числовых поля: широта и долгота. Я хотел бы определить, вставляет ли кто-то в "lat, lon" и правильно ли обрабатывает. В настоящее время это невозможно с type = "number". поскольку "lat, lon" недействителен ... нет способа получить "сырое" значение для выполнения регулярного выражения. Другой вариант использования: отображение ошибки клиента: « blahневерный номер».
Брэд Кент

Ответы:

55

Согласно WHATWG , вы не сможете получить значение, если это не допустимый числовой ввод. Алгоритм очистки числового поля ввода говорит, что браузер должен установить значение в пустую строку, если ввод не является допустимым числом с плавающей запятой.

Алгоритм значения санитарного выглядят следующим образом : Если значение элемента не является допустимым число с плавающей точкой , а затем установить его в пустую строку вместо.

Указывая type ( <input type="number">), вы просите браузер сделать за вас некоторую работу. Если, с другой стороны, вы хотите иметь возможность захватывать нечисловой ввод и что-то делать с ним, вам придется полагаться на старое проверенное и достоверное поле ввода текста и самостоятельно анализировать содержимое.

W3 имеет те же характеристики и добавляет:

Пользовательские агенты не должны позволять пользователю устанавливать значение непустой строки, которая не является допустимым числом с плавающей запятой.

j08691
источник
6
Было бы полезно, если бы пользовательские агенты не разрешали пользователю устанавливать значение в непустую строку, которая не является допустимым числом с плавающей запятой. Но если whatwg говорит, что это невозможно; тогда это ответ. Обходной путь для моей текущей потребности добавлен ниже.
Ян Бойд
57
Указывая type ( <input type="number">), вы просите браузер сделать за вас некоторую работу. Лично я просто просил мобильные браузеры отображать цифровую клавиатуру и получил подтверждение как неприятную дополнительную вещь. Большинство этих проблем проистекает из того факта, что typeатрибут определяет как правила проверки, так и правила о том, какой механизм ввода отображать, но вполне возможно захотеть показать цифровую клавиатуру мобильным пользователям, не желая также, чтобы проверка номера применялась к пользователям настольных компьютеров. HTML 5.1 в конечном итоге решит эту проблему с помощью inputmodeатрибута.
Марк Эмери
4
но когда браузер делает недостаточно, я хотел бы иметь возможность завершить его. например, удаление пробелов во вводе, определение десятичной точки ...
njzk2
1
Кроме того, в разных языках, например во французском, есть 2 слова для числа. один для чисел в качестве идентификаторов, таких как номера кредитных карт, и один для подсчета чисел, таких как числа с плавающей запятой.
njzk2
1
@MotiKorets не работает для ввода чисел с плавающей запятой, поскольку iPhone не помещает десятичную точку на клавиатуре. К сожалению, на данный момент разработчики сильно облажались, обеспечивая хороший UX для ввода с плавающей запятой ...
Энди
50

Это не дает ответа на вопрос, но полезный обходной путь - проверить

edQuantity.validity.valid

Объект ValidityStateобъекта дает подсказку о том, что ввел пользователь. Рассмотрим type="number"вход с a minи maxустановите

<input type="number" min="1" max="10">

Мы всегда хотим использовать .validity.valid.

Другие свойства предоставляют только бонусную информацию:

User's Input  .value  .valid | .badInput  .rangeUnderflow  .rangeOverflow
============  ======  ====== | =========  ===============  ==============
""            ""      true   | false      false            false  ;valid because field not marked required
"1"           "1"     true   | false      false            false  
"10"          "10"    true   | false      false            false
"0"           "0"     false  | false      true             false  ;invalid because below min
"11"          "11"    false  | false      false            true   ;invalid because above max
"q"           ""      false  | true       false            false  ;invalid because not number
"³"           ""      false  | true       false            false  ;superscript digit 3
"٣"           ""      false  | true       false            false  ;arabic digit 3
"₃"           ""      false  | true       false            false  ;subscript digit 3

Перед использованием убедитесь, что браузер поддерживает проверку HTML5:

function ValidateElementAsNumber(element)
{
   //Public Domain: no attribution required.
   if ((element.validity) && (!element.validity.valid))
   {
      //if html5 validation says it's bad: it's bad
      return false;
   }

   //Fallback to browsers that don't yet support html5 input validation
   //Or we maybe want to perform additional validations
   var value = StrToInt(element.value);
   if (value != null)
      return true;
   else
      return false;
}

бонус

У Спадли есть полезный ответ, который он удалил:

Просто используйте :invalidдля этого селектор CSS .

input[type=number]:invalid {
    background-color: #FFCCCC;
}

Это приведет к тому, что ваш элемент станет красным при вводе нечислового допустимого значения.

Поддержка браузером <input type='number'>примерно такая же :invalid, так что проблем нет.

Подробнее читайте :invalid здесь .

Ян Бойд
источник
Не работает в Opera. Он говорит, что действительно, даже если вы вводите строку.
Берги
Opera поддерживает .validityсвойство, но не обрабатывает его правильно .valid?!
Ian Boyd
Да, но когда ввод числа недопустим ? Он просто действует так, как если бы ввод был пуст. A typeMismatchможет иметь смысл, но это только для типов электронной почты или URL…
Берги
@Bergi В таблице выше приведены примеры, когда числовые значения могут быть недопустимыми: «q», «11» (тогда максимальное значение равно 10), «0» (когда минимальное значение равно 1), «» (тогда элемент равен required)
Ян Boyd
1
@Bergi .badInputдобавлен 20.11.2012 . Но никто не должен смотреть, badInputверен ли ввод; они должны смотреть .valid. Возможно (и правильно), .badInputчто он будет ложным, но все равно будет иметь недопустимый ввод. .validопределяется как отсутствие каких-либо ошибок проверки (например, несоответствия, переполнения, потери значимости), из которых .badInputтолько один вид ошибок. Обратите внимание на диаграмму выше, где указано значение .badInputfalse, но ввод все еще недействителен.
Ян Бойд
11
input.focus();
document.execCommand("SelectAll");
var displayValue = window.getSelection().toString();
int32_t
источник
Не работает в firefox: bugzilla.mozilla.org/show_bug.cgi?id=85686 (обратите внимание, что эта ошибка была зарегистрирована в 2001 году !!)
Брэд Кент,
Firefox, как всегда, правильный. Это не должно работать и является ошибкой
vsync
4

Отслеживайте все нажатые клавиши на основе их кодов клавиш

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

http://unixpapa.com/js/key.html

Выберите ввод и получите выделение в виде строки

document.querySelector('input').addEventListener('input', onInput);

function onInput(){
  this.select(); 
  console.log( window.getSelection().toString() )
}
<input type='number'>

Все кредиты на: int32_t

Сандстр
источник
Это решение было испробовано в другом месте, но оно не работает . Особенно , когда пользователи прессы Delete, Backspace, Ctrl+X, Ctrl+V, Right-click-cut, Right-click-paste.
Ян Бойд,
Я согласен с вами, в основном то, что спросил OP, невозможно. Однако оба упомянутых мною взлома (и я не отрицаю, что это взломы) в некоторой степени работают. Может быть, они могут быть кому-то полезны, в каком-то случае?
Sandstrom
как ни странно, выбор работает. Какие ограничения у этого метода?
njzk2
Ограничения: текст выделяется визуально. Если пользователь что-то
напечатает,
Отредактировано живой демонстрацией, которая показывает, насколько плох этот метод
vsync