Плагин для маски ввода чисел в input

Часто стоит задача, ограничить возможность ввода букв в поле input. Во многих источниках предлагают это сделать следующим способом, навесить обработчик события keyup, со следующим кодом:
return ((event.keyCode>47)&&(event.keyCode<58))

Этот метод обладает рядом недостатков, к примеру также пользователь не сможет вводить цифры numpad, в опере не будут работать клавиши tab,up,left и т. д.
Как же сделать правильно?
Но также встречаются хорошие идеи, доработав которые можно добиться желаемого результата.
	function testKey(e)
{
  // Make sure to use event.charCode if available
  var key = (typeof e.charCode == 'undefined' ? e.keyCode : e.charCode);

  // Ignore special keys
  if (e.ctrlKey || e.altKey || key < 32)
    return true;

  key = String.fromCharCode(key);
  return /\d/.test(key);
}

Я решил на основании этого кода написать jQuery плагин. Но чтобы не изобретать велосипед я решил поискать уже готовый плагины, и нашел один digitalbush.com/projects/masked-input-plugin/. Дествительно замечательный плагин, но мне нужно было, что бы я мог задавать условия для поля либо целые числа, либо дробные числа.
И так, какие задачи я поставил себе:
  1. Задавать тип «float», «int», либо регулярное выражение.
  2. Задавать разделитель для типа «float».
  3. Задвать количество символов до разделителя и после него.
  4. Значение по умолчанию, если пользователь вставил значение через контекстное меню.

Как упоминалось ранее, при нажатии клавиши я преобразовал код в символ, проверял его через регулярное выражение. Осталось предусмотреть только случай, если пользователь вставил значение через контекстное меню, для этого я повесил обработчик на события blur, где выполнял проверку через нужное нам регулярное выражение.
Однако когда я стал все проверять, я заметил, если пользователь выделял мышкой какую-то часть текста в Input. Он мог вставить не разрешенный символ, обойти это регулярное выражение, для того чтобы это избежать я брал выделенный текст(вот здесь пришлось бороться с кроссбраузерностью ) и в соответствии с условиями проверял.
Исходники на github и демо
Используемая литература:
  1. habrahabr.ru/blogs/javascript/55922/.
  2. xpoint.ru/know-how/JavaScript/PoleznyieFunktsii?38#Fil'trVvodaDlyaTekstovogoPolya
+13
21 января 2012, 18:18
123
mavrin 3,1

комментарии (22)

+2
Ekstazi #
Регулярка неверная. \w понимает цифры или буквы латинского алфавита. Правильно [\d,\.]. Примерно так у вас сейчас и сделано в коде. Поправьте и в статье.
+2
mavrin #
Да вы правы, я просто привел пример кода.которым я решаю проблему. Но чтобы не вводить читателя в заблуждение поправил.
–2
InteractiveTechnology #
Хорошо, что вы не изобретали велосипед, но ещё лучше если бы взяли вот wiki.jqueryui.com/w/page/12137996/Mask и доработки pull request ;)
+2
mavrin #
Виджета на который вы дали ссылку, за основу его брался указанный мною в статье плагин. Только для него не требуется jQueryUI, который все же реже подключают на сайт, чем сам jquery.
+1
Mithgol #
Разделяю Ваше мнение, хотя бы потому, что jQuery UI — чертовски увесистая штуковина.
+2
mavrin #
Кстати в отличии от самого jQuery, jQuery UI хорошо разбиваться на нужные нам модули. К примеру приведенном виджете InteractiveTechnology, подключаются только сore и widget, которые не в ужатом виде весят вместе 19к. Но я тоже согласен, что штука тяжелая, но дает и большие возможности при построении интерфейса.
–2
Ekstazi #
Замысловатая она очень, я в ней не смог разобраться.
0
lashtal #
почему бы не использовать один универсальный валидатор, который, кроме прочего, умеет и маски? Т.е. да, он тяжелее конечно, зато решение для всех форм сайта сразу.
jquery.validate: bassistance.de/jquery-plugins/jquery-plugin-validation/
+1
mavrin #
Да я знаком с этим плагином, но дело в том, что этот плагин только проверяет верные ли ввел пользователь символы, но не запрещает пользователю вводить неразрешенные символы. Мой плагин не претендует на роль валидатора).Я не тестировал, но я думаю он будет прекрасно работать в связке с указанным вами плагином.
0
Silver_Clash #
Преимущество валидатора в том, что он не вызывается после любого действия пользователя, и тем самым меньше грузит браузер. К тому же зачем лишний раз ограничивать пользователя, если можно вывести ему ненавязчивую подсказку?
+1
mavrin #
По поводу нагрузки на браузер, я особо не волновался бы, пользователь ее не заметит. А на счет ограничение пользователя, плагин я делал для проекта и было условие, что пользователь должен иметь возможности вводить только разрешенные символы. Хотя, если посмотреть на input c type='number', то он действительно разрешает вводить любые символы, и только после потери фокуса возвращает последнее верное значение.
0
Silver_Clash #
Нагрузка это первое по поводу чего нужно волноваться, потому что если пользователь начнет нервничать из за тормозов на вашей страничке — считайте что вы его потеряли.
+1
mavrin #
Я не спорю что не нужно следить за нагрузкой, я о том, что обработка в моем плагине не сделает зависания браузера.
0
VoidEx #
А можно на text-changing проверять валидность текста и отменять, если текст на валиден?
Тогда нам неважно, копипастят текст или ещё как.
Задача же стоит не запретить нажатие клавиш, а запретить невалидный текст.
+2
mavrin #
У меня в задаче стояло запретить ввод невалидного текста, а если Вы смотрели код или внимательно читали, то заметили бы, что я делаю проверку при потере фокуса.
0
yumitsu #
А чем не понравился плагин jQuery Masked Input?
0
yumitsu #
Черт, не заметил, что вы его уже нашли :)
+1
yumitsu #
Кстати, в HTML5 есть нативная валидация. Правда, IE в пролете.
caniuse.com/#feat=form-validation
0
wmw85 #
Возможно вам подошел бы maskmoney
0
RomeroMsk #
Несколько неожиданное поведение плагина при вставке из буфера float, длина дробной части которого превышает «ожидаемую». Копирую и вставляю во второе поле в демо следующее значение: 10,12345, в результате чего получаю урезание до 10,1. Win 7, Chrome 16.0.912.75 m
+1
mavrin #
Извините, не туда ответил, ответ ниже.
+1
mavrin #
Так получается, потому что в плагине есть опция значение по умолчанию, сейчас в примере для дробный чисел стоит 10.1, и если вставляемое число не подходит под выражение, то вставляется значение по умолчанию.

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