Маски времени

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

Для времени чаще всего используются фиксированные форматы:

  • HH:MM
  • HH:MM:SS
  • 12-часовой формат с AM/PM
  • комбинированные маски даты и времени

Базовая маска задаётся строкой, где каждый символ имеет значение:

  • h, H — часы
  • m — минуты
  • s — секунды
  • 9 — любая цифра
  • 0 — обязательная цифра
  • : — разделитель

Простейшая конфигурация для времени в формате 24 часа:

Inputmask("99:99").mask("#time");

Такая маска ограничивает структуру ввода, но не проверяет логическую корректность диапазонов (например, допускает 29:99).


Жёсткая валидация диапазонов времени

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

Пример ограничения часов (00–23) и минут (00–59):

Inputmask({
  mask: "h:m",
  definitions: {
    "h": {
      validator: "[0-2]",
      cardinality: 1
    },
    "m": {
      validator: "[0-5]",
      cardinality: 1
    }
  }
}).mask("#time");

Такой подход ограничивает ввод на уровне символов, но не формирует полноценную семантическую проверку диапазона (например, 29 всё ещё возможно как 2 и 9).


Маска времени HH:MM с корректным диапазоном

Для более строгой логики применяется комбинированная стратегия: маска + обработка событий.

Inputmask("hh:mm", {
  definitions: {
    "h": {
      validator: function (chrs, maskset, pos, strict, opts) {
        const value = maskset.buffer.join("");
        return /^(?:[01]?\d|2[0-3])$/.test(value.slice(0, 2));
      },
      cardinality: 1
    },
    "m": {
      validator: "[0-5]",
      cardinality: 1
    }
  }
}).mask("#time");

Однако в реальных сценариях чаще используется встроенный механизм alias.


Использование alias datetime

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

Inputmask("datetime", {
  inputFormat: "HH:MM"
}).mask("#time");

Alias автоматически:

  • ограничивает диапазоны
  • управляет разделителями
  • синхронизирует ввод
  • поддерживает автозаполнение

Для секундного формата:

Inputmask("datetime", {
  inputFormat: "HH:MM:ss"
}).mask("#time");

12-часовой формат времени

12-часовой формат требует дополнительного суффикса AM/PM. В Inputmask это реализуется через расширенные настройки datetime alias.

Inputmask("datetime", {
  inputFormat: "hh:MM TT"
}).mask("#time");

Здесь:

  • hh — часы 01–12
  • MM — минуты
  • TT — AM/PM

Важно учитывать, что регистр символов влияет на интерпретацию:

  • hh — 12-часовой формат
  • HH — 24-часовой формат
  • MM — минуты в datetime alias
  • mm — месяцы в date контексте

Разделители и локализация времени

Разделитель времени (:) может быть заменён в зависимости от локали или требований интерфейса.

Inputmask("datetime", {
  inputFormat: "HH-MM",
  placeholder: "__-__"
}).mask("#time");

Важный момент — Inputmask не интерпретирует разделитель как часть времени, он рассматривается как фиксированный литерал.

При необходимости динамического разделителя используется параметр separator:

Inputmask("datetime", {
  inputFormat: "HH:MM",
  separator: ":"
}).mask("#time");

Автозаполнение и поведение при вводе

Inputmask управляет поведением курсора и заполнением полей автоматически. При вводе времени применяются следующие принципы:

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

Пример поведения:

Ввод: 1 → 12:__
Ввод: 12 → 12:__
Ввод: 123 → 12:30

Это достигается за счёт механизма буфера маски, который хранит промежуточное состояние строки.


Обработка неполного ввода времени

Для работы с незавершёнными значениями используется опция clearIncomplete.

Inputmask("datetime", {
  inputFormat: "HH:MM",
  clearIncomplete: true
}).mask("#time");

Поведение:

  • неполное значение очищается при потере фокуса
  • полностью заполненное значение сохраняется
  • частично введённые данные не валидируются как корректные

Маска времени с секундной точностью

Секунды добавляются как третий блок:

Inputmask("datetime", {
  inputFormat: "HH:MM:ss"
}).mask("#time");

Символы:

  • HH — часы
  • MM — минуты
  • ss — секунды

Для ограничения секунд используется стандартный диапазон 00–59, который применяется автоматически.


Кастомная маска времени без alias

В случаях, когда alias не подходит, используется ручное определение маски:

Inputmask("h9:m9:s9", {
  definitions: {
    "h": {
      validator: "[0-2]",
      cardinality: 1
    },
    "m": {
      validator: "[0-5]",
      cardinality: 1
    },
    "s": {
      validator: "[0-5]",
      cardinality: 1
    }
  }
}).mask("#time");

Такой подход применяется в системах, где требуется нестандартная логика или интеграция с серверной валидацией.


Маска времени с шагом (интервалы)

Inputmask не имеет встроенного шага времени, но поведение можно эмулировать через onBeforeMask:

Inputmask("datetime", {
  inputFormat: "HH:MM",
  onBeforeMask: function (value) {
    const date = new Date(value);
    const minutes = Math.round(date.getMinutes() / 5) * 5;
    date.setMinutes(minutes);
    return date.getHours().toString().padStart(2, "0") + ":" +
           date.getMinutes().toString().padStart(2, "0");
  }
}).mask("#time");

Это позволяет округлять ввод до ближайших 5, 10 или 15 минут.


Маска времени в связке с формой

При использовании в формах Inputmask интегрируется с обычными input-элементами HTML:

<input id="time" type="text" />
Inputmask("datetime", {
  inputFormat: "HH:MM",
  showMaskOnHover: false,
  showMaskOnFocus: true
}).mask("#time");

Поведение:

  • маска отображается при фокусе
  • исчезает при потере фокуса (если отключено отображение)
  • предотвращается ввод недопустимых символов

Синхронизация времени между полями

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

Inputmask("datetime", { inputFormat: "HH:MM" }).mask("#startTime");
Inputmask("datetime", { inputFormat: "HH:MM" }).mask("#endTime");

Дальнейшая проверка (например, end > start) выполняется отдельно, но маска гарантирует единый формат данных.


Особенности буфера маски времени

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

  • пусто
  • заполнено пользователем
  • заполнено автоматически
  • заблокировано маской

Для времени это особенно важно, так как:

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

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


Работа с удалением и редактированием

При удалении символов Inputmask не просто удаляет символ, а пересчитывает состояние маски:

  • удаление цифры сдвигает буфер
  • разделители остаются фиксированными
  • недостающие позиции заполняются placeholder-символами

Пример:

12:34 → удалить 3 → 12:4_

Интеграция времени с динамическими масками

Inputmask позволяет переключать маски динамически, что полезно для переключения форматов:

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

Inputmask("datetime", { inputFormat: "HH:MM" }).mask(el);

// переключение
Inputmask.remove(el);
Inputmask("datetime", { inputFormat: "hh:MM TT" }).mask(el);

Это используется в интерфейсах, где пользователь может менять формат времени (24h / 12h).