При работе с числовыми инпутами в веб-приложениях ключевая проблема заключается в различии между отображаемым значением и значением, которое должно уходить на сервер. Библиотека AutoNumeric решает эту задачу за счёт строгого разделения форматированного представления и «чистого» числового значения.
Скрытые поля (hidden inputs) становятся важным инструментом, когда требуется сохранять отформатированное число для пользователя, но передавать на сервер только нормализованное значение без разделителей, символов валюты и локализованных форматов.
Типовая схема интеграции выглядит следующим образом:
Такой подход позволяет:
<input type="text" id="price_display">
<input type="hidden" id="price_raw" name="price">
В этом случае price_display используется только для
ввода и отображения, а price_raw участвует в отправке
формы.
AutoNumeric предоставляет API для получения числового значения в различных форматах:
getNumber()getNumericString()getFormatted()Для работы со скрытым полем чаще всего используется
getNumericString() или getNumber().
const displayInput = document.querySelector('#price_display');
const hiddenInput = document.querySelector('#price_raw');
const anElement = new AutoNumeric(displayInput, {
decimalPlaces: 2,
digitGroupSeparator: ' ',
decimalCharacter: ','
});
Основной механизм обновления скрытого поля — обработка событий изменения значения.
displayInput.addEventListener('input', () => {
hiddenInput.value = anElement.getNumericString();
});
Такой подход обеспечивает:
Более надёжный способ — использовать встроенные события библиотеки AutoNumeric, так как они учитывают все внутренние преобразования.
anElement.domElement.addEventListener('autoNumeric:rawValueModified', () => {
hiddenInput.value = anElement.getNumber();
});
Этот вариант предпочтительнее, поскольку:
При отправке формы важно гарантировать актуальность данных. Даже при наличии событий возможна ситуация, когда значение не синхронизировано (например, при программной установке значения непосредственно перед submit).
const form = document.querySelector('#payment_form');
form.addEventListener('submit', () => {
hiddenInput.value = anElement.getNumericString();
});
Такой «финальный» слой синхронизации делает систему устойчивой к любым сценариям.
В реальных формах часто используется набор числовых полей:
Каждое поле имеет собственную пару display/hidden.
<input id="price_display" type="text">
<input id="price_raw" type="hidden" name="price">
<input id="discount_display" type="text">
<input id="discount_raw" type="hidden" name="discount">
const price = new AutoNumeric('#price_display', { decimalPlaces: 2 });
const discount = new AutoNumeric('#discount_display', { decimalPlaces: 2 });
function syncAll() {
document.querySelector('#price_raw').value = price.getNumber();
document.querySelector('#discount_raw').value = discount.getNumber();
}
При масштабировании формы подобный подход часто инкапсулируется в универсальный менеджер полей.
В SPA и административных интерфейсах поля часто создаются динамически. AutoNumeric позволяет инициализировать новые инстансы на лету.
function createNumericField(displayId, hiddenId) {
const display = document.createElement('input');
const hidden = document.createElement('input');
display.type = 'text';
hidden.type = 'hidden';
document.body.appendChild(display);
document.body.appendChild(hidden);
const an = new AutoNumeric(display, {
decimalPlaces: 2
});
display.addEventListener('autoNumeric:rawValueModified', () => {
hidden.value = an.getNumber();
});
return { display, hidden, an };
}
Основные источники рассинхронизации:
set()Для устранения используется единая точка обновления состояния:
function updateHidden(an, hidden) {
hidden.value = an.getNumber();
}
И применение её во всех сценариях изменения значения.
Важный принцип при работе со скрытыми полями и AutoNumeric заключается в разделении:
Неправильная модель (частая ошибка):
input.value напрямуюКорректная модель:
При отправке данных через AJAX скрытые поля становятся источником истины:
function sendData() {
const payload = {
price: document.querySelector('#price_raw').value,
discount: document.querySelector('#discount_raw').value
};
fetch('/api/order', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
}
Использование скрытых полей снижает нагрузку на клиентскую логику сериализации и исключает зависимость от формата отображения.
При получении данных с сервера важно синхронизировать оба уровня:
function setValue(an, hidden, value) {
an.set(value);
hidden.value = an.getNumber();
}
AutoNumeric гарантирует корректное форматирование при установке значения, но скрытое поле требует явного обновления.
Форматирование может включать:
Скрытые поля полностью абстрагируются от локали:
Это устраняет неоднозначность при серверной обработке данных.
При очистке значения необходимо учитывать три состояния:
displayInput.addEventListener('autoNumeric:rawValueModified', () => {
const value = anElement.getNumber();
hiddenInput.value = value === null ? '' : value;
});
Такая модель предотвращает передачу некорректных данных.
В крупных проектах логика скрытых полей часто выносится в отдельный слой:
class NumericField {
constructor(display, hidden, options) {
this.hidden = hidden;
this.an = new AutoNumeric(display, options);
display.addEventListener('autoNumeric:rawValueModified', () => {
this.sync();
});
}
sync() {
this.hidden.value = this.an.getNumber();
}
set(value) {
this.an.set(value);
this.sync();
}
get() {
return this.an.getNumber();
}
}
Такой подход унифицирует работу с числовыми данными и минимизирует ошибки синхронизации.
При повторной инициализации AutoNumeric важно учитывать необходимость очистки предыдущего состояния:
destroy()Игнорирование этих шагов приводит к дублированию событий и некорректной синхронизации.
Использование скрытых полей снижает риск:
При этом скрытое поле становится единственным источником данных для серверной логики, что упрощает валидацию и обработку.