При использовании Tom Select ключевая задача hidden-полей заключается
в разделении визуального представления данных и их фактического значения
в форме. Сам компонент заменяет стандартный <select>
на более гибкий интерфейс, однако итоговая отправка формы должна
оставаться совместимой с классической HTML-формой, где сервер получает
либо одно значение, либо массив значений.
Hidden-поле выступает в роли канонического источника данных.
Визуальный список тегов, выбранных элементов или созданных опций
существует исключительно на клиенте, тогда как hidden input хранит
сериализованное состояние, которое отправляется через
FormData.
В стандартной конфигурации Tom Select создаёт связь между UI и скрытым полем через механизм обновления значений.
Основные принципы:
Типичная структура HTML:
<select id="tags" multiple></select>
<input type="hidden" name="tags" id="tags-hidden">
Инициализация:
new TomSelect("#tags", {
plugins: ["remove_button"],
onChange: function(value) {
document.querySelector("#tags-hidden").value = value;
}
});
Tom Select по умолчанию передаёт значения в виде строки, разделённой запятыми:
"value1,value2,value3"
Такой формат применяется при multiple: true, если не
задана кастомная сериализация.
В однозначных select:
"value1"
Однако скрытое поле может быть адаптировано под любые структуры данных.
При работе с множественным выбором часто требуется преобразование массива в строку или JSON.
onChange: function(values) {
hidden.value = values.join(",");
}
Такой подход сохраняет совместимость с классическими backend-парсерами.
onChange: function(values) {
hidden.value = JSON.stringify(values);
}
Используется при сложных структурах данных или при передаче объектов.
Tom Select поддерживает режим, где значение элемента — объект:
{
id: 1,
title: "JavaScript"
}
В этом случае hidden input должен хранить только идентификатор или сериализованную структуру.
onChange: function(values) {
const ids = values.map(item => item.id);
hidden.value = ids.join(",");
}
onChange: function(values) {
hidden.value = JSON.stringify(values);
}
При отправке формы через FormData hidden input
становится ключевым источником данных.
const form = document.querySelector("form");
form.addEventListener("submit", function(e) {
const data = new FormData(form);
console.log(data.get("tags"));
});
Важно, что Tom Select не участвует в процессе сериализации формы напрямую. Его роль ограничивается синхронизацией состояния.
В сложных интерфейсах состояние может изменяться не только через UI, но и программно:
const select = new TomSelect("#tags");
const hidden = document.querySelector("#tags-hidden");
select.addItem("javascript");
hidden.value = select.getValue().join(",");
При программных изменениях необходимо вручную поддерживать консистентность hidden input.
Удаление элемента из выбора должно синхронизироваться с hidden input без задержек:
onItemRemove: function(value) {
const current = this.getValue();
hidden.value = current.join(",");
}
Важно учитывать, что onItemRemove вызывается после
обновления внутреннего состояния компонента.
Использование hidden input в связке с Tom Select отражает классическую архитектурную модель:
Такое разделение позволяет:
В сложных формах допускается использование нескольких hidden input для одного Tom Select:
<input type="hidden" name="tags_ids" id="tags-ids">
<input type="hidden" name="tags_titles" id="tags-titles">
onChange: function(values) {
document.querySelector("#tags-ids").value =
values.map(v => v.id).join(",");
document.querySelector("#tags-titles").value =
values.map(v => v.title).join("|");
}
Такой подход применяется при необходимости оптимизировать серверную обработку без дополнительных запросов к справочникам.
Hidden input может выступать источником для инициализации состояния компонента:
const hidden = document.querySelector("#tags-hidden");
new TomSelect("#tags", {
items: hidden.value.split(",")
});
При JSON-формате:
items: JSON.parse(hidden.value || "[]")
Это особенно важно при серверном рендеринге форм.
Наиболее частые ошибки возникают при:
Типичный дефект:
Решение — всегда считать Tom Select источником истины, а hidden input производным состоянием.
При загрузке опций через AJAX hidden input должен обновляться только после завершения установки значений:
const select = new TomSelect("#tags", {
load: function(query, callback) {
fetch("/tags?q=" + query)
.then(res => res.json())
.then(data => callback(data));
},
onChange: function(values) {
hidden.value = JSON.stringify(values);
}
});
Особенность заключается в том, что значение может быть установлено до полной загрузки справочника, и hidden input должен учитывать только финальное состояние.
Для стабильной работы системы необходимо соблюдение следующих условий:
Эти правила обеспечивают предсказуемость поведения формы при любых сценариях взаимодействия с Tom Select