Как стать автором
Обновить

Комментарии 56

В последнее время стало актуальным использование масок. Ваш плагин отлично справляется, будем пользовать. Спасибо!
Сразу ошибка при первой попытке ввести телефон г. Брянска с кодом 4832



Остаюсь при мнении, что в случае, если номер телефона обрабатывает человек, то маски не нужны вовсе.
Хотя, сам по себе плагин интересен. Обязательно покажу своим программистам!
В первоначальном наборе ставилась цель правильно определять по номеру телефона страну и подходящую маску — чтобы не возникло ситуации, что номер не вмещается или, наоборот, остались пустые позиции.

На настоящий момент деление по городам России не произведено, однако данная возможность заложена в плагин — нужно лишь расширить список масок… Это вопрос времени.
Если сделаете список масок городов России — будет очень здорово! Я что-то так и не смог найти сколько-нибудь адекватного.
И как вы эти ссылки находите >_< Спасибо :)
Сделано. Вроде, даже, не тормозит. :)

Сведения брал отсюда. Но, как оказалось, они местами устарели. Я вручную пробежался по крупным городам и поправил неточности.

Страницу проекта обновил — можно проверять прямо там.
Да, это правильнее. Первоисточником пока не воспользовался из-за того, что не придумал как его обрабатывать. Кроме того, первоисточник не содержит сведений о длине кода региона (все коды ABC и DEF трёхсимвольные) — соответственно, не решает проблемы, обозначенной freextraz. Если делать серьёзную обработку на основе комбинаций диапазонов — тоже возможны проблемы. Конкретный пример — г.Челябинск, который перешёл на 7-значную нумерацию — из первоисточника это не следует.
По длине все просто — длина телефонного номера в РФ всегда фиксирована
Номер определяется маской +7 XXX YYY-YY-YY где +7 — код страны, XXX — код региона, YYY-YY-YY номер абонента.
А какие проблемы по Челябинску. По мне там все просто.
В качестве XXX очень часто привычнее видеть XXXX — т.е. 4 цифры и более в скобках, вместо 3-х, в зависимости от размера населённого пункта. Поэтому придётся анализировать данные более детально, а именно — все диапазоны, пытаться их объединить и т.д.

Есть надежда, что выгрузку можно переконвертировать, объединяя диапазоны и анализируя населённый пункт. Но избыточность базы может выйти боком — из-за присутствия районов и мелких диапазонов придётся вводить несколько записей для 1 диапазона. Потом в автоматизированном режиме пытаться объединить полученные маски (либо сначала объединить диапазоны, а потом маски — разницы нет).

Ладно, надо сначала попробовать. Как будет время — попробую.
По мне — это бесполезно.

Потому как.
Представим любой маленький населенный пункт.
Нумерация внутри — 3 цифры телефонного номера. Их набирают чтобы позвонить «по городу». Там так привыкли. Но! Официальный городской номер это еще 3 цифры, которые стоят перед этим 3-х значным номером, и по нему также можно позвонить. Соот-но код города — 4-рех значный.

В итоге, что я хочу сказать. Я бы, на вашем месте, сконцентрировался на представлении номеров в международном формате, которые начинаются на +. А все остальное — уж очень специфично и зависит от страны и населенного пункта. Дайте программисту возможность самому изменить эту логику в вашем приложении.

P.S.: Я не критикую, я искренне хочу помочь. Сам несколько завязан на телефонные номера — нахлебался.
Да, возможность как раз и заложена в плагине. Более того — в данной постановке и населённый пункт определять не требуется (чтобы показать правильную маску) и для этого уже подойдёт текущая реализация.
Тогда уж и с сотовыми можно сделать «из коробки», хотя бы по +79xx
Я думал над этим, но нужно понимать, что для определения маски ввода (а не региона или оператора) по номеру, как заявлено в теме, этого не требуется. Да, это было бы круто, но это немного другая задача и правильнее решается по-другому.
Да даже автоматом. Что мешает дать человеку ввести номер в том виде, каком он хочет, а затем преобразовать в нужный формат?
А зачем его преобразовывать в нужный формат после ввода? Обработке это не поможет. Пользователю — в случае ошибки неудобно будет её исправлять, либо мы придём к тому что есть — форматировать номер в процессе исправления (читай — ввода).
Чтобы привести к единому формату для дальнейшей обработки и представления.

Что касается пользователя, то он очень редко ошибается при вводе собственного номера, а маски часто не ошибку помогают исправлять и создают лишь дополнительную работу по оформлению. Допустим здесь элементарный косяк:

— вводим полностью свой номер, ошибаясь в одной цифре
— ставим курсор перед ошибочной цифрой
— нажимаем цифру и… ничего не происходит

Второй:

— мы еще не ввели номер и видим: +7(___)___-__-__
— хм… у меня же номер 8-904…
— ставим курсор перед 7 (перед плюсом не дает)
— нажимаем 8… опять ничего

В итоге, зачем эти сложности лишние по борьбе с ветряной мельницей?
— вводим полностью свой номер, ошибаясь в одной цифре
— ставим курсор перед ошибочной цифрой
— нажимаем цифру и… ничего не происходит

Перечитывая комментарии, вспомнил ещё про один режим работы основного плагина — режим замены. Если нажать Insert, то станет активен режим исправления написанного. Кроме того, этот режим можно инициализировать по умолчанию, указав параметр insertMode: false внутри параметра inputmask.
Это очень хорошо. Часть проблемы должно снять минимум.
Скроллер поправь, Панченко ругается! :)
+1 (858) XXX-XXXX — США (Калифорния) а не Канада.
Аналогично и +1(925)273-6263 — тоже США. Проблемы у БД плагина с США, похоже…
Есть такая проблема. Насколько мне удалось узнать, в США и Канаде используется одинаковый код страны — +1. Поскольку деления по штатам в БД не заносилось (пока), для Канады и США временно указана одинаковая маска — +1(###)###-####.

НО, что более важно, одинаковые маски ввода привели к разным результатам в разных браузерах! Для меня основным пока остаётся Google Chrome — так у меня указанные номера распознаются как США (соответственно, Канада не отображаестся никогда). Когда проверил эти примеры в Mozilla Firefox — получил ровно противоположный результат, о котором написали выше.

Разумеется, это не является ошибкой плагина — причина в разной реализации сортировки в разных браузерах (т.к. список масок предварительно сортируется дополнительной функцией — см. описание). Я внесу коррективы в список масок по Канаде и США — тогда проблема будет устранена.
Ну так можно же в БД для +1 так и написать — «США и Канада». В США один из самых больших интернетов, и, имея неточности в БД в этом месте, вы резко ограничиваете популярность плагина. Меня остановило от его немедленного использования только это, например (хотя я и понимаю, что руками могу сам поправить, но осадочек остался).
А что на счет тех, кто
привыкли указывать номер с ведущей цифрой 8

Номера вида 8(831) ххх-хх-хх, 8(495) ххх-хх-хх все еще актуальны в России.
Если речь о международном формате, то правило написания едино. А так — ещё можно вспомнить про 8-53, 8-58, 8-55 и 8-10. Кроме того, если говорить о других странах, во многих странах 0 — выход на межгород, 00 — международная связь. Это проблема, как её решать — пока не знаю…
НЛО прилетело и опубликовало эту надпись здесь
Доля истины в этом, конечно есть, и многие очень любят выделять подряд идущие (или одинаковые) цифры в отдельные группы — для более удобного запоминания. Кстати, это можно было бы предусмотреть в плагине, но я старался решать задачу в общем виде — в виде перечисления разрешённого списка масок, поэтому описанная проблема осталась за кадром. Стоит решать данную проблему или нет — пока не знаю.

На странице демонстрации проекта я умышленно добавил флажок «Ввод без маски». Думаю, имеет смысл рекомендовать так поступать всем — ведь ситуации, действительно, бывают самые разные и кому-то предложенная маска может мешать.
Умники! Что вы докопались до человека? Правильность набора номеров — прерогатива программиста. А вам предоставили инструмент. Пользуйтесь и настраивайте как хотите, а не умничайте где правильный номер, а где нет.
Автор правильно рассмотрел нестандартные события (обычно такую вещь ограничивают onchange или keydown). Но парочки не хватает. Кроме вот этих нестандартный, но предложенных автором событий:

— input для Gecko (+WebKit и Opera)
This event is sent when a user enters text in a textbox. This event is only called when the text displayed would change, thus it is not called when the user presses non-displayable keys.

XUL

— dragdrop (Gecko)

— paste (WebKit)

Предлагаю рассмотреть остальные варианты:

— DOMSubtreeModified (WebKit)

— DOMControlValueChanged для Opera.

— IE поддерживает нестандартное событие onpropertychange
The onpropertychange event fires when properties of an object, expando, or style sub-object change. <…> When the onpropertychange event fires, the srcElement property of the event object is set to the object whose property has changed

msdn

— DOMCharacterDataModified (W3C).

Резюмируя:
— Gecko only suppports 'input' (XUL)
— WebKit: 'input', parentNode.'DOMSubtreeModified', 'paste'
— IE: onpropertychange
— Opera: DOMControlValueChanged, input
По мобильным операторам данные пока не собирались. Мобильные не вводятся потому что не добавлена соответствующая маска, а компонент не разрешает ввод того что не разрешено. Это не является ошибкой — позже будет добавлено, скорее всего также будет добавлен тип номера — мобильный или стационарный (т.к. список дополнительных параметров номеров разного типа тоже отличается).
Если в одном поле можно будет ввести как мобильный, так и стационарный без переключения флагов плагин станет идеальным.
+380 44 555-55-55 — что-то не то выходит. И как то каждый раз по разному, не всегда дает писать, например там где я знаю что нужно поставить пробел как у нас принято, или короткое тире между группами символов.

Мне кажется это запарит обычных пользователей. Вот как в айфоне нужно обратить внимание — пишешь как можешь а оно старается красиво соструктурировать, а тут не дает.
Честно — сложно было собрать информацию о привычном отображении номера внутри каждой страны. Я заметил, что мало где используются скобки и дефисы — чаще пробелы. Но чтобы использовались одновременно пробелы и дефисы — такого не встречал нигде.

Здесь, по сути, маска тоже старается красиво структурировать. Единственное — у каждого свои привычки и понятие вкуса, поэтому может получаться несовсем то что ожидаешь.

Приведённый Вами пример отображается как +380-44-555-5555. Правильно ли я понимаю, что предлагается сделать отображение в виде +380 44 555 55 55?
У нас пишут по разному, и в правду стандарта особо нет. Я вижу часто так:

+38 (044) 555-55-55
(044) 555-55-55
0 (44) 555-55-55

Да ладно, все равно супер :-) Я просто про то что когда человек начинает писать так как он привык система не кушает, это может для многих вызвать нервы.
так правильно именно +380. +38 это бывший код Югославии распавшейся на +381 +382 +385 +386 +387 +389. Украинский +380 появился позднее.
Друзья, хочу обратить ваше внимание на то, что применение плагина не ограничивается телефонными номерами. Я старался решить задачу в общем виде, поэтому данный плагин может использоваться, например, при вводе данных документа, удостоверяющего личность, регистрационного номера транспортного средства и т.д. Список масок ввода для различных областей, при возникновении в этом потребности, будет пополняться. Pull request'ы приветствуются :).
Добавлена информация по США и Канаде, скорректированы маски ввода по Белоруссии, Украине, Казахстану и Казани. Для мобильных определение оператора по коду делать не стал — нетривиальная эта задача и слишком избыточный набор масок получается. Маски ввода для этой цели плохо подходят — пока что для мобильных в демо добавил общую заглушку. А с учётом намечающейся отмены привязки к оператору данная задача вообще отпадает.
Здорово! :)

Касательно выбора текущей страны (а ещё лучше и языка подсказок) — думаю, данный функционал рациональнее реализовать вне плагина. Т.е. при инициализации плагина выполнять определение и инициализировать соответствующим образом плагин.

Идея, безусловно, неплохая и достойна внимания. Попробуйте реализовать и я включу это в примеры использования плагина.
Да такой пример было бы мега удобен, чтобы делать поля в формах для телефонов чемто похожие на Google
accounts.google.com/SignUp?hl=ru
Круто! Плагин хорош, но почему нельзя убрать "+" и поставить «8»?
Если Вы за то, чтобы вводить 8 — никто Вам не запрещает исправить список масок ввода. Однако в таком случае Вы сосредотачиваетесь только на России и я очень часто видел, что 8 вообще в таком случае опускают, оставляя маску (___)___-__-__.

В настоящий момент сделать нестираемую цифру 8, к сожалению, не получится — такова особенность реализации. Это будет возможно сделать когда появится реальная потребность.
речь о том, чтобы она была стираемой, чтобы пользователь мог при желании ввести +7 и 8
А как в таком случае отличить 8 в качестве выхода на межгород от +8 в качестве первой цифры кода страны?

Если организовать список масок, продублировав каждую с 8 и +7, возможно это будет решением Вашей задачи. Но из-за описанной выше неоднозначности возможно некорректное поведение в ряде случаев. Попробуйте.

С другой стороны, непонятен смысл такого решения. Да, пользователям вводить будет удобнее, но будет ли Вам удобно потом обрабатывать то что ввели таким образом пользователи? На мой взгляд, если у вас аудитория только из России, то разрешать ввод и +7, и 8 не имеет смысла.
Плагин отличный, только не работает в IE8.
Проблема в отсутствии поддержки в этом «замечательном» браузере встроенной функции Object.keys();
Плагин доработан. Теперь плагин работает начиная с IE7.
Плагин действительно отличный, намного удобнее чем другие реализации, но есть один недочет:

одни привыкли указывать номер с ведущей цифрой 8

Что-то демо-версия плагина таких привыкших не особо любит, начинаешь набирать и сразу в корею или японию отсылает.
Может быть сделать чтобы при наличии первой цифры 8 подставлялось +7 и Россия?
Попробуйте например вставить мегафоновский номер через буфер туда: 89201234567 — от него останется только +81 и всё. Сможете это как-то поправить?
В fork'е кто-то (может, Вы?) такое уже предложили. Однако мне потребуется доработать предлагаемое решение, чтобы это не выглядело как хардкод, чтобы использование плагина не было слишком заточено под телефонные номера и оставалась возможность его использования НЕ только по назначению (для телефонных номеров).

Думаю, этот недочёт удастся решить путём предопределения списка замен на уровне регулярок. Вероятно же, что позже появится предложение 00 заменять на + :-). Да и, в зависимости от страны, замену 0 на +код появится возможность сделать (зависит от страны).
К сожалению не я ;) А можете дать ссылку на этот форк? Пока в вашей версии это не реализовано — хотя бы форк поиспользую ;)

И ещё предложение появилось — создать массив, который содержит только страны России и СНГ + города России — это будет полезно для магазинов, которые преимущественно продают в России, но иногда получают заказы из СНГ, как например мой магазин ;)

Сейчас из готовых файлов есть только города россии или только страны. Для себя решил это дополнив массив phones-ru.json строками:
	{ "mask": "+374(###)###-###", "region": "Армения", "city": "", "operator": "", "desc": "" },
	{ "mask": "+994(###)###-###", "region": "Азербайджан", "city": "", "operator": "", "desc": "" },
	{ "mask": "+995(###)###-###", "region": "Грузия", "city": "", "operator": "", "desc": "" },
	{ "mask": "+375(###)###-###", "region": "Беларусь", "city": "", "operator": "", "desc": "" },
	{ "mask": "+380(###)###-###", "region": "Украина", "city": "", "operator": "", "desc": "" },
	{ "mask": "+371(###)###-###", "region": "Латвия", "city": "", "operator": "", "desc": "" },
	{ "mask": "+370(###)###-###", "region": "Литва", "city": "", "operator": "", "desc": "" },
	{ "mask": "+373(###)###-###", "region": "Молдова", "city": "", "operator": "", "desc": "" },
	{ "mask": "+996(###)###-###", "region": "Киргизия", "city": "", "operator": "", "desc": "" },
	{ "mask": "+993(###)###-###", "region": "Туркмения", "city": "", "operator": "", "desc": "" },
	{ "mask": "+372(###)###-###", "region": "Эстония", "city": "", "operator": "", "desc": "" },
	{ "mask": "+998(###)###-###", "region": "Узбекистан", "city": "", "operator": "", "desc": "" }

Может ещё кому пригодится.
Форк нашёл, при вставке из буфера он действительно работает, но при наборе не дает ввести цифру 8, я думаю это введет в ступор «особо одаренных» пользователей, поэтому решил данную проблему спец. маской:
        { "mask": "8(9##)###-##-##", "type": "mobile" },
А можно ли как-то сделать отложенную загрузку файла phones-ru.json? Он занимает порядка 326 кб, а нужен только в случае когда пользователь начинает набирать номер?

Не хотелось бы при каждой загрузке страницы тягать на комп клиента и парсить такой большой файл…
Проблему может частично решить сокращенный файл только с областями России, я думаю раз в 10 сократит объем файла такое объединение.

Или другой вариант — парсить строку на этапе ввода, но тут уже без серверной части (на php или ещё чем-либо) не обойдёшься наверно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории