Разрешить 2 десятичных знака в <input type = «number»>

222

У меня есть <input type="number">и я хочу ограничить ввод пользователей только цифрами или числами с десятичными знаками до 2 десятичных знаков.

В основном, я прошу ввод цен.

Я хотел избежать регулярных выражений. Есть ли способ сделать это?

<input type="number" required name="price" min="0" value="0" step="any">
nubteens
источник
2
type = "number" не имеет широкой поддержки браузера. Лучше просто использовать текстовое поле с некоторым javascript, чтобы убедиться, что вы получите желаемый ввод.
www139
6
Да, но входные данные type="text"все равно возвращаются , так какое это имеет значение?
Ultimater
/^\d+\.\dndom2,2 enj$/ работал для меня, чтобы потребовать 0,00
ZStoneDPM

Ответы:

337

Вместо step="any", который позволяет использовать любое количество знаков после запятой, используйте step=".01", который допускает до двух знаков после запятой.

Более подробная информация в спецификации: https://www.w3.org/TR/html/sec-forms.html#the-step-attribute.

Майкл Бенджамин
источник
38
Это не правильный ответ. Шаг только управляет тем, что происходит, когда вы нажимаете или нажимаете вверх, и ничего не ограничивает.
Ини
1
@Michael_B, независимо от того, на что рассчитывает спецификация, это довольно просто протестировать: jsfiddle.net/9hvm0b5u по- прежнему позволяет вводить более 2 десятичных знаков. Шаги определяют только то, на что кнопки +/- перемещают сумму. (Chrome)
Натан
3
@Michael_B пользователю не запрещается набирать номер, такой как 500.12345в любом из входных данных, возможно, наше понимание требований отличается.
Натан
3
Следует отметить, что, хотя пользователь может вводить любое количество цифр после десятичного знака, большинство браузеров не разрешают отправку формы с недопустимым значением и селекторов CSS :validи :invalidприменяются в соответствии с ожиданиями.
Эндрю Динмор
1
@ Натан, это также тривиально проверить проверку браузера. Попробуйте отправить значение с более чем двумя десятичными разрядами
imclean
43

В этом случае кто-то ищет регулярное выражение, которое допускает только числа с необязательными двумя десятичными знаками

^\d*(\.\d{0,2})?$

Например, я нашел решение ниже достаточно надежным

HTML:

<input name="my_field" pattern="^\d*(\.\d{0,2})?$" />

JS / JQuery:

$(document).on('keydown', 'input[pattern]', function(e){
  var input = $(this);
  var oldVal = input.val();
  var regex = new RegExp(input.attr('pattern'), 'g');

  setTimeout(function(){
    var newVal = input.val();
    if(!regex.test(newVal)){
      input.val(oldVal); 
    }
  }, 0);
});
Уэстон Гангер
источник
2
Какова цель наличия setTimeout ()?
Дерек
2
@Derek. Я предполагаю, что это так, что regex.test не блокирует DOM. Найти это: developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
christo8989
2
@Derek Я могу только предположить, что setTimeout()нужно дождаться завершения keydownсобытия, прежде чем устанавливать newVal(иначе оно будет таким же, как oldVal). Однако, с таймаутом 0, это бессмысленно и не работает, так как оба значения часто одинаковы (в Firefox). Например, если вы установите значение 1, оно будет работать нормально.
alstr
Итак, вы откатили мою правку в двух разных постах по причине «неутвержденная правка ухудшает качество форматирования ответа». Не могли бы вы объяснить, как мое изменение не одобрено и как именно оно ухудшает качество ответа? (IMO, это улучшает его, так как люди могут запускать код прямо из поста, и им не нужно переходить в JSFiddle).
двойной сигнал
21

Для валюты я бы предложил:

<div><label>Amount $
    <input type="number" placeholder="0.00" required name="price" min="0" value="0" step="0.01" title="Currency" pattern="^\d+(?:\.\d{1,2})?$" onblur="
this.parentNode.parentNode.style.backgroundColor=/^\d+(?:\.\d{1,2})?$/.test(this.value)?'inherit':'red'
"></label></div>

Смотрите http://jsfiddle.net/vx3axsk5/1/

Свойства HTML5 "step", "min" и "pattern" будут проверяться при отправке формы, а не onblur. Вам не нужно, stepесли у вас есть, patternи вам не нужно, patternесли у вас есть step. Таким образом, вы можете вернуться к step="any"моему коду, так как шаблон будет проверять его в любом случае.

Если вы хотите проверить onblur, я считаю, что предоставление пользователю визуальной подсказки также полезно, как окрашивание фона в красный цвет. Если браузер пользователя не поддерживает, type="number"он вернется к type="text". Если браузер пользователя не поддерживает проверку шаблона HTML5, мой фрагмент JavaScript не препятствует отправке формы, но дает визуальный намек. Таким образом, для людей с плохой поддержкой HTML5 и людей, пытающихся взломать базу данных с отключенным JavaScript или подделывать HTTP-запросы, вам все равно придется снова проверять на сервере. Пункт с проверкой на переднем конце для лучшего пользовательского опыта. Таким образом, пока большинство ваших пользователей имеют хороший опыт, можно полагаться на функции HTML5, если код все еще работает, и вы можете проверить его на бэкэнде.

Ultimater
источник
2
Согласно MDN , patternне работает для input type=number:<input type="number"> elements do not support use of the pattern attribute for making entered values conform to a specific regex pattern. The rationale for this is that number inputs can't contain anything except numbers, and you can constrain the minimum and maximum number of valid digits using the min and max attributes, as explained above.
izogfif
@izogfif Хорошая заметка. Также обратите внимание, что я на самом деле заметил, что вам не нужны оба, и предоставил три способа: Step, pattern и onblur. В то время я обосновывал это тем, что один браузер по какой-то причине захлопывает другой. Вероятно, безопасно полагаться на шаг в эти дни для проверки внешнего интерфейса.
Ultimater
16

Шаг 1: Подключите поле ввода вашего номера HTML к событию onchange

myHTMLNumberInput.onchange = setTwoNumberDecimal;

или в коде HTML

<input type="number" onchange="setTwoNumberDecimal" min="0" max="10" step="0.25" value="0.00" />

Шаг 2: Напишите setTwoDecimalPlaceметод

function setTwoNumberDecimal(event) {
    this.value = parseFloat(this.value).toFixed(2);
}

Вы можете изменить количество десятичных разрядов, изменяя значение, передаваемое в toFixed()метод. Смотрите MDN документы .

toFixed(2); // 2 decimal places
toFixed(4); // 4 decimal places
toFixed(0); // integer
Сачин Судхакар Сонаване
источник
3
parseFloat (parseFloat (this.value) .toFixed (2)); Если вам нужен десятичный или числовой тип, вы можете обернуть все это в parseFloat (), так как по умолчанию метод toFixed () возвращает строку.
Spacedev
6

Я нашел, что использование jQuery было моим лучшим решением.

$( "#my_number_field" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});
SamohtVII
источник
6

Попробуйте это для разрешения только 2 десятичных в типе ввода

<input type="number" step="0.01" class="form-control"  />

Или используйте jQuery в соответствии с предложением @SamohtVII

$( "#ELEMENTID" ).blur(function() {
    this.value = parseFloat(this.value).toFixed(2);
});
Нилеш Гаджаре
источник
21
Это не ограничивает десятичные дроби до 2 мест в Chrome 57
mintedsky
1
Это не правильно. Шаг только управляет тем, что происходит, когда вы нажимаете или нажимаете вверх, и ничего не ограничивает.
Ини
шаг также предотвращает ввод числа, такого как 1.000.
Zapnologica
-2

Используйте этот код

<input type="number" step="0.01" name="amount" placeholder="0.00">

По умолчанию значение шага для элементов ввода HTML5 равно step = "1".

Обайдул Хак
источник
-4

просто пиши

<input type="number" step="0.1" lang="nb">

lang = 'nb "позволяет записывать десятичные числа с запятой или точкой

ИЛЛЮСТРАЙ КИНГ
источник
"lang = 'nb' позволяет вам писать десятичные числа с запятой или точкой" Не могу говорить ни о чем другом, но это не работает в Chrome для меня.
Эндрю Динмор
-9

На входе:

step="any"
class="two-decimals"

По сценарию:

$(".two-decimals").change(function(){
  this.value = parseFloat(this.value).toFixed(2);
});
xemasiv
источник
5
Пожалуйста, избегайте использования логов в своем посте. И не забывай быть милым
Джеймс