Условная логика в масках

Принцип условного поведения в Inputmask

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

Ключевые механизмы:

  • альтернативные маски (multi-mask)
  • условные определения символов (definitions)
  • функциональные маски (dynamic mask functions)
  • регулярные выражения внутри сегментов
  • переключение правил на основе введённых данных

Альтернативные маски как основа ветвления

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

Inputmask({
  mask: [
    "+7 (999) 999-99-99",
    "+1 (999) 999-9999"
  ]
}).mask("#phone");

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


Жадность маски и влияние на выбор ветки

Параметр greedy влияет на то, насколько строго библиотека придерживается первой подходящей маски.

Inputmask({
  mask: [
    "999-999",
    "9999-9999"
  ],
  greedy: false
}).mask("#code");

При greedy: false Inputmask допускает более гибкое сопоставление, позволяя переключение между альтернативами даже при частично заполненном вводе. При true выбор фиксируется раньше, что уменьшает вероятность динамического изменения структуры.


Условные определения символов (definitions)

Основной инструмент точечной условной логики — расширение набора символов через definitions. Каждый символ может содержать функцию-валидатор, возвращающую допустимость ввода.

Inputmask({
  mask: "A*-999",
  definitions: {
    "A": {
      validator: "[A-ZА-Я]",
      casing: "upper"
    },
    "*": {
      validator: function (ch) {
        return ch !== "0";
      }
    }
  }
}).mask("#field");

Здесь реализуются два уровня условности:

  • проверка диапазона символов через регулярное выражение;
  • функциональная проверка произвольного условия.

Функция validator позволяет вводить любые логические ограничения: длину, диапазоны символов, исключения, контекстные правила.


Функциональные маски

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

Inputmask({
  mask: function () {
    return this.value.startsWith("8")
      ? "8 (999) 999-99-99"
      : "+7 (999) 999-99-99";
  }
}).mask("#phone");

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

Типичные сценарии:

  • выбор страны по первой цифре номера;
  • переключение формата даты;
  • адаптация под длину идентификатора;
  • изменение структуры в зависимости от префикса.

Условные сегменты внутри одной маски

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

Inputmask("999-9999[9]").mask("#number");

Сегмент в квадратных скобках активируется только при наличии дополнительного символа. Это позволяет:

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

Многоуровневая логика через повторяющиеся группы

Комбинирование групп и альтернатив позволяет строить более сложные условия.

Inputmask({
  mask: "999{.999}{.9999}"
}).mask("#version");

Здесь фигурные группы могут интерпретироваться как повторяемые сегменты, активируемые при продолжении ввода. Это создаёт эффект каскадного расширения формата.


Контекстное поведение через события

Условная логика может быть реализована через события жизненного цикла маски:

  • onBeforePaste
  • onBeforeMask
  • onKeyValidation
  • onUnMask

Пример динамической трансформации входного значения:

Inputmask({
  mask: "9999-9999",
  onBeforePaste: function (pastedValue) {
    if (pastedValue.includes("+")) {
      return pastedValue.replace("+", "");
    }
    return pastedValue;
  }
}).mask("#card");

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


Переключение масок на основе состояния поля

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

const el = document.querySelector("#input");

const im = new Inputmask({
  mask: "999-999"
}).mask(el);

el.addEventListener("input", () => {
  if (el.value.length > 3) {
    im.setOptions({
      mask: "9999-9999"
    });
  }
});

Такой подход используется при необходимости:

  • изменять формат по длине ввода;
  • учитывать внешние параметры (например, выбор пользователя);
  • реагировать на серверные подсказки.

Регулярные выражения как форма условной логики

Встроенные regex-маски позволяют задавать сложные условия проверки.

Inputmask({
  mask: "Regex",
  regex: "[A-Za-z0-9]{5,10}"
}).mask("#id");

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

Использование regex целесообразно при:

  • переменной длине;
  • сложных правилах состава символов;
  • отсутствии необходимости структурного форматирования.

Каскадные условия и приоритеты

При наличии нескольких уровней условий Inputmask использует следующий порядок приоритета:

  1. явное соответствие текущей маске;
  2. альтернативные маски;
  3. функциональная маска;
  4. fallback через regex;
  5. локальные необязательные сегменты.

Этот порядок определяет предсказуемость поведения при неоднозначном вводе.


Контекстные ограничения через кастомные валидаторы

Функции валидатора могут учитывать не только текущий символ, но и состояние всей строки.

Inputmask({
  mask: "999-AAA",
  definitions: {
    "A": {
      validator: function (ch, buffer, pos) {
        return buffer.join("").indexOf("0") === -1;
      }
    }
  }
}).mask("#code");

Такие проверки позволяют вводить зависимости между позициями символов, реализуя сложную условную структуру:

  • запрет символов при наличии определённых значений;
  • зависимость последующих символов от предыдущих;
  • контекстные ограничения по позиции.

Динамическое форматирование на основе длины ввода

Часто условная логика базируется на длине уже введённого значения.

Inputmask({
  mask: function (input) {
    return input.length > 6
      ? "9999 9999 9999 9999"
      : "999 999 999";
  }
}).mask("#account");

Такой подход применяется для:

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

Комбинирование всех уровней условности

На практике условная логика редко ограничивается одним механизмом. Чаще используется комбинация:

  • альтернативных масок для базового ветвления;
  • функциональной маски для контекста;
  • definitions для точечных правил;
  • событий для предобработки;
  • regex для универсальных случаев.
Inputmask({
  mask: [
    "999-9999",
    "+7 (999) 999-99-99",
    function () {
      return "9999-9999-9999";
    }
  ],
  definitions: {
    "9": {
      validator: "[0-9]"
    }
  },
  onBeforeMask: function (value) {
    return value.replace(/\s/g, "");
  }
}).mask("#multi");

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