Валидация перед отправкой

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

Библиотека AutoNumeric хранит внутри поля сразу два представления данных: отформатированное (для пользователя) и «сырое» числовое (для логики приложения). Ошибка на этапе валидации чаще всего возникает при попытке отправить именно отформатированное значение без предварительного извлечения чистого числа.


Извлечение числового значения из AutoNumeric-инстанса

Основой корректной валидации является работа не с DOM-значением input, а с API экземпляра AutoNumeric.

Ключевые методы:

  • getNumber() — возвращает значение как число (Number)
  • getNumericString() — возвращает строковое представление без форматирования
  • getFormatted() — возвращает значение в отображаемом виде

Пример получения значения:

const anElement = AutoNumeric.getAutoNumericElement('#price');

const rawNumber = anElement.getNumber();
const rawString = anElement.getNumericString();

Использование input.value в данном контексте приводит к получению форматированной строки, содержащей разделители и символы валют, что делает дальнейшую валидацию некорректной.


Проверка на валидность числового значения

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

Типовые случаи некорректных данных:

  • null или undefined после преобразования
  • NaN при некорректном вводе
  • пустое значение при обязательном поле

Проверка реализуется через стандартные механизмы Jav * aScript:

const value = anElement.getNumber();

const isValidNumber = typeof value === 'number' && !Number.isNaN(value);

В сценариях с обязательным вводом добавляется проверка на наличие значения:

const isEmpty = value === null || value === undefined;

Валидация диапазонов значений

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

Часто используемые ограничения:

  • минимальное значение (min)
  • максимальное значение (max)
  • логические границы (например, процент 0–100)

Пример ручной проверки:

const value = anElement.getNumber();

const min = 10;
const max = 500;

const inRange = value >= min && value <= max;

Для денежных значений часто добавляется контроль точности:

const decimals = 2;
const factor = Math.pow(10, decimals);

const isPrecisionValid = Number.isInteger(value * factor);

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

В процессе ввода AutoNumeric может находиться в промежуточных состояниях, особенно при незавершённом вводе числа.

Типовые состояния:

  • пустая строка
  • одиночный минус -
  • точка . без дробной части

Такие значения должны трактоваться отдельно от финального числа.

const formatted = anElement.getNumericString();

const isIntermediate =
  formatted === '' ||
  formatted === '-' ||
  formatted === '.' ||
  formatted === '-.';

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


Интеграция с событием отправки формы

При использовании AutoNumeric важно перехватывать событие отправки формы до фактической передачи данных.

Стандартный подход заключается в принудительном извлечении «сырых» значений и подмене значений input-полей.

const form = document.querySelector('form');

form.addEventListener('submit', (event) => {
  const anElement = AutoNumeric.getAutoNumericElement('#price');

  const value = anElement.getNumber();

  if (value === null || Number.isNaN(value)) {
    event.preventDefault();
    return;
  }

  const hiddenInput = document.querySelector('#price_raw');
  hiddenInput.value = value;
});

Альтернативный подход — отключение форматирования перед отправкой:

anElement.unformat();

После этого input.value становится пригодным для отправки как числовое значение в строковом виде.


Согласование с HTML5 validation API

AutoNumeric не заменяет встроенную HTML-валидацию, но может работать совместно с ней через синхронизацию значений.

Пример использования setCustomValidity:

const input = document.querySelector('#price');
const anElement = AutoNumeric.getAutoNumericElement(input);

const value = anElement.getNumber();

if (value < 0) {
  input.setCustomValidity('Значение не может быть отрицательным');
} else {
  input.setCustomValidity('');
}

После установки кастомного сообщения браузер блокирует отправку формы.


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

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

Примеры зависимостей:

  • сумма двух полей не должна превышать лимит
  • процентное распределение должно давать 100
  • цена должна быть кратна шагу тарификации

Пример проверки суммы:

const a = AutoNumeric.getAutoNumericElement('#a').getNumber();
const b = AutoNumeric.getAutoNumericElement('#b').getNumber();

const limit = 1000;

const isValid = (a + b) <= limit;

Пример процентного контроля:

const p1 = AutoNumeric.getAutoNumericElement('#p1').getNumber();
const p2 = AutoNumeric.getAutoNumericElement('#p2').getNumber();

const total = p1 + p2;

const isValid = total === 100;

Приведение значений к единому формату перед отправкой

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

Основные цели нормализации:

  • устранение плавающих ошибок
  • фиксированная точность
  • единый формат JSON
const value = anElement.getNumber();

const normalized = Number(value.toFixed(2));

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

const cents = Math.round(value * 100);

Типовые ошибки при валидации AutoNumeric

Неправильная работа с данными чаще всего связана с использованием DOM-значения вместо API библиотеки.

Основные ошибки:

  • использование input.value вместо getNumber()
  • отсутствие проверки NaN
  • игнорирование промежуточных состояний ввода
  • дублирование форматированных строк в API запросах
  • отсутствие синхронизации скрытых полей

Некорректный пример:

const value = document.querySelector('#price').value; // строка с форматированием

Корректный вариант:

const value = AutoNumeric.getAutoNumericElement('#price').getNumber();