Choices.js изначально не зависит от jQuery и построен на нативном DOM
API. При интеграции с jQuery возникает слой адаптации, в котором jQuery
выступает как средство выбора элементов, управления коллекциями и
организации жизненного цикла компонентов, а Choices.js — как независимый
UI-рендеринг поверх <select> или
<input>.
Ключевая особенность интеграции заключается в том, что экземпляр Choices привязывается к DOM-элементу один раз, после чего управление состоянием должно происходить либо через API Choices, либо через аккуратное обновление DOM с последующим вызовом методов обновления.
Наиболее распространённый сценарий — инициализация Choices на элементах, полученных через jQuery-селектор.
$(document).ready(function () {
const $select = $('#country-select');
const choicesInstance = new Choices($select[0], {
searchEnabled: true,
removeItemButton: true,
shouldSort: false
});
});
jQuery возвращает коллекцию, а Choices требует чистый
DOM-элемент, поэтому используется индекс [0].
При работе с формами, содержащими несколько
<select> или <input>, используется
итерация по jQuery-коллекции.
$('.js-choices').each(function () {
const element = this;
const instance = new Choices(element, {
searchEnabled: true,
itemSelectText: ''
});
$(element).data('choices-instance', instance);
});
Использование $.data() позволяет:
Choices.js не рассчитан на повторную инициализацию поверх уже существующего экземпляра без его уничтожения.
function initChoices($el) {
const existing = $el.data('choices-instance');
if (existing) {
existing.destroy();
}
const instance = new Choices($el[0], {
searchEnabled: true
});
$el.data('choices-instance', instance);
}
При вставке новых элементов через jQuery (.html(),
.append(), .load()) Choices не активируется
автоматически. Требуется повторная инициализация.
$('#container').html(newContent);
$('#container').find('select.js-choices').each(function () {
new Choices(this, {
searchEnabled: true
});
});
Choices хранит внутреннее состояние, поэтому повторная инициализация без destroy приводит к:
Choices генерирует собственные события (addItem,
removeItem, change). Их можно синхронизировать
с jQuery-логикой.
const $el = $('#tags');
const instance = new Choices($el[0]);
$el.on('addItem', function (event) {
console.log('Добавлен элемент:', event.detail.value);
});
$el.on('removeItem', function (event) {
console.log('Удалён элемент:', event.detail.value);
});
Choices диспатчит события на DOM-элемент, поэтому jQuery корректно их перехватывает без дополнительных адаптеров.
Choices не имеет встроенной зависимости от jQuery.ajax, но легко комбинируется с ней при заполнении списка.
const $select = $('#users');
const instance = new Choices($select[0], {
searchEnabled: true
});
$.ajax({
url: '/api/users',
method: 'GET',
success: function (data) {
const items = data.map(user => ({
value: user.id,
label: user.name
}));
instance.setChoices(items, 'value', 'label', true);
}
});
true очищает старые значенияПри использовании динамически создаваемых элементов jQuery делегирование применяется только к моменту инициализации, но не к самому Choices.
$(document).on('focus', 'select.js-choices', function () {
if (!$(this).data('choices-instance')) {
const instance = new Choices(this);
$(this).data('choices-instance', instance);
}
});
Инициализация по событию focus может приводить к задержке UX, поэтому чаще используется явный init после вставки DOM.
Choices управляет состоянием независимо от jQuery
.val(). Прямое изменение значения через jQuery не всегда
отражается в UI.
const $select = $('#status');
const instance = $select.data('choices-instance');
instance.setChoiceByValue('active');
$('#status').val('active'); // UI Choices не обновится
При работе SPA-подобных интерфейсов требуется корректное уничтожение инстанса.
function destroyChoices($el) {
const instance = $el.data('choices-instance');
if (instance) {
instance.destroy();
$el.removeData('choices-instance');
}
}
<select>Choices не поддерживает chaining jQuery напрямую, но можно сохранять семантику цепочек через возврат jQuery-объекта.
$.fn.activateChoices = function (options) {
return this.each(function () {
const instance = new Choices(this, options);
$(this).data('choices-instance', instance);
});
};
$('.js-choices').activateChoices({
searchEnabled: true
});
Возникает при повторном вызове без destroy. Приводит к наложению UI.
jQuery .val() не синхронизирует UI Choices.
При .html() контейнера старые экземпляры теряются и
требуют повторного связывания.
При AJAX-обновлениях важно использовать setChoices, а не
прямую модификацию <option>.
.data()