Начальное значение, Data API, локальный поиск, группы и дерево.
VGSelect сохраняет исходный <select> для формы и строит интерфейс рядом с ним.
Каждый пример запускается один раз после появления HTML. Параметры из data-* читаются при инициализации;
библиотека сама не сканирует страницу в поисках полей. По умолчанию модуль использует
position: 'auto': список выбирает сторону с большим свободным местом.
Одиночный выбор и placeholder
Пустая hidden-опция сохраняет состояние «не выбрано». Выбранное значение читается из исходного поля.
Город
Калуга
Москва
Тула
Значение: не выбрано
Много городов
Калуга
Москва
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Тула
Липецк
Значение: не выбрано
Показать код
<div class="row gap-y-6">
<div class="col-xl-6">
<div class="select-demo">
<label for="select-single">Город</label>
<select id="select-single" class="vg-select" name="city" data-select-demo
data-placeholder="Выберите город" data-autosearch="false">
<option value="" selected hidden></option>
<option value="kaluga">Калуга</option>
<option value="moscow">Москва</option>
<option value="tula">Тула</option>
</select>
<output id="select-single-value" aria-live="polite">Значение: не выбрано</output>
</div>
</div>
<div class="col-xl-6">
<div class="select-demo">
<label for="select-single">Много городов</label>
<select id="select-single-more" class="vg-select" name="city" data-select-demo
data-placeholder="Выберите город" data-autosearch="true">
<option value="" selected hidden></option>
<option value="kaluga">Калуга</option>
<option value="moscow">Москва</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Тула</option>
<option value="tula">Липецк</option>
</select>
<output id="select-single-value-more" aria-live="polite">Значение: не выбрано</output>
</div>
</div>
</div>
/**
* Описание: рабочий пример VGSelect — single.
* Возможности: инициализация и демонстрация публичного контракта на исходном select.
*/
import {VGSelect} from 'vgapp';
function initSelectDemo() {
const select = document.querySelector('#select-single');
if (!select || select.dataset.inited === 'true') return;
VGSelect.init(select); // data-* — параметры; явный запуск обязателен.
select.addEventListener('change', () => {
document.querySelector('#select-single-value').textContent = 'Значение: ' + (select.value || 'не выбрано');
});
const selectMore = document.querySelector('#select-single-more');
if (!selectMore || selectMore.dataset.inited === 'true') return;
VGSelect.init(selectMore); // data-* — параметры; явный запуск обязателен.
}
initSelectDemo();
.select-demo {
display: grid;
gap: 12px;
max-width: 560px;
min-width: 0;
}
.select-demo-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.select-demo output {
overflow-wrap: anywhere;
}
.select-demo-log {
max-height: 240px;
overflow: auto;
white-space: pre-wrap;
overflow-wrap: anywhere;
padding: 12px;
border: 1px solid var(--vg-border-default);
border-radius: var(--vg-radius-md);
background: var(--vg-surface-muted-bg);
color: var(--vg-text-primary);
}
.select-demo-placement {
padding-top: 180px;
}
.vg-select.select-demo-compact {
--vg-select-current-font-size: 14px;
--vg-select-current-padding-top: 8px;
--vg-select-current-padding-bottom: 8px;
--vg-select-current-border-radius: 10px;
--vg-select-list-hover-background-color: var(--vg-surface-muted-bg);
}
.module-select-content {
min-width: 0;
}
.module-select-reference {
margin-top: 32px;
overflow-wrap: anywhere;
}
.module-select-reference dt {
margin-top: 16px;
font-weight: 600;
}
.module-select-reference dd {
margin: 6px 0 0;
}
По умолчанию поиск появляется при количестве непустых опций больше семи. Введите «ка» или несуществующее название. Сетевых запросов нет.
Город с локальным поиском
Калуга Казань
Краснодар Кострома
Киров Курск
Москва Минск
Самара
Показать код
<div class="select-demo">
<label for="select-search">Город с локальным поиском</label>
<select id="select-search" class="vg-select" data-select-demo data-placeholder="Выберите город">
<option value="" selected hidden></option>
<option value="1">Калуга</option><option value="2">Казань</option>
<option value="3">Краснодар</option><option value="4">Кострома</option>
<option value="5">Киров</option><option value="6">Курск</option>
<option value="7">Москва</option><option value="8">Минск</option>
<option value="9">Самара</option>
</select>
</div>
/**
* Описание: рабочий пример VGSelect — search.
* Возможности: инициализация и демонстрация публичного контракта на исходном select.
*/
import {VGSelect} from 'vgapp';
function initSelectDemo() {
const select = document.querySelector('#select-search');
if (!select || select.dataset.inited === 'true') return;
VGSelect.init(select); // autosearch: true, поле поиска при > 7 опциях.
}
initSelectDemo();
.select-demo {
display: grid;
gap: 12px;
max-width: 560px;
min-width: 0;
}
.select-demo-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.select-demo output {
overflow-wrap: anywhere;
}
.select-demo-log {
max-height: 240px;
overflow: auto;
white-space: pre-wrap;
overflow-wrap: anywhere;
padding: 12px;
border: 1px solid var(--vg-border-default);
border-radius: var(--vg-radius-md);
background: var(--vg-surface-muted-bg);
color: var(--vg-text-primary);
}
.select-demo-placement {
padding-top: 180px;
}
.vg-select.select-demo-compact {
--vg-select-current-font-size: 14px;
--vg-select-current-padding-top: 8px;
--vg-select-current-padding-bottom: 8px;
--vg-select-current-border-radius: 10px;
--vg-select-list-hover-background-color: var(--vg-surface-muted-bg);
}
.module-select-content {
min-width: 0;
}
.module-select-reference {
margin-top: 32px;
overflow-wrap: anywhere;
}
.module-select-reference dt {
margin-top: 16px;
font-weight: 600;
}
.module-select-reference dd {
margin: 6px 0 0;
}
Группы и недоступная опция
optgroup объединяет варианты. data-search-enabled включает поиск даже в коротком списке; data-close="false" оставляет список открытым после выбора.
Специалист
Иван — электрика
Анна — двигатель
Олег — подвеска
Мария — недоступна
Показать код
<div class="select-demo">
<label for="select-groups">Специалист</label>
<select id="select-groups" class="vg-select" data-select-demo data-search-enabled="true" data-close="false">
<optgroup label="Диагностика">
<option value="ivan" selected>Иван — электрика</option>
<option value="anna">Анна — двигатель</option>
</optgroup>
<optgroup label="Ремонт">
<option value="oleg">Олег — подвеска</option>
<option value="maria" disabled>Мария — недоступна</option>
</optgroup>
</select>
</div>
/**
* Описание: рабочий пример VGSelect — groups.
* Возможности: инициализация и демонстрация публичного контракта на исходном select.
*/
import {VGSelect} from 'vgapp';
function initSelectDemo() {
const select = document.querySelector('#select-groups');
if (!select || select.dataset.inited === 'true') return;
VGSelect.init(select);
}
initSelectDemo();
.select-demo {
display: grid;
gap: 12px;
max-width: 560px;
min-width: 0;
}
.select-demo-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.select-demo output {
overflow-wrap: anywhere;
}
.select-demo-log {
max-height: 240px;
overflow: auto;
white-space: pre-wrap;
overflow-wrap: anywhere;
padding: 12px;
border: 1px solid var(--vg-border-default);
border-radius: var(--vg-radius-md);
background: var(--vg-surface-muted-bg);
color: var(--vg-text-primary);
}
.select-demo-placement {
padding-top: 180px;
}
.vg-select.select-demo-compact {
--vg-select-current-font-size: 14px;
--vg-select-current-padding-top: 8px;
--vg-select-current-padding-bottom: 8px;
--vg-select-current-border-radius: 10px;
--vg-select-list-hover-background-color: var(--vg-surface-muted-bg);
}
.module-select-content {
min-width: 0;
}
.module-select-reference {
margin-top: 32px;
overflow-wrap: anywhere;
}
.module-select-reference dt {
margin-top: 16px;
font-weight: 600;
}
.module-select-reference dd {
margin: 6px 0 0;
}
tree: true превращает вложенные children в плоский select с визуальными отступами data-level. Это не дерево с раскрытием веток.
Показать код
<div class="select-demo">
<label for="select-tree">Категория работ</label>
<select id="select-tree" class="vg-select" data-select-demo data-placeholder="Выберите категорию">
<option value="" selected hidden></option>
</select>
</div>
/**
* Описание: рабочий пример VGSelect — tree.
* Возможности: инициализация и демонстрация публичного контракта на исходном select.
*/
import {VGSelect} from 'vgapp';
function initSelectDemo() {
const select = document.querySelector('#select-tree');
if (!select || select.dataset.inited === 'true') return;
VGSelect.init(select, {tree: true, search: {enabled: true}});
VGSelect.addOptions(select, [
{text: 'Обслуживание', children: [
{id: 'oil', text: 'Масло'},
{id: 'filters', text: 'Фильтры', children: [
{id: 'air', text: 'Воздушный фильтр'},
{id: 'cabin', text: 'Салонный фильтр'}
]}
]},
{text: 'Диагностика', children: [{id: 'electric', text: 'Электрика'}]}
]);
// Узлы без id с children недоступны для выбора; ветки не сворачиваются.
}
initSelectDemo();
.select-demo {
display: grid;
gap: 12px;
max-width: 560px;
min-width: 0;
}
.select-demo-actions {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.select-demo output {
overflow-wrap: anywhere;
}
.select-demo-log {
max-height: 240px;
overflow: auto;
white-space: pre-wrap;
overflow-wrap: anywhere;
padding: 12px;
border: 1px solid var(--vg-border-default);
border-radius: var(--vg-radius-md);
background: var(--vg-surface-muted-bg);
color: var(--vg-text-primary);
}
.select-demo-placement {
padding-top: 180px;
}
.vg-select.select-demo-compact {
--vg-select-current-font-size: 14px;
--vg-select-current-padding-top: 8px;
--vg-select-current-padding-bottom: 8px;
--vg-select-current-border-radius: 10px;
--vg-select-list-hover-background-color: var(--vg-surface-muted-bg);
}
.module-select-content {
min-width: 0;
}
.module-select-reference {
margin-top: 32px;
overflow-wrap: anywhere;
}
.module-select-reference dt {
margin-top: 16px;
font-weight: 600;
}
.module-select-reference dd {
margin: 6px 0 0;
}