Как сделать поиск по опциям в селекте?
Есть селект с опциями:
<select id="group_id_170" name="group_id" class="mySelect choices__input is-hidden" tabindex="-1" aria-hidden="true" data-choice="active"> <option value="771" selected="">Обратная связь</option> <option value="772" selected="">Обратная</option> <option value="773" selected="">Связь</option> </select> При клике на селект и вводе буквы с клавиатуры (событие keyup) должен срабатывать поиск по опциями, по первой букве опции и подсветке найденой. Но подсвечивать нужно только первую найдённую, а если юзер снова введёт эту же букву, то уже подсветить нужно вторую найденную и так дале. Поиск нужно зациклить. То есть если больше опций нет, то вернуться нужно в начало и подсветить первую. Как можно подобное реализовать? У меня есть следующее:
const select = event.target.querySelector("select")
const choices = Array.from( event.target.querySelectorAll("option") )
choices.forEach(e => e.textContent = e.textContent.replace(/\s+/g, ' ').trim()) // убираем лишние пробелы
const filtred = choices.filter(e => e.textContent[0].toLowerCase().includes(searchValue)) // все найденные
P.S опции обрабатываются библиотекой choices.js и первая опция по умолчанию уже выделенна, класс is-highlighted |
Цитата:
|
Цитата:
<option value="771" selected="">Обратная связь</option> <option value="772" selected="">Обратная</option> Если я нажал один раз "о" на клавиатуре, то должна подсветиться <option value="771" selected="">Обратная связь</option>если второй раз, то <option value="772" selected="">Обратная</option>и так далее. А когда эти опции закончаться, то нужно вернуться на самый первый и так по кругу. |
CryNet,
как понять буква первая или вторая или третья... ? |
Цитата:
option.filter(e => {
e.textContent[0]
})
|
CryNet,
поиск всегда только по первой букве option? |
Цитата:
Песочница:https://jsfiddle.net/qokp6g1e/4/ |
CryNet,
надо читать документацию на плагин, без плагина можно так ... нажать на селект, нажать на клавишу нужной буквы.
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
</head>
<body>
<select id="group_id_170" name="group_id" class="mySelect">
<option class="is-highlighted" value="0" selected="">Админ</option>
<option value="1" selected="">Обратная связь</option>
<option value="2" selected="">Обратная</option>
<option value="3" selected="">О</option>
<option value="4" selected="">Связь</option>
<option value="5" selected="">С</option>
</select>
<script>
let sel = document.querySelector('select').addEventListener('keydown', function(event) {
const key = event.key.toLowerCase();
const options = Array.from( this.options);
const choices = options.filter(({text}) => text.toLowerCase().startsWith(key));
if(choices.length){
let index = (choices.findIndex(({selected}) => selected) + 1) % choices.length;
choices[index].selected = true;}
})
</script>
</body>
</html>
|
Цитата:
Немного не правильно отрабатывает: https://jsfiddle.net/u53txznd/ 1) Если мы нажали одну и ту же клавишу второй раз, то с текущего нужно снять подсветку (класс is-highlighted), а следующему добавить. 2) Если опций больше двух, то логика ломается - третий посвечивать не хочет. |
Цитата:
Теперь всё работает как нужно. Правда решение не очень симтатичное. Может у вас будут идеи как его улучшить/переписать? |
Цитата:
Цитата:
|
Цитата:
|
CryNet,
в выпадающем списке сортировка по алфавиту(
<!DOCTYPE html>
<html>
<head>
<title>Untitled</title>
<meta charset="utf-8">
</head>
<body>
<select id="group_id_170" name="group_id" class="mySelect">
<option class="is-highlighted" value="0" selected="">Админ</option>
<option value="1" selected="">Обратная связь</option>
<option value="2" selected="">Обратная</option>
<option value="3" selected="">О</option>
<option value="4" selected="">Связь</option>
<option value="5" selected="">С</option>
</select>
<link rel="stylesheet" href="https://joshuajohnson.co.uk/Choices/assets/styles/choices.min.css" />
<script src="https://joshuajohnson.co.uk/Choices/assets/scripts/choices.min.js"></script>
<script>
const elements = Array.from(
document.querySelectorAll('select'),
element => {
const options = Array.from( element.options);
const example = new Choices(element, {
searchEnabled: true,
searchChoices: false,
shouldSort : false
});
element.addEventListener('search', function(event) {
const key = event.detail.value.toLowerCase();
example.clearInput();
const choices = options.filter(({text}) => text.toLowerCase().startsWith(key));
if(choices.length){
const values = example.getValue(true)[0];
let index = (choices.findIndex(({value}) => value == values) + 1) % choices.length;
example.setChoiceByValue(choices[index].value);
};
})
return example
}
);
</script>
</body>
</html>
|
Спасибо |
| Часовой пояс GMT +3, время: 22:49. |