Замена ввода в поле поиска событием onclick не обновляет список

У меня есть поле поиска, которое фильтрует три разных списка. Мне нужно onclick-событие, которое добавляет текст в поле поиска и заменяет любое другое значение, которое может быть.

Я могу это сделать, но onclick не обновляет списки, пока я не нажму на поле поиска и не нажму ввод вручную. Добавление события click() не помогло.

В то же время нажатие X в поле поиска для очистки ввода также не обновляет списки.

Что я могу сделать?

<p onclick = "document.getElementById('searchCombo').value = 'element 1'; document.getElementById('searchCombo').click()">Filter for: vitamins</p>

<p onclick = "document.getElementById('searchCombo').value = 'element 2'; document.getElementById('searchCombo').click()">Filter for: drugs</p>

<p onclick = "document.getElementById('searchCombo').value = 'element 3'; document.getElementById('searchCombo').click()">Filter for: medications</p>

<input type = "search" id = "searchCombo" placeholder = "Search for combination...">

<ul ID = "list1" class = "combo">
    <li><a href = "#">List 1 element 1</a></li>
    <li><a href = "#">List 1 element 2</a></li>
    <li><a href = "#">List 1 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

<ul ID = "list2" class = "combo">
    <li><a href = "#">List 2 element 1</a></li>
    <li><a href = "#">List 2 element 2</a></li>
    <li><a href = "#">List 2 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

<ul ID = "list3" class = "combo">
    <li><a href = "#">List 3 element 1</a></li>
    <li><a href = "#">List 3 element 2</a></li>
    <li><a href = "#">List 3 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

Это javascript:

<script>
    /* drug combo search */
    const select_all = (selector, selectee = document) =>
        Array.from(selectee.querySelectorAll(selector));

    const hide_item = item => item.style.display = 'none';
    const show_item = item => item.style.display = '';
    const item_text = item => item.textContent.toLowerCase();
    const compare = text => item => item_text(item).includes(text);
    const has_class = class_name => item => item.className.includes(class_name);
    const not_has_class = class_name => item => !has_class(class_name)(item);

    const filter_list = text => list => {
        let lis = select_all("li", list);
        let to_show = lis
            .filter(not_has_class('none'))
            .filter(compare(text));

        if (to_show.length === 0)
            to_show = lis.filter(has_class('none'));

        lis.forEach(hide_item);
        to_show.forEach(show_item);
    };

    const filter = (event) =>
        select_all(".combo").forEach(
            filter_list((event?.target?.value || '').toLowerCase())
        );

    document.getElementById('searchCombo').addEventListener("keyup", filter);

    filter();

</script>
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
0
223
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот рабочая демонстрация Рабочая демонстрация Jsbin

HTML

<p id = "filter1">Filter for: vitamins</p>
<p id = "filter2">Filter for: drugs</p>
<p id = "filter3">Filter for: medications</p>

<input type = "search" id = "searchCombo" placeholder = "Search for combination...">

<ul ID = "list1" class = "combo">
    <li><a href = "#">List 1 element 1</a></li>
    <li><a href = "#">List 1 element 2</a></li>
    <li><a href = "#">List 1 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

<ul ID = "list2" class = "combo">
    <li><a href = "#">List 2 element 1</a></li>
    <li><a href = "#">List 2 element 2</a></li>
    <li><a href = "#">List 2 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

<ul ID = "list3" class = "combo">
    <li><a href = "#">List 3 element 1</a></li>
    <li><a href = "#">List 3 element 2</a></li>
    <li><a href = "#">List 3 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul> 

JS

const select_all = (selector, selectee = document) =>
Array.from(selectee.querySelectorAll(selector));

const hide_item = item => item.style.display = 'none';
const show_item = item => item.style.display = '';
const item_text = item => item.textContent.toLowerCase();
const compare = text => item => item_text(item).includes(text);
const has_class = class_name => item => item.className.includes(class_name);
const not_has_class = class_name => item => !has_class(class_name)(item);

const filter_list = text => list => {
    let lis = select_all("li", list);
    let to_show = lis
        .filter(not_has_class('none'))
        .filter(compare(text));

    if (to_show.length === 0)
        to_show = lis.filter(has_class('none'));

    lis.forEach(hide_item);
    to_show.forEach(show_item);
};

const filter = (value) =>
    select_all(".combo").forEach(
        filter_list((value || '').toLowerCase())
    );

const searchCombo = document.getElementById('searchCombo')
searchCombo.addEventListener("keyup", function(e) {
    filter(e.target.value)
});
//Trigger filter when search input field cancel is clicked
searchCombo.addEventListener("search", function(e) {
    filter('')
});

function trigger(value) {
    searchCombo.value = value;
    filter(value)
}
document.getElementById('filter1').addEventListener("click", function() {
    trigger('element 1')
});
document.getElementById('filter2').addEventListener("click", function() {
    trigger('element 2')
});
document.getElementById('filter3').addEventListener("click", function() {
    trigger('element 3')
});


filter(); 

Спасибо! Нет ли способа добавить событие onclick в HTML-документ без редактирования javascript?

suverenia 12.12.2020 01:11
Ответ принят как подходящий

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

Я думаю, что вам не нужны теги a здесь, если они вам не нужны, пока вы перемещаете class = "filter_to" data-filter_to_term = "element 1" на теги p.

const select_all = (selector, selectee = document) =>
  Array.from(selectee.querySelectorAll(selector));

const hide_item = item => item.style.display = 'none';
const show_item = item => item.style.display = '';
const item_text = item => item.textContent.toLowerCase();
const compare = text => item => item_text(item).includes(text);
const has_class = class_name => item => item.className.includes(class_name);
const not_has_class = class_name => item => !has_class(class_name)(item);

const filter_list = text => list => {
  let lis = select_all("li", list);
  let to_show = lis
    .filter(not_has_class('none'))
    .filter(compare(text));

  if (to_show.length === 0)
    to_show = lis.filter(has_class('none'));

  lis.forEach(hide_item);
  to_show.forEach(show_item);
};

const search_box = document.getElementById('searchCombo');

const filter = (text) =>
  select_all(".combo").forEach(
    filter_list((text || '').toLowerCase())
  );

const set_filter = (text) => {
  search_box.value = text;
  filter(text);
};

const onclick_filter_to = (event) => {
  event.preventDefault();
  set_filter(event.target.dataset.filter_to_term);
};

select_all(".filter_to").forEach(
  (element) => element.addEventListener("click", onclick_filter_to)
);

search_box.addEventListener("input", event => filter(event.target.value));

filter();
<p><a href = "#" class = "filter_to" data-filter_to_term = "element 1">Filter for: vitamins</a></p>

<p><a href = "#" class = "filter_to" data-filter_to_term = "element 2">Filter for: drugs</a></p>

<p><a href = "#" class = "filter_to" data-filter_to_term = "element 3">Filter for: medications</a></p>

<input type = "search" id = "searchCombo" placeholder = "Search for combination...">

<ul ID = "list1" class = "combo">
    <li><a href = "#">List 1 element 1</a></li>
    <li><a href = "#">List 1 element 2</a></li>
    <li><a href = "#">List 1 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

<ul ID = "list2" class = "combo">
    <li><a href = "#">List 2 element 1</a></li>
    <li><a href = "#">List 2 element 2</a></li>
    <li><a href = "#">List 2 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

<ul ID = "list3" class = "combo">
    <li><a href = "#">List 3 element 1</a></li>
    <li><a href = "#">List 3 element 2</a></li>
    <li><a href = "#">List 3 element 3</a></li>
    <li class = "none">Nothing found in this category</li>
</ul>

Похоже, что замена keyup вводом может работать для кнопки отмены X в Chrome (но я не использовал это раньше).

Другие вопросы по теме