Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как сделать поиск по опциям в селекте? (https://javascript.ru/forum/misc/81024-kak-sdelat-poisk-po-opciyam-v-selekte.html)

CryNet 16.09.2020 10:55

Как сделать поиск по опциям в селекте?
 
Есть селект с опциями:

<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

рони 16.09.2020 12:23

Цитата:

Сообщение от CryNet
, а если юзер снова введёт эту же букву, то уже подсветить нужно вторую найденную и так дале.

трудноуловимая логика...

CryNet 16.09.2020 12:45

Цитата:

Сообщение от рони (Сообщение 528889)
трудноуловимая логика...

Вот у нас есть опции:

<option value="771" selected="">Обратная связь</option>
<option value="772" selected="">Обратная</option>


Если я нажал один раз "о" на клавиатуре, то должна подсветиться
<option value="771" selected="">Обратная связь</option>
если второй раз, то
<option value="772" selected="">Обратная</option>
и так далее. А когда эти опции закончаться, то нужно вернуться на самый первый и так по кругу.

рони 16.09.2020 13:06

CryNet,
как понять буква первая или вторая или третья... ?

CryNet 16.09.2020 13:11

Цитата:

Сообщение от рони (Сообщение 528892)
CryNet,
как понять буква первая или вторая или третья... ?

Ну, нарпимер, если мы перебираем опции селекта, то это может выглядеть так:

option.filter(e => {
   e.textContent[0]
})

рони 16.09.2020 13:17

CryNet,
поиск всегда только по первой букве option?

CryNet 16.09.2020 13:24

Цитата:

Сообщение от рони (Сообщение 528894)
CryNet,
поиск всегда только по первой букве option?

Да. У меня все решения сводяться к одному. И я как бы не могу выбраться из своего кругозора, чтобы взглянуть на задачу по другому :D

Песочница:https://jsfiddle.net/qokp6g1e/4/

рони 16.09.2020 14:19

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>

CryNet 16.09.2020 15:39

Цитата:

Сообщение от рони (Сообщение 528896)
CryNet,
надо читать документацию на плагин, без плагина можно так ... нажать на селект, нажать на клавишу нужной буквы.

У плагина есть метод, добавляющий полосу поиска. Но мне это не подходит.

Немного не правильно отрабатывает: https://jsfiddle.net/u53txznd/

1) Если мы нажали одну и ту же клавишу второй раз, то с текущего нужно снять подсветку (класс is-highlighted), а следующему добавить.
2) Если опций больше двух, то логика ломается - третий посвечивать не хочет.

CryNet 16.09.2020 17:18

Цитата:

Сообщение от рони (Сообщение 528896)
CryNet,
надо читать документацию на плагин, без плагина можно так ... нажать на селект, нажать на клавишу нужной буквы.

Доделал ваше решение: https://jsfiddle.net/g54eLdnb/
Теперь всё работает как нужно. Правда решение не очень симтатичное. Может у вас будут идеи как его улучшить/переписать?


Часовой пояс GMT +3, время: 20:35.