Как сделать выпадающий список с возможность ввода, как в input type="text" и возможностью выбора, как в select
Нужен похожий выпадающий список, в котором совмещен функционал input type="text" и select. Как можно такой реализовать? Вариант с datalist не подходит, так как он работает по подсказкам и при вводе допустим значения "2" все варианты без двойки пропадают, но пропадать они не должны.
Ответы (2 шт):
Автор решения: ksa
→ Ссылка
Могу предложить некий "упрощенный" вариант такого "селекта"...
document.querySelectorAll('.select').forEach(el => {
el.addEventListener('click', e => {
if (e.target.tagName === 'BUTTON') {
el.querySelector('ul').classList.toggle('on')
}
if (e.target.tagName === 'LI') {
el.querySelector('input').value = e.target.textContent
el.querySelector('ul').classList.remove('on')
}
})
})
.select {
display: inline-block;
}
.select ul {
display: none;
border: 1px solid;
list-style-type: none;
list-style-position: outside;
}
.select ul.on {
display: block;
}
<div class='select'>
<div>
<input />
<button>+</button>
</div>
<ul>
<li>10</li>
<li>20</li>
<li>30</li>
</ul>
</div>
Автор решения: Miha
→ Ссылка
const search = document.getElementById('input-search');
const list = document.getElementById('search-list');
const options = list.children;
for (let i = 1, n = options.length; i < n; i++) {
let option = options[i];
option.addEventListener('click', (e) => {
search.value = e.target.textContent;
})
}
// При фокусе инпута показывает писок
search.addEventListener('focus', (e) => {
searchFromInput(e.target.value);
});
// При расфокусировать инпута скрываем select
search.addEventListener('focusout', () => {
changeSelectSize(1);
});
// Добавляем эвент при нажатия на клавиши
search.addEventListener('keyup', (e) => {
searchFromInput(e.target.value);
})
function changeSelectSize(size) {
setTimeout(() => {
list.size = size;
}, 75);
}
// Проходим по каждому элементу списка
function searchFromInput(value) {
let size = 1;
for (let i = 1, n = options.length; i < n; i++) {
let option = options[i];
// Если текст элемента содержит наше строку то показываем её, в противоположном слкчае скрываем
if (option.textContent.toLowerCase().includes(value.toLowerCase())) {
option.hidden = false;
size++;
} else {
option.hidden = true;
}
changeSelectSize(size);
}
}
.search {
position: relative;
display: flex;
width: 320px;
height: auto;
}
.search-list-block {
position: absolute;
width: 100%;
height: 100%;
z-index: 1;
}
#search-list {
width: 100%;
min-height: 100%;
}
#search-list option {
height: 100%;
cursor: pointer;
}
#input-search {
width: 100%;
z-index: 2;
}
<div class="search">
<input type="text" id="input-search">
<div class="search-list-block">
<select name="" id="search-list">
<option selected disabled></option>
<option value="">Russia</option>
<option value="">Europe</option>
<option value="">Asia</option>
<option value="">Australia</option>
<option value="">SUA</option>
</select>
</div>
</div>

