У меня есть поле поиска, которое фильтрует три разных списка. Мне нужно 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>
Вот рабочая демонстрация Рабочая демонстрация 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();
Если у вас есть некоторая гибкость с 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 (но я не использовал это раньше).
Спасибо! Нет ли способа добавить событие onclick в HTML-документ без редактирования javascript?