HTML-селект, предназначенный для выбора страны, в большинстве случаев
начинается с обычного элемента <select>, содержащего
список <option>. Библиотека Choices.js расширяет его
поведение, добавляя поиск, улучшенное управление фокусом, кастомный UI и
поддержку динамических данных.
<sel ect id="country-select" placeholder="Выбор страны">
<option value="">Выбор страны</option>
<option value="kz">Казахстан</option>
<option value="ru">Россия</option>
<option value="us">США</option>
<option value="de">Германия</option>
<option value="fr">Франция</option>
<option value="jp">Япония</option>
</select>
Ключевым моментом является наличие пустого значения или placeholder-элемента, который используется библиотекой для отображения состояния до выбора значения. Без него поведение placeholder может быть непредсказуемым в зависимости от конфигурации.
Подключение библиотеки и создание экземпляра осуществляется через
конструктор Choices.
import Choices fr om 'choices.js';
const countrySelect = document.getElementById('country-select');
const choices = new Choices(countrySelect, {
searchEnabled: true,
itemSelectText: '',
shouldSort: false,
placeholder: true,
placeholderValue: 'Выбор страны',
removeItemButton: false
});
Параметр searchEnabled: true включает фильтрацию списка
стран, что особенно важно при большом количестве элементов. Для
небольших списков допустимо отключение поиска, но в контексте стран это
редко оправдано.
Флаг shouldSort: false сохраняет порядок стран таким,
каким он задан в HTML. Это критично, если список заранее структурирован
(например, по приоритетным регионам).
Choices.js обрабатывает пустые значения особым образом. Если первый
<option> имеет пустой value, он
используется как начальное состояние.
<option value="">Выбор страны</option>
При отсутствии такого элемента библиотека может считать первым элементом фактическое значение, что приводит к автоматическому выбору страны без действия пользователя.
Корректная настройка placeholder через конфигурацию:
placeholder: true,
placeholderValue: 'Выбор страны'
Для селекта стран чаще всего используется одиночный выбор. В
Choices.js это поведение контролируется автоматически через обычный
<select> без атрибута multiple.
<select id="country-select">
Если multiple не указан, библиотека создаёт
single-select компонент с заменой стандартного UI на кастомный блок с
выпадающим списком.
По умолчанию Choices.js может сортировать элементы в алфавитном порядке. Для списков стран это поведение часто нежелательно, так как требуется фиксированный порядок (например, по приоритету аудитории или региона).
shouldSort: false
При необходимости кастомной сортировки используется подготовка массива перед инициализацией:
const countries = [
{ value: 'kz', label: 'Казахстан' },
{ value: 'ru', label: 'Россия' },
{ value: 'us', label: 'США' }
];
const select = document.getElementById('country-select');
select.innerHTML = countries
.map(c => `<option value="${c.value}">${c.label}</option>`)
.join('');
new Choices(select, {
shouldSort: false
});
Поиск является ключевой функцией при работе с большими наборами
стран. Choices.js использует внутренний фильтр по текстовому содержимому
label.
searchEnabled: true,
searchPlaceholderValue: 'Поиск страны'
При вводе текста выполняется фильтрация без серверных запросов. Алгоритм поиска чувствителен к строковому совпадению, но не требует точного соответствия.
Для улучшения UX в больших списках можно настроить порог минимального ввода:
searchFloor: 1
Choices.js позволяет управлять тем, как отображаются элементы в выпадающем списке и выбранные значения.
const choices = new Choices(countrySelect, {
callbackOnCreateTemplates: function (template) {
return {
item: (classNames, data) => {
return template(`
<div class="${classNames.item} ${data.highlighted
? classNames.highlightedState
: classNames.itemSelectable}"
data-item
data-id="${data.id}"
data-value="${data.value}">
${data.label}
</div>
`);
}
};
}
});
Эта возможность используется для добавления флагов стран, дополнительных описаний или кастомных UI-меток.
Типичный сценарий для селекта стран — отображение флагов рядом с названием. Для этого в данные добавляется дополнительное поле.
const countries = [
{ value: 'kz', label: 'Казахстан', customProperties: { flag: '??' } },
{ value: 'ru', label: 'Россия', customProperties: { flag: '??' } },
{ value: 'us', label: 'США', customProperties: { flag: '??' } }
];
Отображение в шаблоне:
callbackOnCreateTemplates: function (template) {
return {
item: (classNames, data) => {
const flag = data.customProperties?.flag || '';
return template(`
<div class="${classNames.item} ${classNames.itemSelectable}"
data-item data-id="${data.id}" data-value="${data.value}">
<span class="flag">${flag}</span>
<span>${data.label}</span>
</div>
`);
}
};
}
В простом селекте стран часто требуется запретить очистку выбора. Это
контролируется параметром allowSingleDeselect.
new Choices(countrySelect, {
allowSingleDeselect: false
});
При этом крестик удаления и возможность сброса выбора не отображаются.
Choices.js поддерживает базовые ARIA-атрибуты и управление клавиатурой. Однако поведение можно дополнительно контролировать через конфигурацию:
{
silent: false,
renderChoiceLimit: -1
}
renderChoiceLimit особенно полезен при больших списках
стран, позволяя ограничить количество отображаемых элементов и снижать
нагрузку на DOM.
Список стран может обновляться после инициализации компонента, например при смене языка интерфейса.
choices.clearStore();
choices.setChoices([
{ value: 'kz', label: 'Қазақстан' },
{ value: 'ru', label: 'Россия' },
{ value: 'us', label: 'United States' }
], 'value', 'label', true);
Флаг true в конце означает полную перезапись текущего
списка.
Получение текущего выбора осуществляется через API экземпляра:
const value = choices.getValue(true);
Возвращается строковое значение выбранной страны, например
"kz". Для получения объекта используется:
const valueObj = choices.getValue();
Сброс состояния селекта стран выполняется программно:
choices.removeActiveItems();
При необходимости возврата к начальному состоянию можно также перезаписать значение:
choices.setChoiceByValue('');
Хотя список стран обычно фиксирован и относительно небольшой, в некоторых случаях он дополняется территориями или регионами, что увеличивает объём данных. В таких ситуациях применяется ограничение отображения:
renderChoiceLimit: 20
Это влияет только на визуальное отображение, не ограничивая фактические данные.
Choices.js предоставляет базовые классы для кастомизации внешнего вида:
.choices.choices__inner.choices__list--dropdown.choices__itemПример CSS для адаптации под минималистичный интерфейс:
.choices__inner {
border-radius: 6px;
padding: 6px 10px;
min-height: 38px;
}
.choices__list--dropdown {
border-radius: 6px;
box-shadow: 0 8px 20px rgba(0,0,0,0.08);
}
.choices__item--selectable {
padding: 6px 10px;
}
Неправильная структура <option> приводит к
некорректной инициализации:
<option>Казахстан</option>
Отсутствие value нарушает корректную работу API и
усложняет обработку данных на сервере.
Ещё одна частая проблема — повторная инициализация Choices без уничтожения предыдущего экземпляра, что приводит к дублированию DOM-структуры и утечкам памяти.
choices.destroy();
Оптимальный набор параметров для стабильной работы:
new Choices(countrySelect, {
searchEnabled: true,
shouldSort: false,
itemSelectText: '',
placeholder: true,
placeholderValue: 'Выбор страны',
allowSingleDeselect: false,
renderChoiceLimit: 20,
searchPlaceholderValue: 'Поиск страны'
});
Такой набор обеспечивает предсказуемое поведение, корректный UX и масштабируемость при увеличении списка стран.