Статические и динамические маски

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

В контексте Inputmask статическая маска задаётся строкой, где используются специальные токены:

  • 9 — обязательная цифра
  • a — обязательная буква
  • * — любой символ
  • фиксированные символы (например, +, (, ), -, пробелы) — литералы, не изменяющиеся при вводе

Пример типичной статической маски для телефона:

Inputmask("+7 (999) 999-99-99").mask(inputElement);

В этом случае структура ввода жёстко зафиксирована:

  • код страны всегда +7
  • скобки всегда присутствуют
  • пробелы и дефисы являются частью шаблона
  • пользователь может вводить только цифры в позициях 9

Любое отклонение от структуры предотвращается библиотекой, что обеспечивает единообразие формата данных.

Статические маски широко применяются в сценариях, где формат строго регламентирован:

  • телефонные номера в фиксированном формате
  • даты в заданной структуре
  • индексы и коды
  • банковские реквизиты с неизменной длиной

Пример маски даты:

Inputmask("99.99.9999").mask(dateInput);

Здесь каждая позиция строго определена: две цифры дня, две месяца и четыре года.

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


Динамические маски

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

Ключевое отличие от статических масок заключается в том, что структура ввода может адаптироваться в процессе редактирования поля.


Альтернативные маски (массивы шаблонов)

Одним из базовых способов реализации динамического поведения является передача массива масок. В этом случае Inputmask автоматически выбирает подходящий вариант в зависимости от введённых данных.

Inputmask({
  mask: ["+7 (999) 999-99-99", "+380 (99) 999-99-99"]
}).mask(phoneInput);

В данном примере поддерживаются два формата:

  • российский номер
  • украинский номер

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

Такой подход особенно эффективен при работе с международными форматами, где структура номера зависит от кода страны.


Динамическая длина и необязательные блоки

Inputmask поддерживает использование необязательных сегментов, которые позволяют одной маске покрывать несколько вариантов длины.

Inputmask("9999-9999999[9]").mask(serialInput);

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

Более сложный пример:

Inputmask("(999) 999-99-99[9]").mask(phoneInput);

Такая конструкция позволяет вводить как стандартный номер, так и расширенный вариант без изменения самой маски.


Маски с функцией-генератором

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

Inputmask({
  mask: function () {
    return isCompanyNumber ? "999-999-999" : "+7 (999) 999-99-99";
  }
}).mask(inputElement);

Функция позволяет учитывать внешние условия:

  • тип пользователя
  • выбранную страну
  • режим формы
  • состояние интерфейса

Такой подход обеспечивает полную адаптивность, но требует контроля за изменением условий, так как маска может изменяться во время ввода.


Альтернативные группы символов (alternator)

Механизм alternator позволяет задавать несколько вариантов внутри одной маски без использования массива.

Inputmask("(999) 999-99-99|+7 999 999 99 99").mask(phoneInput);

Символ | разделяет альтернативные структуры. Inputmask выбирает подходящий вариант в зависимости от вводимых данных.

Alternator удобен, когда необходимо объединить несколько форматов в одну логическую маску без явного разделения на массив.


Регулярные маски

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

Inputmask({
  regex: "[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}"
}).mask(emailInput);

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

Регулярные маски применяются там, где структура данных не может быть описана фиксированной последовательностью символов:

  • email
  • сложные идентификаторы
  • пользовательские форматы

Динамическое поведение через определения символов

Inputmask позволяет расширять стандартные токены через definitions, что также используется в динамических сценариях.

Inputmask({
  mask: "99-AAA-***",
  definitions: {
    A: {
      validator: "[A-Za-z]",
      cardinality: 1
    }
  }
}).mask(codeInput);

Здесь создаётся пользовательский тип символа A, который может быть использован в маске как динамическая единица.

Расширенные определения позволяют:

  • изменять правила валидации
  • создавать контекстно-зависимые символы
  • комбинировать числовые и текстовые ограничения

JIT-режим и частичная активация маски

В динамических сценариях важную роль играет механизм lazy или JIT (just-in-time) активации. Он позволяет применять ограничения только к введённым символам, не перегружая интерфейс заранее.

Inputmask({
  mask: "9999 9999 9999 9999",
  jitMasking: true
}).mask(cardInput);

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

Это особенно полезно для длинных последовательностей, где полное отображение шаблона может ухудшать UX.


Комбинирование статических и динамических подходов

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

Inputmask({
  mask: "+7 (999) 999-99-99[ x999]",
  placeholder: "_"
}).mask(phoneInput);

Основная часть номера остаётся статической, а добавочный номер является динамическим и опциональным.

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


Приоритеты и разрешение конфликтов в динамических масках

При использовании нескольких вариантов масок Inputmask применяет внутреннюю систему приоритизации:

  1. Наиболее специфичный формат (по совпадению начальных символов)
  2. Маска с наибольшей степенью соответствия введённым данным
  3. Первая подходящая маска в списке

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


Поведение маски при редактировании

Динамические маски сохраняют целостность структуры даже при вставке, удалении или перемещении курсора. При изменении данных происходит пересчёт допустимых позиций символов.

Особое значение имеет обработка:

  • вставки из буфера обмена
  • автозаполнения браузером
  • программного изменения значения поля

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