- PVSM.RU - https://www.pvsm.ru -
Данный плагин для jQuery позволяет автоматически подбирать подходящую маску ввода на основе введённого начала телефонного номера. Это позволяет сделать ввод номера телефона на странице web-cайта более быстрым и безошибочным. Кроме того, разработанный плагин может быть использован в других областях, если правила ввода возможно представить в виде нескольких масок ввода.
На web-сайтах очень требуется ввод информации о телефонном номере. Так сложилось, что каждая страна вправе устанавливать свои правила набора и длину номера, в результате чего между жителями разных стран периодически возникает путаница: одни привыкли указывать номер с ведущей цифрой 8, другие — с ведущей цифрой 0, а третьи — со знака +.
Чтобы как-то разрешить возникшую сложность и привести номера к единому формату встречаются 3 основных решения:
+ перед номером (за пределами input) и разрешить только ввод цифр. Преимущества: простота реализации. Недостаток: отсутствие наглядного отображения номера.В результате было решено доработать привычную маску ввода так, чтобы она менялась в соответствии с текущим значением номера. Кроме того, по мере ввода номера предлагается отображать название определившейся страны. Данный подход, субъективно, должен решить все недостатки перечисленных выше решений.
С учётом того, что количество стран в мире относительно невелико, было принято решение составить список масок ввода для всех стран. В качестве источника использовались сведения [1], опубликованные на сайте международного союза электросвязи.
Сбор данной информации преподнёс немало сюрпризов. В процессе сбора сведений приходилось учитывать все возможные варианты телефонных номеров, в том числе внутри страны. Однако, ввиду большого количества обработанной вручную информации, возможно, в собранной базе остались неточности. С течением времени планируется вносить исправления в первоначальный набор.
В качестве ядра маски ввода была использована реализация jquery.inputmask [2], о которой многократно упоминалось на Хабрахабр. Данный плагин сейчас активно развивается и, к тому же, спроектирован таким образом, что для него достаточно просто писать расширения. Однако в данной задаче написать такое расширение оказалось практически невозможно. Я не стал дорабатывать или переписывать исходный плагин под свои нужды, т.к. его автор продолжает активную работу над расширением функционала, в результате чего применение моих правок может оказаться проблематичным. Поэтому мне пришлось написать плагин-надстройку над основным ядром, который отслеживает (плюс перехватывает) внешние воздействия и производит модификацию данных. Для того, чтобы внедрить свои обработчики внешних воздействий до обработчиков основного плагина использовался плагина-библиотека jquery.bind-first [3].
Для корректного выбора наиболее подходящей маски ввода весь набор масок требуется предварительно отсортировать специальным образом. При разработке правил сортировки были приняты следующие условности:
#, означающий произвольную цифру, и цифры 0-9) и символы-декораторы (все остальные).#) и все остальные.В результате получились следующие правила сортировки в порядке их применения:
При сравнении входного текста с очередной маской из отсортированного списка принимаются во внимание только значимые символы каждой маски. Если строка оказывается длиннее маски ввода, несмотря на то что все предшествующие символы прошли проверку, данная маска ввода считается неподходящей. В случае, если входному тексту удовлетворяет несколько масок ввода, то возвращается первая из них. Далее в найденной маске все значимые символы (в том числе нешаблонные) заменяются на шаблонный, который является комбинацией всех символов, разрешённых любым из шаблонных символов.
С целью предотвращения конфликтов с обработчиками событий основного ядра маски ввода перехватываются следующие события:
Все события навешиваются в пространстве inputmask. Это позволяет избежать некорректного поведения при вызове inputmask после инициализации надстройки (т.к. ядро при инициализации снимает все ранее установленные обработчики в пространстве inputmask).
Список масок представляет собой JavaScript-массив объектов, предпочтительно с одинаковым набором свойств. Как минимум одно свойство, которое содержит маску ввода, должно присутствовать у всех объектов массива. Имя параметра, содержащего маску, может быть произвольным. Ниже представлен фрагмент такого массива:
[
…
{ "mask": "+7(###)###-##-##", "cc": "RU", "name_en": "Russia", "desc_en": "", "name_ru": "Россия", "desc_ru": "" },
{ "mask": "+250(###)###-###", "cc": "RW", "name_en": "Rwanda", "desc_en": "", "name_ru": "Руанда", "desc_ru": "" },
{ "mask": "+966-5-####-####", "cc": "SA", "name_en": "Saudi Arabia ", "desc_en": "mobile", "name_ru": "Саудовская Аравия ", "desc_ru": "мобильные" },
{ "mask": "+966-#-###-####", "cc": "SA", "name_en": "Saudi Arabia", "desc_en": "", "name_ru": "Саудовская Аравия", "desc_ru": "" },
…
]
До подключения требуется загрузить и отсортировать список масок. Это делается выполнением следующей функции:
$.masksSort = function(maskList, defs, match, key)
#);/[0-9]|#/);При подключении плагину передаётся специальный объект, описывающий его работу. Данный объект содержит следующий набор параметров:
Для инициализации плагина нужно применить метод inputmasks к полю ввода:
$.fn.inputmasks = function(maskOpts, mode)
isCompleted — в результате метод возвращает true, если текст, соответствующей подходящей маске, введён полностью и false в противном случае.<input type="text" id="customer_phone" value="7" size="25"><br>
<input type="checkbox" id="phone_mask" checked>
<label id="descr" for="phone_mask">Маска ввода</label>
<script>
var maskList = $.masksSort($.masksLoad("phone-codes.json"), ['#'], /[0-9]|#/, "mask");
var maskOpts = {
inputmask: {
definitions: {
'#': {
validator: "[0-9]",
cardinality: 1
}
},
//clearIncomplete: true,
showMaskOnHover: false,
autoUnmask: true
},
match: /[0-9]/,
replace: '#',
list: maskList,
listKey: "mask",
onMaskChange: function(maskObj, completed) {
if (completed) {
var hint = maskObj.name_ru;
if (maskObj.desc_ru && maskObj.desc_ru != "") {
hint += " (" + maskObj.desc_ru + ")";
}
$("#descr").html(hint);
} else {
$("#descr").html("Маска ввода");
}
$(this).attr("placeholder", $(this).inputmask("getemptymask"));
}
};
$('#phone_mask').change(function() {
if ($('#phone_mask').is(':checked')) {
$('#customer_phone').inputmasks(maskOpts);
} else {
$('#customer_phone').inputmask("+[####################]", maskOpts.inputmask)
.attr("placeholder", $('#customer_phone').inputmask("getemptymask"));
$("#descr").html("Маска ввода");
}
});
$('#phone_mask').change();
</script>
Пример демонстрации разработанного плагина представлен на странице проекта [4].
Автор: avegorov
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/22565
Ссылки в тексте:
[1] сведения: http://www.itu.int/oth/T0202.aspx?parent=T0202
[2] jquery.inputmask: https://github.com/RobinHerbots/jquery.inputmask
[3] jquery.bind-first: https://github.com/private-face/jquery.bind-first
[4] странице проекта: http://andr-04.github.com/inputmask-multi/
[5] Источник: http://habrahabr.ru/post/162537/
Нажмите здесь для печати.