Обработка ввода с клавиатуры

AutoNumeric реализует обработку клавиатурного ввода через перехват низкоуровневых DOM-событий, формируя контролируемый поток символов, который проходит предварительную валидацию, нормализацию и форматирование до попадания в значение инпута. Основная цель такого подхода — исключить некорректные числовые состояния ещё на этапе ввода, а не постфактум исправлять их.

Ключевой механизм основан на обработке событий keydown, keypress (в legacy-режиме) и input, с дополнительным анализом контекста поля: текущего значения, позиции каретки, выделенного диапазона и активной локали.


Перехват keydown и управление разрешёнными клавишами

На этапе keydown AutoNumeric определяет, является ли нажатая клавиша допустимой в текущем числовом контексте. Внутри формируется классификация клавиш:

  • цифровые символы (0–9)
  • управляющие клавиши (Backspace, Delete)
  • навигация (ArrowLeft, ArrowRight, Home, End)
  • функциональные комбинации (Ctrl/Cmd + C/V/X/A)
  • символы форматирования (десятичный разделитель, знак минус, если разрешён)

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

new AutoNumeric(input, {
    decimalCharacter: ",",
    digitGroupSeparator: " ",
    allowDecimalPadding: true,
    negativePositiveSignPlacement: "l"
});

При обработке клавиши происходит проверка:

  1. Является ли клавиша системной (не влияющей на значение)
  2. Разрешён ли символ в текущей конфигурации
  3. Не нарушает ли добавление символа ограничений (min/max, формат, precision)

Если символ не проходит проверку, вызывается event.preventDefault(), и ввод блокируется до уровня браузера.


Нормализация символов и локализация ввода

AutoNumeric не работает напрямую с сырыми символами клавиатуры. Вместо этого каждый вводимый символ проходит нормализацию:

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

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

decimalCharacter: "."

При вводе запятой , она либо преобразуется в ., либо блокируется, если политика строгая.


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

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

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

После этого происходит пересборка строки:

  1. Удаление форматирующих символов (разделители групп)
  2. Преобразование в “чистое” число
  3. Вставка нового символа
  4. Повторное форматирование результата
  5. Восстановление позиции каретки с учётом добавленных символов

Пример логики вставки:

const rawValue = "12 345.67";
caretPosition = 3;
inputChar = "9";

Результат:

12 9 345.67 (в логическом виде: 129345.67)

AutoNumeric пересчитывает позицию каретки так, чтобы пользователь оставался в ожидаемом месте ввода.


Обработка удаления символов (Backspace и Delete)

Удаление символов в числовом поле существенно сложнее стандартного текстового поведения, поскольку форматирование добавляет “невидимые” символы.

AutoNumeric различает два режима:

Backspace

Удаляет символ слева от каретки, затем:

  • пересчитывает число
  • пересобирает формат
  • корректирует позицию каретки

Delete

Удаляет символ справа от каретки, с аналогичной переработкой состояния

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

1 234 567

При удалении каретка может “перепрыгивать” через пробелы, чтобы избежать их ручного удаления пользователем.


Работа с выделением диапазона

Если пользователь выделяет часть значения и вводит новый символ, AutoNumeric выполняет операцию замены:

  1. Выделенный диапазон удаляется из логического числа
  2. Новый символ вставляется в позицию начала выделения
  3. Выполняется нормализация и форматирование

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


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

Событие paste обрабатывается отдельно от клавиатурного ввода. Причина — вставляемая строка может содержать:

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

Алгоритм обработки:

  1. Получение текста из clipboard
  2. Очистка строки от недопустимых символов
  3. Приведение к единому числовому формату
  4. Проверка на соответствие ограничениям (minimumValue, maximumValue)
  5. Вставка результата в текущее поле
  6. Форматирование отображаемого значения

Пример:

"1 234,56 ₽" → "1234.56"

Composition Events и IME-ввод

Для языков с методом ввода через IME (китайский, японский, корейский) используются события:

  • compositionstart
  • compositionupdate
  • compositionend

AutoNumeric временно отключает строгую валидацию на этапе composition, чтобы не блокировать промежуточные состояния ввода.

Поведение:

  • во время composition ввод не форматируется
  • промежуточные символы не валидируются как число
  • после compositionend выполняется полная нормализация

Это предотвращает ситуацию, при которой IME не может корректно завершить ввод из-за вмешательства форматтера.


Контроль допустимых символов

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

  • цифры всегда разрешены
  • минус — только при allowLeadingHyphen: true
  • десятичный разделитель — только один в числе
  • экспонента — при включённом scientific mode

При попытке ввода второго разделителя AutoNumeric блокирует событие.


Управление отрицательными значениями при вводе

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

Поведение зависит от конфигурации:

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

Логика переключения:

  • если число положительное → добавляется минус
  • если отрицательное → минус удаляется

Синхронизация отображаемого и логического значения

AutoNumeric поддерживает два слоя представления:

  • display value — форматированная строка в input
  • raw value — числовое значение без форматирования

Клавиатурный ввод всегда работает с raw value, после чего результат преобразуется обратно в display value.

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


Конфигурационные параметры, влияющие на ввод

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

  • decimalCharacter
  • digitGroupSeparator
  • allowDecimalCharacterAutoReplace
  • decimalPlaces
  • minimumValue
  • maximumValue
  • allowLeadingHyphen
  • modifyValueOnWheel

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


Обработка быстрых комбинаций клавиш

Поддерживаются стандартные сочетания:

  • Ctrl/Cmd + A — выделение
  • Ctrl/Cmd + C — копирование
  • Ctrl/Cmd + V — вставка
  • Ctrl/Cmd + X — вырезание
  • Tab — переход фокуса

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


Защита от неконсистентных состояний ввода

В процессе быстрого ввода возможны промежуточные состояния:

  • “12..3”
  • “–5”
  • “1 2 3 4”

AutoNumeric не позволяет таким состояниям закрепиться в DOM. Вместо этого используется стратегия:

  1. принять ввод
  2. нормализовать строку
  3. при необходимости откатить изменение
  4. восстановить корректное значение

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