В Tom Select контроль количества выбранных значений реализуется на
уровне конфигурации экземпляра и может сочетаться с пользовательской
логикой, событиями и модификацией поведения интерфейса. Базовый механизм
основан на параметре maxItems, который задаёт верхнюю
границу количества элементов в текущем выборе.
Конфигурация maxItems определяет максимальное количество
выбранных значений в компоненте. При достижении этого лимита интерфейс
перестаёт позволять добавление новых элементов, а ввод или выбор из
списка становится ограниченным.
new TomSelect("#select", {
maxItems: 3
});
При значении 1 компонент фактически превращается в
одновыборочный список, аналогичный стандартному
<select> без множественного выбора, но с сохранением
расширенных возможностей поиска и рендеринга.
new TomSelect("#select", {
maxItems: 1
});
В случае отсутствия ограничения (maxItems: null)
количество выбранных элементов становится неограниченным, что
соответствует поведению по умолчанию для мультиселекта.
При достижении значения maxItems происходит несколько
внутренних изменений состояния:
С точки зрения UX это важно, поскольку пользователь не получает явной ошибки, а ограничение проявляется через недоступность действий.
Значение maxItems может быть изменено после
инициализации компонента. Для этого используется метод
setValue или пересоздание конфигурации через обновление
настроек.
const select = new TomSelect("#select", {
maxItems: 2
});
// изменение логики ограничения
select.settings.maxItems = 5;
select.refreshOptions(false);
Изменение параметра через settings не всегда приводит к
немедленному пересчёту состояния выбранных элементов, поэтому часто
требуется принудительное обновление интерфейса.
Для более гибкой логики ограничения используется событие
onItemAdd, которое позволяет перехватывать момент
добавления элемента и предотвращать его при необходимости.
new TomSelect("#select", {
maxItems: 3,
onItemAdd: function(value) {
if (this.items.length > this.settings.maxItems) {
this.removeItem(value);
}
}
});
Такой подход позволяет реализовать динамические ограничения, которые выходят за рамки фиксированного значения. Например, можно учитывать внешние условия, состояние формы или данные пользователя.
При превышении лимита возможны разные стратегии обработки:
1. Игнорирование новых значений
Новые элементы просто не добавляются, без уведомления и без удаления уже выбранных.
2. Удаление последнего добавленного значения
onItemAdd: function(value) {
if (this.items.length > this.settings.maxItems) {
this.removeItem(this.items[this.items.length - 1]);
}
}
3. Замена старого значения новым
onItemAdd: function(value) {
if (this.items.length > this.settings.maxItems) {
const removed = this.items.shift();
this.removeItem(removed);
}
}
Такая модель используется в интерфейсах, где важна актуальность последних выбранных элементов.
Помимо maxItems, ограничение может реализовываться через
временное отключение компонента. Метод disable() полностью
блокирует взаимодействие, включая открытие списка и ввод.
if (select.items.length >= 3) {
select.disable();
}
Обратное включение осуществляется через enable().
select.enable();
Этот подход применяется в сценариях, где выбор становится окончательным после достижения лимита.
В мультивыборе часто требуется сохранять возможность удаления даже
при достижении лимита. Tom Select сохраняет стандартное поведение
удаления тегов независимо от maxItems.
Это позволяет реализовать стратегию «скользящего окна», где пользователь может удалять элементы и добавлять новые до достижения ограничения.
При использовании удалённого источника данных (load),
ограничение maxItems влияет только на локальный выбор, но
не на загрузку опций.
new TomSelect("#select", {
maxItems: 2,
load: function(query, callback) {
fetch(`/api/search?q=${query}`)
.then(res => res.json())
.then(data => callback(data));
}
});
Даже при достижении лимита серверные запросы продолжают выполняться, но добавление результатов блокируется на уровне интерфейса.
Некоторые плагины Tom Select могут изменять поведение ограничения:
remove_button усиливает управление удалением
элементов;dropdown_input влияет на ввод при достижении
лимита;При разработке расширений важно учитывать значение
maxItems, так как оно остаётся центральным ограничителем
состояния выбора.
Массив items внутри экземпляра является фактическим
источником текущего состояния выбора. Любые ограничения, включая
maxItems, в конечном счёте влияют именно на него.
console.log(select.items);
Проверка длины массива используется во всех пользовательских и встроенных механизмах ограничения.
Вместо пост-фактум удаления элементов может применяться проверка
перед добавлением через shouldAddItem-подобную логику,
реализуемую вручную.
onItemAdd: function(value) {
if (this.items.length > this.settings.maxItems) {
this.removeItem(value);
return;
}
}
Такой подход снижает визуальные артефакты и предотвращает кратковременное превышение лимита.
При активном поиске внутри поля поведение не изменяется, однако UX может быть дополнительно улучшен скрытием результатов при достижении лимита.
onDropdownOpen: function() {
if (this.items.length >= this.settings.maxItems) {
this.close();
}
}
Это предотвращает попытки дальнейшего выбора через интерфейс списка.
В ряде случаев фиксированное значение maxItems
недостаточно. Тогда применяется вычисляемое ограничение:
new TomSelect("#select", {
maxItems: 10,
onItemAdd: function(value) {
const limit = this.settings.maxItems;
const dynamicLimit = limit - (this.items.includes("admin") ? 2 : 0);
if (this.items.length > dynamicLimit) {
this.removeItem(value);
}
}
});
Такая модель позволяет учитывать контекст выбранных значений и внешние зависимости.
Метод addItem() также подчиняется ограничению
maxItems. При попытке добавить значение сверх лимита
поведение зависит от внутренней реализации и может быть либо
игнорированием, либо частичным применением с последующей
корректировкой.
select.addItem("value");
Для строгого контроля используется предварительная проверка:
if (select.items.length < select.settings.maxItems) {
select.addItem("value");
}
При установке нескольких значений через setValue важно
учитывать, что массив входных данных может превышать лимит.
select.setValue(["a", "b", "c", "d"]);
В этом случае сохраняются только первые элементы до достижения
maxItems, а остальные отбрасываются или игнорируются в
зависимости от конфигурации.
Tom Select не отображает ограничение явно, поэтому часто добавляется кастомная индикация:
onItemAdd: function() {
const remaining = this.settings.maxItems - this.items.length;
console.log(`Осталось: ${remaining}`);
}
Такая логика может быть интегрирована в внешний UI, не изменяя сам компонент.
Ограничение количества выбранных элементов напрямую влияет на структуру данных формы, особенно при сериализации. Значение поля становится массивом фиксированной длины, что упрощает серверную валидацию и снижает необходимость дополнительных проверок на стороне backend.
В типизированных схемах данных это соответствует массиву с верхней
границей длины, где maxItems выступает как клиентское
отражение серверного правила валидации.