Использование функций для генерации масок

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


Общая модель функциональных масок

Функциональная маска в Inputmask может быть представлена как:

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

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


Сигнатура и контекст выполнения

Функции генерации маски обычно получают доступ к параметрам состояния:

  • текущее значение input;
  • объект опций Inputmask;
  • позиция курсора;
  • служебные данные маскировщика;
  • пользовательские метаданные.

Типичная форма:

const maskFunction = function (opts) {
    return "+7 (999) 999-99-99";
};

В расширенном варианте:

const maskFunction = function (opts) {
    if (opts && opts.country === "kz") {
        return "+7 (700) 000-00-00";
    }
    return "+1 (999) 999-9999";
};

Динамическая генерация на основе условий

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

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

Пример выбора формата телефона:

const phoneMask = function (opts) {
    switch (opts.region) {
        case "ru":
            return "+7 (999) 999-99-99";
        case "us":
            return "+1 (999) 999-9999";
        case "de":
            return "+49 9999 999999";
        default:
            return "+9{1,3} 999 999 9999";
    }
};

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


Использование вычисляемых значений

Функции могут формировать маску на основе уже введённых данных. Это позволяет строить адаптивные структуры, например:

  • переключение длины номера;
  • изменение количества блоков;
  • динамическое добавление сегментов.

Пример изменения длины по первому символу:

const dynamicMask = function (opts) {
    const value = opts.value || "";

    if (value.startsWith("8")) {
        return "9 (999) 999-99-99";
    }

    if (value.startsWith("7")) {
        return "+7 (999) 999-99-99";
    }

    return "+9{1,3} (999) 999-9999";
};

Такой подход позволяет учитывать частично введённые данные ещё до завершения ввода.


Возврат объекта конфигурации

Функции генерации маски могут возвращать не только строку, но и объект с параметрами:

const configMask = function (opts) {
    return {
        mask: "+7 (999) 999-99-99",
        placeholder: "_",
        showMaskOnHover: false
    };
};

Это позволяет централизованно управлять:

  • шаблоном ввода;
  • визуальным поведением;
  • правилами отображения заполнителей.

Композиция функций и вложенные генераторы

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

const getPhoneMaskByCountry = function (country) {
    if (country === "kz") return "+7 (700) 000-00-00";
    if (country === "ru") return "+7 (999) 999-99-99";
    return "+1 (999) 999-9999";
};

const maskFactory = function (opts) {
    return getPhoneMaskByCountry(opts.country);
};

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


Генерация маски на основе длины значения

Один из частых сценариев — адаптация структуры под количество введённых символов:

const lengthBasedMask = function (opts) {
    const len = (opts.value || "").length;

    if (len <= 3) return "999";
    if (len <= 6) return "999-999";
    return "999-999-9999";
};

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


Использование функций в алиасах

Функциональная генерация масок часто интегрируется через alias-конфигурации:

Inputmask.extendAliases({
    dynamicPhone: {
        mask: function (opts) {
            if (opts.country === "ru") {
                return "+7 (999) 999-99-99";
            }
            return "+9{1,3} (999) 999-9999";
        }
    }
});

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


Работа с асинхронными данными (паттерн предзагрузки)

Хотя сама функция маски синхронна, часто используется внешний слой, который подготавливает параметры:

  • загрузка профиля пользователя;
  • получение региона через API;
  • определение типа устройства;
  • получение бизнес-правил.

После получения данных вызывается инициализация:

fetch("/api/user-settings")
    .then(r => r.json())
    .then(data => {
        Inputmask({
            mask: function () {
                return data.phoneFormat;
            }
        }).mask(document.querySelector("input"));
    });

Функция выступает как адаптер между внешними данными и механизмом маскирования.


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

При использовании функций генерации важно учитывать порядок переопределения:

  • глобальные настройки Inputmask;
  • alias-конфигурации;
  • локальная функция mask;
  • runtime-обновления.

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


Ограничения функционального подхода

Несмотря на гибкость, функциональная генерация масок имеет особенности:

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

Поэтому часто применяется баланс между статическими масками и вычисляемыми функциями.


Практика построения устойчивых генераторов

Устойчивые генераторы масок обычно следуют ряду принципов:

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

Пример структурированного подхода:

const masks = {
    ru: "+7 (999) 999-99-99",
    us: "+1 (999) 999-9999"
};

const getMask = function (country) {
    return masks[country] || "+9{1,3} (999) 999-9999";
};

const dynamicMask = function (opts) {
    return getMask(opts.country);
};

Расширение поведения через параметры

Функции могут учитывать дополнительные параметры:

  • режим редактирования;
  • тип устройства;
  • роль пользователя;
  • состояние формы;
  • контекст UI.
const contextualMask = function (opts) {
    if (opts.readonly) {
        return "*{+} 999 999 9999";
    }

    if (opts.mode === "international") {
        return "+999 (999) 999-999";
    }

    return "+7 (999) 999-99-99";
};

Связь с пользовательским вводом

Функциональные маски тесно связаны с потоком ввода. Изменение значения может приводить к:

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

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