Здравствуйте, дорогие читатели!

Я как всегда с сюрпризом) В этой статье я покажу Вам, как можно сделать поле для ввода телефона, но не простое а золотое, с маскировкой и проверкой.

Маскируем и проверяем поле телефона с помощью jQuery

Что такое маскировка поля? Наверняка Вы уже сталкивались с такой штукой, что у поля телефона есть такая вот подсказка +38 (___) ___ __ __ — именно она и называется маскировкой. Преимущество маскировки над обычным тегом placeholder заключается в том, что она не исчезает после клика по заполняемому полю. Для реализации такой штуки новый велосипед мы изобретать не будем а используем готовое решение в виде jQuery плагина Masked Input — этот плагин реально крутой и получил очень широкое распространение во всем мире.

Разметка формы

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

<form action="#" method="post" class="phone_form">
	
	<div class="user_phone">
		<input type="text" placeholder="(___) ___ __ __" id="user_phone" class="rfield" />
	</div>
	
	<input type="submit" class="btn_submit" />
	
</form>

Стилизация формы

Полю для телефона я присвоил идентификатор #user_phone, и обернул его дополнительным дивом, чтобы добавить с помощью псевдоэлемента :before код страны (в моем случае Украины +38, Вы можете добавить свой, но учтите что тогда нужно увеличить или уменьшить отступ слева у поля телефона, см. ниже стили). Сразу пропишем пару строк стилей для нашей формы:

.phone_form {
	width: 300px;
	margin: 50px auto;
	position: relative;
}
#user_phone {
	width: 300px;
	box-sizing: border-box;
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	padding: 8px 8px 8px 36px;
	height: 40px;
	border: 1px solid #ccc;
	font-size: 16px;
	color: #363636;
}
#user_phone:focus {
	outline: none;
	border-color: #363636;
}
input#user_phone:-moz-placeholder {
	color: #363636;
}
input#user_phone::-webkit-input-placeholder {
	color: #363636;
}
.user_phone {
	position: relative;
}
.user_phone:before {
	content: "+38";
	display: block;
	height: 40px;
	color: #363636;
	position: absolute;
	top: 6px;
	left: 7px;
	font-size: 16px;
}
.btn_submit {
	height: 30px;
	position: absolute;
	top: 5px;
	right: 5px;
	background: #363636;
	color: #fff;
	border: none;
	width: 120px;
	cursor: pointer;
	transition: all 0.5s;
	-webkit-transition: all 0.5s;
	-moz-transition: all 0.5s;
}
.btn_submit.disabled {
	color: #363636;
	background: #ccc;
}

Как Вы видите я оформил так же тег placeholder, вобще он нужен потому, что обычное поведение плагина это появление маскировки при клике по полю, когда поле теряет фокус то и маскировка тоже исчезает, чтобы такого не происходило я добавил тег placeholder. Здесь ничего сверхъестественного я не написал, поэтому идем дальше и напишем простой jQuery скрипт.

jQuery скрипт

Перед закрывающим тегом body подключим библиотеку jQuery, плагин Masked Input, ну и наш скрипт:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="jquery.maskedinput.min.js"></script>
<script src="script.js"></script>

Теперь, когда мы все подключили, открываем файл script.js и будем в нем писать наш скрипт, но для начала давайте разберем логику работы скрипта. Первым делом мы «повесим» событие mask на поле телефона а проверку заполнености будем осуществлять по приниципу из предыдущей статьи про простую проверку полей формы, только с некоторым изменениями. Приведу листинг скрипта:

(function( $ ){
	
//// ---> Проверка на существование элемента на странице
jQuery.fn.exists = function() {
   return jQuery(this).length;
}

//	Phone Mask
$(function() {
  
  if($('#user_phone').exists()){
    
    $('#user_phone').each(function(){
      $(this).mask("(999) 999-99-99");
    });
    
  }
  
  if($('.phone_form').exists()){
    
    var form = $('.phone_form'),
      btn = form.find('.btn_submit');
    
    form.find('.rfield').addClass('empty_field');
  
    setInterval(function(){
    
      if($('#user_phone').exists()){
        var pmc = $('#user_phone');
        if ( (pmc.val().indexOf("_") != -1) || pmc.val() == '' ) {
          pmc.addClass('empty_field');
        } else {
            pmc.removeClass('empty_field');
        }
      }
      
      var sizeEmpty = form.find('.empty_field').size();
      
      if(sizeEmpty > 0){
        if(btn.hasClass('disabled')){
          return false
        } else {
          btn.addClass('disabled')
        }
      } else {
        btn.removeClass('disabled')
      }
      
    },200);

    btn.click(function(){
      if($(this).hasClass('disabled')){
        return false
      } else {
        form.submit();
      }
    });
    
  }

});

})( jQuery );

Как Вы смогли заметить, у скрипта добавился такой вот блок:

 if($('#user_phone').exists()){
   var pmc = $('#user_phone');
   if ( (pmc.val().indexOf("_") != -1) || pmc.val() == '' ) {
     pmc.addClass('empty_field');
   } else {
     pmc.removeClass('empty_field');
   }
 }

В этом куске кода с помощью условий мы проверяем: если в поле есть знак «_» или оно пустое, то полю телефона добавляется класс empty_field, в противном случае это класс удаляется, функция setInterval() подхватывает это изменение практически мгновенно и кнопка сабмита формы стает активной.

Мобильная проверка поля телефона

Казалось все реально круто и красиво. Но как говорится мечтать не вредно, на сцену выходя мобильные браузеры и кто еще не сталкивался, тот столкнется с той проблемой, что javascript в них работает не ахти, тоесть нифига нормально не работает и это печально, однако не все потеряно. Благодаря HTML5 в арсенале верстальщика есть браузерные средства проверки полей формы и радует то, что мобильные браузеры их поддерживают!

Браузерная проверка очень простая, не нужно писать никаких скриптов, достаточно в разметке формы указать аттрибут required полю, которое обязательно для заполнения, стандартно это выглядит так:

<form action="#" method="post" class="phone_form">
	
	<div class="user_phone">
		<input type="tel" placeholder="(___) ___ __ __" id="user_phone" required />	
	</div>
	
	<input type="submit" class="btn_submit" />
	
</form>

Тоесть дело остается за малым, нужно организовать проверку откуда пользователь просматривает Ваш проект/сайт, это можно осуществить еще одним очень маленьким jQuery плагином, который называется is.mobile.js (он есть в папке с архивом урока), подключим его там же где и остальные скрипты:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="jquery.maskedinput.min.js"></script>
<script src="is.mobile.js"></script>
<script src="script.js"></script>

Финальный этап

Чтобы не было никаких конфликтов, разметку формы мы сразу пишем для мобильных браузеров:

<form action="#" method="post" class="phone_form">
	
	<div class="user_phone">
		<input type="tel" required pattern="[0-9_-]{10}" title="Формат: (096) 999 99 99" placeholder="(___) ___ __ __" id="user_phone" />	
	</div>
	
	<input type="submit" class="btn_submit" />
	
</form>

В форме все достаточно просто:

  • type="tel" — указываем что это поле для ввода телефона
  • required — обязательное поле
  • pattern="[0-9_-]{10}" — паттерн поля, цифры 0-9 указывают на то что вводимые символы должны быть цифрами, а {10} — на то что этих цифр должно быть 10
  • title="Формат: (096) 999 99 99" — это пожалуй самое крутое, мало того что подсказка показывается при наведении, она также вылазит если кликнули по кнопке когда ничего не заполнено(см. картинку ниже)

Маскируем и проверяем поле телефона с помощью jQuery, всплывашка HTML5

Туда-сюда, наконец-то мы добрались до того момента, что нужно грамотно оформить наш скрипт, привожу полный листинг файла script.js:

(function( $ ){
	
	//// ---> Проверка на существование элемента на странице
	jQuery.fn.exists = function() {
	   return jQuery(this).length;
	}
	
	//	Phone Mask
	$(function() {
		
    if(!is_mobile()){
    
      if($('#user_phone').exists()){
        
        $('#user_phone').each(function(){
          $(this).mask("(999) 999-99-99");
        });
        $('#user_phone')
          .addClass('rfield')
          .removeAttr('required')
          .removeAttr('pattern')
          .removeAttr('title')
          .attr({'placeholder':'(___) ___ __ __'});
      }
      
      if($('.phone_form').exists()){
        
        var form = $('.phone_form'),
          btn = form.find('.btn_submit');
        
        form.find('.rfield').addClass('empty_field');
      
        setInterval(function(){
        
          if($('#user_phone').exists()){
            var pmc = $('#user_phone');
            if ( (pmc.val().indexOf("_") != -1) || pmc.val() == '' ) {
              pmc.addClass('empty_field');
            } else {
                pmc.removeClass('empty_field');
            }
          }
          
          var sizeEmpty = form.find('.empty_field').size();
          
          if(sizeEmpty > 0){
            if(btn.hasClass('disabled')){
              return false
            } else {
              btn.addClass('disabled')
            }
          } else {
            btn.removeClass('disabled')
          }
          
        },200);

        btn.click(function(){
          if($(this).hasClass('disabled')){
            return false
          } else {
            form.submit();
          }
        });
        
      }
    }

	});

})( jQuery );

Как Вы смогли заметить у нас добавилась проверка if(!is_mobile()) — тоесть когда пользователь зашел на сайт не с мобильного устройства в разметке происходят следующие изменения: удаляются атрибуты title, pattern, required, добавляется класс rfield (проверяемое поле).

Результат

Результат наших усилий можно просмотреть кликнув по кнопке «Демо», чтобы скачать исходники нажмите кнопку «Скачать»:

И на последок пару бонусов: простая проверка полей формы на заполненость и полная проверка полей формы с валидацией email, телефона и чекбоксов!

Заключение

Теперь мы умеем не напрягаясь проверять поле телефона любой формы. Ваши пожелания, полезные и не очень правки моих скриптов, оставляйте вв комментариях! Делитесь статьей в социальных сетях! Спасибо за внимание!

Добавить комментарий:


Комментарии
  1. Junk

    Статья конечно полезная, осталось только сайт сделать, где это может пригодиться.

  2. JAH

    Junk, практически в любом интернет магазине нужно такую штуку делать)

  3. Альйоша

    Красава, автор! Умные вещи в паблике всегда нужны) Даже забыл зачем заходил О_о

  4. ЛЯЛЬКА

    Херня полная это ваша форма тупо не дает вписать номер телефона произвольно, а нужно что бы принимала запись в любой форме а записывало в базу по шаблону ВОТ ЭТО ДРУГОЕ ДЕЛО. А тупо не давать пользователям региться тупыми скриптами это ИДИОТИЗМ.

  5. JAH

    Лялька, покажите Ваше решение. Для регистрации достаточно почты, а в профиле пользователь пусть заполняет телефон как нужно а не в произвольной форме, попробуйте пополнить счет в произвольной форме или перевести денежек с уведомлением, Ваша произвольная форма выдаст перезагрузку страницы и незаполненное поле.. как-то так вроде)

  6. Стар

    При дублировании на одной странице (лендинг) работает корректно только одна форма (поля) у остальных слетает фокус (поля для цифр)

  7. anadikt

    Пытался добавить в в готовую форму, чтоб была проверка номера и написание по шаблону, а именно такого вида (999) 999-99-99, но ничего не помогло, скажите почему?

  8. Андрей

    Подскажите, пожалуйста, как все-таки сделать, чтоб работало несколько полей на странице?

  9. Дмитрий

    Есть вопрос: как сделать что бы вводимый телефон дошел на нужную почту? Я так понял что надо .php обработчик вот сюда вставить Но у меня что-то не получается настроить. Подскажите что надо сделать?

  10. Павел

    Да да да, как сделать что бы введенный телефон отправлялся на указанное мыло…?

  11. JAH

    Павел, Дмитрий, могу для Вас написать пост как аяксом отправлять формы (но тока для WordPress), интересно Вам будет?

  12. Дмитрий

    Да, я бы хотел узнать, как это сделать!

  13. Perperik

    спасибо за статью! один нюанс все таки если не работает на айфоне.. может есть решение?

  14. JAH

    Perperik, возможно в проверке is_mobile() проверять если это iphone через navigator user agent

  15. Евгений

    Вся проблема в том что данная маска работает корректно только если поле для ввода телефона одно если их на странице более одного второй и последующие уже не обрабатываются это БЕДА.

  16. JAH

    Евгений, достаточно вместо id юзать класс и перебирать циклом each

  17. Евгений

    Может вы посоветуете, как в masked input убрать ограничение по длине поля.

  18. Дмитрий

    Прошу исправить статью.
    Телефонного кода страны +38 не существует. Вот ссылка https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D1%82%D0%B5%D0%BB%D0%B5%D1%84%D0%BE%D0%BD%D0%BD%D1%8B%D1%85_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D1%82%D1%80%D0%B0%D0%BD

    Код Украины +380

  19. JAH

    Дмитрий, возможно я не так выразился в посте)
    +38 имеется ввиду что в скобках пишем обычно 3 символа например: (067) поэтому код +38
    сути это не меняет

  20. Роман

    Добрый день! как заменить +38 на +7

  21. JAH

    Роман,

    1. +38 заменить на +7 нужно в стилях в строке content: '+38'
    2. форма отправляется или php или ajax обработчиком
    3. если юзать телефон то скрипт не работает в нем, взамен работает стандартная браузерная проверка
  22. Роман

    Добрый день! Спасибо!
    а вариант php обработчика можете предложить?

  23. Макс

    Вопрос. А если пользователь захочет указать домашний телефон?

  24. JAH

    Макс, имеешь ввиду что код будет не 3-значным?

  25. Макс

    Да, возникла задачка. Номер может быть +7 900 444 44 44, 8 (83342) 4-44-44 или вообще 4-44-44. И я задумался…

  26. JAH

    Макс, тогда лучше без маски, заюзать скрипт который будет разрешать вводить тока цифры в поле а инпуту добавить атрибут maxlength

    jQuery.fn.ForceNumericOnly = function() {
    	return this.each(function() {
    		$(this).keydown(function(e) {
    			var key = e.charCode || e.keyCode || 0;
    			// Разрешаем backspace, tab, delete, стрелки, обычные цифры и цифры на дополнительной клавиатуре
    			return (
    				key == 8 || 
    				key == 9 ||
    				key == 46 ||
    				key == 107 ||
    				(key >= 37 && key <= 40) ||
    				(key >= 48 && key <= 57) ||
    				(key >= 96 && key <= 105)
    			);
    		});
    	});
    }
    

    ну и на инпут повесить:

    $('.required-num').ForceNumericOnly();
    

    пока ниче другого в голову не лезет

  27. Макс

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

  28. Alina

    А если нужно чтобы вместо х была возможность для всех цифр кроме 7,8 .Для нулей [0-9] +380 (Х00) 000-00-00?

  29. test

    Все конечно супер — но де совершенно , у меня в хроме проскакивали при тесте возможность в часть (___) поставить курсор куда угодна если часто клацать именно в разные части этого блока — то получилось написать (_09) надо дорабатывать

  30. JAH

    в данный момент времени почти ушел с jQuery, вместо него юзаю AngularJs и для таких решений использую маску поля на AngularJs

  31. Николай

    Все понял спасибо, но остался вопрос куда надо вписать адрес своей почты, чтоб приходило письмо с сайта?

  32. Макс

    Николай, вы путаете валидацию формы с ее отправкой. Обычно этим занимается php-обработчик, например функция mail().

  33. Николай

    Спасибо! Разобрался скачал простой обработчик PHP и все заработало.

  34. antracit

    Скажите, как сделать чтобы поле с телефоном не очищалось, когда случайно кликаешь мышкой за его пределами?

  35. zzhanka

    antracit, нужно добавить код

    jQuery(function($){
    $(«#product»).mask(«99/99/9999»,{autoclear: false});
    });

    об этом можно почитать в документации: https://github.com/digitalBush/jquery.maskedinput

  36. Виталий

    а как сделать, чтоб в поле можно было вводить только вначале цифры?

    Допустим, маска в инпуте такая +7 (___) ___-__-__ По умолчанию скрипт позволяет вводить цифры с любого положения. Например, после скобок или в другом месте, если поставить туда курсор. Это происходит так +7 (___) _45-_6-8_ Необходимо что-то прописать, чтобы при постановке курсора не в начало, он возвращался в начало строки автоматически и не позволял вводить цифры с неположенного места.

    как такое сделать?