Як отримати необроблене значення поле <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 - агент, що дозволяє вводити дані, крім цифр; мені просто потрібно знати, що вони ввели інші речі, крім цифр.
Ян Бойд

1
Перевірте поле в validityстані - я б очікувати , typeMismatchале я не перевіряв сам.
robertc

2
@ int32_t Прочитайте шостий рядок вниз (тобто "Але якщо користувач увійде ..." )
Ян Бойд

6
Мій випадок використання ... У мене є два числові поля: широта і довгота. Я хотів би визначити, чи хтось вставляє "lat, lon" та обробляє належним чином. Наразі це неможливо за допомогою type = "number". оскільки "lat, lon" недійсний .. немає способу отримати значення "raw" для виконання регулярного вираження. Інший випадок використання: відображення помилки клієнта: " blahнедійсне число".
Бред Кент

Відповіді:


55

Відповідно до WHATWG , ви не можете отримати значення, якщо це не дійсне числове введення. Алгоритм санітації поля введення номера говорить, що браузер повинен встановити значення в порожній рядок, якщо введення не є дійсним номером з плаваючою комою.

Алгоритм санітарії значення такий: Якщо значення елемента не є дійсним числом з плаваючою комою , то встановіть його замість порожнього рядка.

Вказавши тип (<input type="number"> ), ви просите браузер виконати певну роботу за вас. Якщо, з іншого боку, ви хочете мати можливість захопити нечисловий ввід і зробити щось з ним, вам доведеться покластись на старе випробуване і справжнє поле для введення тексту та самостійно проаналізувати вміст.

W3 має ті ж характеристики і додає:

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


6
Було б корисно, якби користувацькі агенти не дозволили користувачеві встановити значення не порожній рядку, що не є дійсним номером з плаваючою комою. Але якщо whatwg каже, це зробити не можна; то це відповідь. Нижче додано вирішення моєї поточної потреби.
Ян Бойд

57
Вказуючи тип ( <input type="number">), ви просите браузер виконати певну роботу за вас. Особисто я просто просив мобільні браузери показати цифрову клавіатуру і отримав перевірку як неприємну додаткову інформацію. Більшість цих проблем випливає з того, що typeатрибут визначає як правила перевірки, так і правила щодо того, який механізм введення відображати, але цілком можливо хотіти показати числову клавіатуру мобільним користувачам, не бажаючи також перевірки числа, застосованої до користувачів настільних ПК. HTML 5.1 принаймні вирішить цю проблему з часом за допомогою inputmodeатрибута.
Марк Амері

4
але коли браузер недостатньо працює, я хотів би мати можливість його завершити. наприклад, видалення пробілів у введенні, виведення десяткових знаків ...
njzk2,

1
також у різних мовах, таких як французька, є 2 слова для числа. один для номерів як ідентифікаторів, таких як номери кредитних карток, і один для підрахунку чисел, таких як номери з плаваючою комою.
njzk2

1
@MotiKorets не працює для введення чисел з плаваючою комою, оскільки iPhones не кладе десяткову крапку на клавіатурі. На жаль, на даний момент девіси досить накручені настільки, що забезпечує приємний запис з плаваючою точкою UX ...
Енді

50

Це не відповідає на питання, але корисний спосіб вирішити - це перевірити

edQuantity.validity.valid

ValidityStateОб'єкта підказує про те, що вводиться користувач. Розглянемо type="number"вхід з a minі maxset

<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;
}

Бонус

У Spudly є корисна відповідь, що він видалив:

Просто використовуйте :invalidдля цього селектор CSS .

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

Це призведе до того, що ваш елемент стане червоним щоразу, коли буде введено нечислове значення.

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

Детальніше про це :invalid читайте тут .


Не працює в Opera. Він говорить, що дійсний навіть у випадку введення рядка.
Бергі

Opera підтримує .validityвластивість, але не працює правильно .valid?!
Ян Бойд

Так, але коли введення числа недійсне ? Він просто діє так, ніби вхід був порожнім. typeMismatchМоже мати сенс, але це тільки для електронної пошти або URL - адреси типів ...
Берги

@Bergi У наведеній вище таблиці наведено приклади, коли числові введення можуть бути недійсними: "q", "11" (тоді макс дорівнює 10), "0" (коли хв 1), "" (тоді елемент є required)
Ian Бойд

1
@Bergi .badInputбув доданий 11/20/2012 . Але ніхто не повинен дивитись, badInputщоб перевірити, чи вхід правильний; вони повинні дивитись .valid. Можливо, (і правильно), .badInputщоб вони були помилковими, і все ще мають недійсні дані. .validвизначається як відсутність будь-яких помилок перевірки (наприклад, невідповідності, переповнення, підтоки), з яких .badInputлише один вид помилок. Зверніть увагу на діаграмі вище, де .badInputпомилково, але введення все ще недійсне.
Ян Бойд

11
input.focus();
document.execCommand("SelectAll");
var displayValue = window.getSelection().toString();


Не працює у 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.
Ян Бойд

Я згоден з вами, в основному те, що запитувала ОП, неможливо. Однак обидві хаки, про які я згадував (і це хаки, я цього не заперечую), певною мірою працюють. Можливо, вони можуть комусь стати в нагоді?
пісок

дивно, але здається, що справа з вибором працює. У чому полягає обмеження цього методу?
njzk2

Обмеження: текст вибирається візуально. Якщо користувач щось
введе,

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