Маска ввода телефона в input на чистом JS

Маска ввода телефона в input на чистом JS Верстка
Маска ввода — это важный инструмент в веб-разработке, который помогает пользователям вводить данные в нужном формате и значительно снижает количество ошибок при заполнении форм. Маски используются для различных полей ввода, таких как номера телефонов, адреса электронной почты, даты, банковские карты и многое другое. В этой статье мы рассмотрим, как реализовать маску ввода для телефона, электронной почты и других данных с использованием популярной библиотеки Imask.js. А так же поделюсь с вами своим небольшим ванильным JS, который весит пару килобайт.

Различные маски ввода при помощи Imask

Imask.js — это легковесная и мощная библиотека для работы с масками ввода. Она поддерживает различные типы масок, такие как числа, строки, даты, регулярные выражения и даже динамические маски. Imask обеспечивает гибкость и простоту использования, благодаря чему она широко используется в веб-разработке.

Преимущества использования Imask:

  1. Легко интегрируется в проект, минимальные настройки.
  2. Поддержка множества типов масок.
  3. Импорт библиотеки не требует большого объема ресурсов.
  4. Корректно работает во всех современных браузерах.

Установка Imask

Для начала нужно установить библиотеку Imask. Это можно сделать через пакетный менеджер npm или yarn:

npm install imask

Также можно подключить библиотеку через CDN:

<script src="https://unpkg.com/imask"></script>

После этого мы можем приступить к настройке масок для различных типов ввода.

Маска для ввода телефона

Самый частый случай использования масок — это ввод номера телефона. Давайте создадим маску для номера телефона с российским форматом +7 (___) ___-__-__.

Пример HTML-кода для поля ввода телефона:

<input type="tel" id="phone" placeholder="Ваш телефон">

Пример JavaScript-кода с использованием Imask для телефона:

var phoneInput = document.getElementById('phone');
var phoneMask = IMask(phoneInput, {
    mask: '+{7} (000) 000-00-00'
});

Здесь mask: '+{7} (000) 000-00-00' — это маска, где 0 обозначает, что пользователь может ввести только цифры. Символы +, пробелы, скобки и дефисы добавляются автоматически. В итоге пользователь видит удобный интерфейс для ввода номера телефона, где система контролирует правильность ввода.

Маска для ввода электронной почты

Хотя маска для электронной почты может показаться сложной, Imask позволяет гибко настраивать правила валидации через регулярные выражения. Для электронной почты чаще всего используется формат вида name@domain.com.

Пример HTML-кода для поля ввода email:

<input type="email" id="email" placeholder="Ваш email">

Пример JavaScript-кода для настройки маски email:

var emailInput = document.getElementById('email');
var emailMask = IMask(emailInput, {
    mask: /^\S*@?\S*$/
});

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

Маска для ввода даты

Дата — еще один важный тип данных, для которого часто требуется маска. Например, для даты можно использовать формат DD/MM/YYYY.

Пример HTML-кода для поля ввода даты:

<input type="text" id="date" placeholder="Дата рождения">

Пример JavaScript-кода для настройки маски даты:

var dateInput = document.getElementById('date');
var dateMask = IMask(dateInput, {
    mask: Date,
    pattern: 'd{.}`m{.}`Y',  // Маска для формата даты
    lazy: false,  // Показать символы маски сразу
    blocks: {
        d: { mask: IMask.MaskedRange, from: 1, to: 31, maxLength: 2 },
        m: { mask: IMask.MaskedRange, from: 1, to: 12, maxLength: 2 },
        Y: { mask: IMask.MaskedRange, from: 1900, to: 2099, maxLength: 4 }
    }
});

В этом примере мы используем маску для даты с диапазонами значений для дня, месяца и года. Это позволяет контролировать, чтобы введенные значения не выходили за пределы допустимого диапазона.

Маска для ввода номера банковской карты

Для ввода номеров банковских карт можно использовать маску вида 0000 0000 0000 0000. Рассмотрим пример настройки такой маски.

Пример HTML-кода для поля ввода карты:

<input type="text" id="card" placeholder="Номер карты">

Пример JavaScript-кода для настройки маски карты:

var cardInput = document.getElementById('card');
var cardMask = IMask(cardInput, {
    mask: '0000 0000 0000 0000'
});

Эта маска позволяет вводить только цифры, разделенные на блоки по 4 цифры для удобства ввода и чтения.

Небольшие выводы по библиотеке и Demo

Библиотека Imask.js предоставляет простой и мощный способ добавления масок ввода к вашим формам. Она поддерживает множество типов данных и масок, а также легко настраивается под любые нужды проекта.

Смотреть Demo

Если вы любите хардкор и не хотите использовать библиотеки или вас чем то не устраивает сама маска, тогда альтернативное решение чисто для маски ввода телефона, которое использую я (вес всего 3,5 кб), ниже.

Маска ввода телефона без доп. библиотек и зависимостей

Вот вам решение которое использую я, смотрите демо, чтобы посмотреть как оно работает.

Смотреть demo

HTML разметка

Любой input у которого есть класс tel, например:

<input value="" class="tel">

JS код маски

Не забудьте заключить его в: <script> код </script>:

document.addEventListener("DOMContentLoaded", function () {
    var phoneInputs = document.querySelectorAll('input.tel');

    var getInputNumbersValue = function (input) {
        // Возвращаем только цифры из введенного значения
        return input.value.replace(/\D/g, '');
    }

    var onPhonePaste = function (e) {
        var input = e.target,
            inputNumbersValue = getInputNumbersValue(input);
        var pasted = e.clipboardData || window.clipboardData;
        if (pasted) {
            var pastedText = pasted.getData('Text');
            if (/\D/g.test(pastedText)) {
                // При вставке некорректного символа оставляем только цифры
                input.value = inputNumbersValue;
                return;
            }
        }
    }

    var onPhoneInput = function (e) {
        var input = e.target,
            inputNumbersValue = getInputNumbersValue(input),
            selectionStart = input.selectionStart,
            formattedInputValue = "";

        if (!inputNumbersValue) {
            return input.value = "";
        }

        if (input.value.length != selectionStart) {
            // Если редактируем не в конце поля
            if (e.data && /\D/g.test(e.data)) {
                // Если вводим не числовой символ
                input.value = inputNumbersValue;
            }
            return;
        }

        if (["7", "8", "9"].indexOf(inputNumbersValue[0]) > -1) {
            if (inputNumbersValue[0] == "9") inputNumbersValue = "7" + inputNumbersValue;
            var firstSymbols = (inputNumbersValue[0] == "8") ? "8" : "+7";
            formattedInputValue = input.value = firstSymbols + " ";
            if (inputNumbersValue.length > 1) {
                formattedInputValue += '(' + inputNumbersValue.substring(1, 4);
            }
            if (inputNumbersValue.length >= 5) {
                formattedInputValue += ') ' + inputNumbersValue.substring(4, 7);
            }
            if (inputNumbersValue.length >= 8) {
                formattedInputValue += '-' + inputNumbersValue.substring(7, 9);
            }
            if (inputNumbersValue.length >= 10) {
                formattedInputValue += '-' + inputNumbersValue.substring(9, 11);
            }
        } else {
            formattedInputValue = '+' + inputNumbersValue.substring(0, 16);
        }
        input.value = formattedInputValue;
    }

    var onPhoneKeyDown = function (e) {
        // Удаление последнего символа очищает поле
        var inputValue = e.target.value.replace(/\D/g, '');
        if (e.keyCode == 8 && inputValue.length == 1) {
            e.target.value = "";
        }
    }

    var onPhoneFocus = function (e) {
        var input = e.target;
        if (input.value === "") {
            input.value = "+7 "; // Устанавливаем начальное значение
            input.setSelectionRange(3, 3); // Устанавливаем курсор после +7
        }
    }

    for (var phoneInput of phoneInputs) {
        phoneInput.addEventListener('keydown', onPhoneKeyDown);
        phoneInput.addEventListener('input', onPhoneInput, false);
        phoneInput.addEventListener('paste', onPhonePaste, false);
        phoneInput.addEventListener('focus', onPhoneFocus); // Добавляем обработчик focus
    }
});
Скачать js скрипт маски ввода

История изменений:

  1. Код переписан полностью

Заключение

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

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

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 10 оценок, среднее 4.2 из 5 )
Web-Revenue.ru
Добавить комментарий

  1. Даниил

    Подскажите почему в модальном окне imask не инициализируется? Где то прочитал что надо два раза инициализировать. Как это делается? Или я ошибаюсь?

    Ответить
    1. Алексей автор

      Честно говоря не знаю, т.к. я в основном пользуюсь 2м решением «Маска ввода телефона без доп. библиотек и зависимостей». Закиньте свой код в codepen к примеру и дайте ссылку, я посмотрю

      Ответить
  2. Ваня

    Алексей,маска работает некорректно. Курсор прыгает не пойми куда, при вводе номера вообще ужас. Надо доработать маску однозначно.

    Ответить
    1. Алексей автор

      Согласен, самый первый вариант был лучше, с доработками стал больше и корявее) В общем решил полностью переписать JS + добавил в статью альтернативный вариант. В общем заходите, оценивайте, пользуйтесь)))

      Ответить
  3. Алексей

    Спасибо большое за рабочий код! В своем кейсе заметил, что если нажать на поле input и перевести курсор перед +7, то нет помощи в переводе на нужное место для начала ввода данных. Если не трудно, подскажите пожалуйста как это сделать?

    Ответить
    1. Алексей автор

      Обновил немного код, добавил строку this.setSelectionRange(pos, pos); — теперь такой проблемы не наблюдаю

      Ответить
  4. Иван

    Если выделить полностью и удалить/вырезать данные в поле, то форма не очищается вообще.
    Было бы неплохо, чтобы после полной очистки поля удалялось все и заново заполнялось +7 в начале

    Ответить
    1. Алексей автор

      Сделал, версия кода добавлена в статью (демо не делал для нее)))

      Ответить
  5. Кир

    Огромное спасибо! Ты сэкономил мне пару часов жизни!

    Ответить
    1. Алексей автор

      Всегда пожалуйста)))

      Ответить
  6. Pavel

    Молодец, чувак, но твоя маска сыро вата..
    ну форматирует данные, а если не до конца введено, то ей пофигу))
    вспомни как $.mask() работает)))

    Ответить
    1. Алексей автор

      Для моих целей достаточно, главное что страницу не грузит (пару строк кода), а проверку на количество символов я обычно модулями CMS делаю (чтобы форма не отправлялась с неполным номером). Так же можно прямо средствами HTML проверять, импуту укажите minlength="13".

      Ответить
  7. Айрат

    Спасибо, очень удобно что без сторонних библиотек используется!

    Ответить
    1. Алексей автор

      Пожалуйста, пользуйтесь)

      Ответить
  8. Олег

    Здравствуйте, если использовать автозаполнение на ios, то номер не полностью стирается. Багует с номером вида +7 (000) 000-00-00

    Ответить
    1. Алексей автор

      Здравствуйте. Поправил в коде 2 строчки. Теперь код должен корректно стирать номер телефона при использовании автозаполнения на iOS. На данный момент нет девайсов на iOS чтобы проверить. Посмотрите на демо.

      Ответить
  9. Nickulas

    все ок, но как решить проблему, что при редактировании номера новые символы печатаются в конце строки, а не на месте старых? при этом, с последними 4 символами все ок

    Ответить
  10. 433

    alert(‘воу’)

    Ответить
  11. Виктор

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

    Ответить
  12. Аноним

    Спасибо! Изучаю JS, и Ваш скрипт очень помогает узнать что-то новое.

    Ответить
    1. Голягин Алексей

      Пожалуйста)

      Ответить
  13. Аноним

    Спасибо! На лендинге форма в шапке работает.
    Если не сложно, ответьте, пожалуйста.
    Вопросы:
    1. На popup при подключенных файлах скриптов перестала вообще отправляться форма, хотя и пишет, что ОТПРАВЛЕНО
    2. Как бы сделать еще проверку на ПОЛНОСТЬЮ введенный телефон, чтобы пользователи не могли 3 символа по маске отправить.

    Ответить
    1. Голягин Алексей

      Ну как вариант, попробуйте так:

      Ответить
  14. Аноним

    Спасибо!

    Ответить