В библиотеке Tom Select процесс сериализации данных тесно связан с
тем, как компонент хранит внутреннее состояние и как это состояние
синхронизируется с DOM-элементом <select>, формами и
внешними API. Под сериализацией в данном контексте понимается
преобразование выбранных пользователем значений в формат, пригодный для
отправки на сервер, сохранения или дальнейшей обработки: строка, массив,
JSON-структура.
Tom Select оперирует двумя уровнями данных:
Каждый элемент item представляет собой объект, где
ключевым полем выступает значение valueField (по умолчанию
"value"), а отображаемый текст берётся из
labelField (по умолчанию "text").
new TomSelect('#select', {
valueField: 'id',
labelField: 'title',
searchField: 'title'
});
При такой конфигурации внутренний элемент будет выглядеть так:
{
id: 42,
title: "JavaScript"
}
Именно эти объекты становятся основой для сериализации.
getValue()Основной способ извлечения данных — метод
getValue().
const ts = new TomSelect('#select');
const value = ts.getValue();
Поведение зависит от режима:
Пример для multiple:
// ["js", "ts", "node"]
const values = ts.getValue();
Важно: возвращаются именно значения valueField, а не
целые объекты.
Для более сложной сериализации часто требуется доступ к полным объектам:
const items = ts.items;
items содержит массив объектов из options,
соответствующих выбранным значениям.
Пример:
[
{ id: "js", title: "JavaScript" },
{ id: "ts", title: "TypeScript" }
]
Это критично для случаев, когда нужно отправлять не только идентификаторы, но и метаданные.
На практике часто требуется преобразовать состояние в JSON-структуру для API:
const payload = {
tags: ts.getValue()
};
fetch('/api/save', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
Если требуется передать не только значения, но и дополнительные поля:
const payload = {
tags: ts.items
};
Однако такой подход увеличивает объём данных и требует согласования с сервером.
Tom Select автоматически синхронизирует выбранные значения с
оригинальным <select> элементом.
<select id="select" name="tags" multiple>
<option value="js">JavaScript</option>
<option value="ts">TypeScript</option>
</select>
После инициализации:
new TomSelect('#select');
При сабмите формы браузер отправит:
tags=js&tags=ts
Это происходит потому, что Tom Select обновляет состояние DOM
<option selected>.
{
value: "js"
}
ts.getValue(); // "js"
ts.getValue(); // ["js", "ts"]
При проектировании API важно учитывать, что тип данных меняется автоматически.
Если включён режим создания новых опций:
new TomSelect('#select', {
create: true
});
Пользователь может вводить новые значения, которые не существуют в
options.
Такие значения:
itemsts.getValue(); // ["js", "custom-tag"]
Если требуется различать созданные элементы:
const result = ts.items.map(item => ({
value: item.value,
created: item.$isNew || false
}));
Ключевым механизмом является valueField, который
определяет, что именно попадёт в getValue():
new TomSelect('#select', {
valueField: 'slug',
labelField: 'name'
});
Теперь:
ts.getValue(); // ["javascript", "typescript"]
При этом внутренние объекты остаются богатыми:
{
slug: "javascript",
name: "JavaScript",
category: "language"
}
В сложных сценариях стандартного getValue()
недостаточно. Тогда используется ручное преобразование:
const serialized = ts.items.map(item => ({
id: item.id,
text: item.title,
meta: {
length: item.title.length
}
}));
Такой подход применяется при:
Tom Select предоставляет события, которые позволяют синхронизировать данные в реальном времени:
new TomSelect('#select', {
onChange(value) {
console.log('Serialized:', value);
}
});
Значение value уже является результатом
getValue().
Для расширенной сериализации:
onChange(value) {
const payload = {
raw: value,
full: this.items
};
}
Сериализация зависит от того, насколько синхронизированы:
optionsitems<select>Если данные загружаются асинхронно:
ts.addOption({ id: 1, title: "JS" });
ts.addItem("1");
важно учитывать порядок:
addOptionaddItemиначе items может содержать ссылки на несуществующие
опции.
Частый сценарий — восстановление состояния:
fetch('/api/data')
.then(r => r.json())
.then(data => {
ts.setValue(data.tags);
});
Если сервер возвращает полный объект:
ts.setValue(data.items.map(i => i.id));
Tom Select всегда принимает именно valueField, а не
объекты.
Некоторые плагины изменяют поведение данных:
create — добавляет новые значенияremove_button — не влияет на сериализацию, но меняет
itemscheckbox_options — влияет только на UIС точки зрения сериализации важно помнить: плагины не меняют
getValue(), но могут изменять состав
items.
Иногда требуется строковый формат:
const str = ts.getValue().join(',');
Результат:
js,ts,node
Такой формат используется:
Сериализация всегда предполагает обратный процесс — восстановление состояния:
const values = "js,ts,node".split(',');
ts.setValue(values);
или из JSON:
ts.setValue(JSON.parse(response.tags));
Фактически Tom Select можно свести к трём уровням представления:
labelFieldvalueFielditemsИ сериализация всегда выбирает один из них:
getValue() → логический уровеньitems → объектный уровень<select> → HTML-уровеньЭта трёхуровневая модель делает Tom Select предсказуемым в интеграции с серверными API и формами, где требуется строгий контроль над тем, какие данные реально покидают клиентское приложение.