简体   繁体   English

用 onclick-event 替换搜索字段中的输入不会更新列表

[英]Replacing input in search field with onclick-event does not update list

I have a search field that filters three different lists.我有一个过滤三个不同列表的搜索字段。 I want an onclick -event that adds text to the search field, and replaces any other value there may be.我想要一个onclick -将文本添加到搜索字段并替换可能存在的任何其他值的事件。

I'm able to do so but onclick doesn't update the lists unless I click on the search field and hit enter manually.我可以这样做,但onclick不会更新列表,除非我单击搜索字段并手动输入。 Adding the click() event didn't help.添加click()事件没有帮助。

At the same time, hitting the X in the search field to clear the input doesn't update the lists neither.同时,在搜索字段中点击X以清除输入也不会更新列表。

What can I do?我能做些什么?

<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>

This is the javascript:这是 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>

If you have some flexibility with the HTML, this would be my suggestion:如果您对 HTML 有一定的灵活性,我的建议是:

I think you don't need the a tags here if you don't want them as long as you move the class="filter_to" data-filter_to_term="element 1" on to the p tags.只要将class="filter_to" data-filter_to_term="element 1"移到 p 标签上,我认为您不需要 a 标签。

 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>

It looks like replacing keyup with input might work for the cancel X button in Chrome (but I've not used that before).看起来用输入替换 keyup 可能适用于 Chrome 中的取消 X 按钮(但我以前没有使用过)。

Here is the working demo Jsbin working demo这是工作演示Jsbin 工作演示

HTML 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 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(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM