Получил я достаточно стандартное задание: фильтровать вводимые юзером символы в input, т. е. пользователь может ввести в строку набор цифр и букв, например, '5s68d.4r55e.6t5', а на сервер я должен отправить корректное для сохранения сумму в рублях — '568,455' (рублей).
Справился я с заданием достаточно быстро, повесив на input событие focusout, но у моего решения был ряд важных недостатков: где в данном примере заканчивается сумма в рублях и начинаются копейки? Если пользователь введет несколько минуcов (отрицательные значения тоже корректны в данном случае), то какой из минусов считать началом строки? И так далее.
Поэтому появилась вторая версия скрипта с регулярными выражениями на событие keyup:
$(e.curretTarget).val(($(e.currentTarget).val()).replace( /[^0123456789.-]/, '' ))
Но как оказалось, этот способ имел ощутимый недостаток (я не имею ввиду то, что пользователь видит символ, который вводит и потом этот символ пропадает), а именно — если поставить курсор, например, посередине введенного числа в input, ввести букву, то скрипт вырежет букву, но перекинет курсов в конец строки.
По этой причине старший товарищ дал указание написать функцию на событие keypress. Через 30 минут уже третий вариант функции был готов и имел он примерно такой вид:
function()
{
return this.each(function()
{
$(this).keydown(function(e)
{
var key = e.charCode || e.keyCode || 0;
// allow backspace, tab, delete, enter, arrows, numbers and keypad numbers ONLY
// home, end, period, and numpad decimal
return (
key == 8 ||
key == 9 ||
key == 13 ||
key == 46 ||
key == 110 ||
key == 190 ||
(key >= 35 && key <= 40) ||
(key >= 48 && key <= 57) ||
(key >= 96 && key <= 105));
});
});
};
Код взят со steckoverflow, но мой код мало чем отличался от примера выше.
Всё выглядело красиво — пользователь не видит вводимых чисел и курсор не перебрасывает в конец строки, но, как оказалось, радовались мы рано. Если смотреть на keycode клавиш на разных операционных системах (mac, linux, win), то они имеют некоторые различия, а если к этому прибавить то, что не у всех маков есть numPud и, следовательно, числа вводятся с зажатым шифтом и также цифры могут вводится с виртуальной клавиатуры. В итоге получается код во много раз больше, чем последний пример.
В итоге я написал скрипт на событие keyup и он заработал с единственным недостатком — пользователь на секунду видит вводимое число. По понятным причинам я не могу выложить скрипт, но эта ситуация побудила меня написать новый скрипт, который я выложил на github. Я сделал скрипт более универсальным — сейчас он больше рассчитан на передачу значения в DOM-элементы, чем на модификацию введенного значения в input (это будет следующий шаг).
На момент написания статьи в функцию можно передать несколько параметров:
- forDisplay: true, // для отображения в дивах
- classOfDomElement: '',// классы DOM элементов через запятую без пробелов
- idOfDomElement: '',// id DOM элементов через запятую без пробелов
- //forInput: false,
- forSave: false, // function forSave — возвращает только цифры с точкой
- negative: false,
- afterPoint: 2, // количество цифр после точки
- showPoint: true, // показывать точку до ввода копеек
- currency: 'руб.' // валюта
Спасибо за внимание!
Автор: tarasikgoga