javascript - 按文本字段过滤列表
问题描述
我创建了一个小应用程序,可以帮助我提高工作效率。它通过文本内容过滤标签列表。它目前非常适合查找连续的文本行,但我更愿意将其重新实现为适用于非连续文本组合的过滤器。
例如,如果标签内的字符串是“Appleville, MN”,如果您输入“Apple”或“Appleville”或“App”,当前过滤器将找到它,但我希望能够通过输入成功过滤作为“应用程序 MN”。
谁能指出我正确的方向?我不确定我需要使用什么确切的算法。谢谢!
PS:我在下面包含了一些代码,其中包含我正在过滤的搜索项类型、当前过滤器功能以及搜索字段的示例。
function filterList() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById("itemList");
li = ul.getElementsByTagName('li');
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
<input type="text" id="myInput" onkeyup="filterList()" placeholder="Search list..">
<ul id="itemList">
<li onclick=applevilleMN()><a href="#">Appleville, MN</a></li>
<li onclick=orangevilleOR()><a href="#">Orangeville, OR</a></li>
<li onclick=kiwivilleCA()><a href="#">Kiwiville, CA</a></li>
<li onclick=bananavilleCA()><a href="#">Bananaville, CA</a></li>
</ul>
解决方案
这是一个修改后的版本,可以做你想做的事。
它用空格分割过滤器字符串以创建过滤器数组,li
仅当它们对数组的每个子字符串都有效时才显示。
function filterList() {
var input, filter, ul, li, a, i, txtValue;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById("itemList");
li = ul.getElementsByTagName('li');
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
// split filter by spaces, gives ["app", "MN"] in your example
let filters = filter.split(" ")
// remove the empty filters (if your filter string
// starts or ends by a space) since they are source of errors
// Array.filter takes in parameter a function returning a boolean
// it create a new array containing only element where
// the function returned truthy value
// here we return the length of the string which is falsy (== 0) for ""
// and truthy for every other string (!= 0)
filters = filters.filter(f => f.length)
let shouldDisplay = true
// test each filter and store true only if string contains all filter
filters.forEach(filt => {
shouldDisplay = shouldDisplay && txtValue.toUpperCase().includes(filt)
})
// update visibility
// set visible if the string include all filters
// or if there is no filter
li[i].style.display = (shouldDisplay || filters.length === 0) ? "" : "none";
}
}
<ul id="itemList">
<li onclick=applevilleMN()><a href="#" >Appleville, MN</a></li>
<li onclick=orangevilleOR()><a href="#" >Orangeville, OR</a></li>
<li onclick=kiwivilleCA()><a href="#" >Kiwiville, CA</a></li>
<li onclick=bananavilleCA()><a href="#" >Bananaville, CA</a></li>
</ul>
<input type="text" id="myInput" onkeyup="filterList()" placeholder="Search list.." >
推荐阅读
- java - How to create a unit test to detect if someone edited the file using the wrong encoding?
- c# - 使用 JSON.Net 填充不属于 JSON 模式的属性
- visual-studio - 在项目 A 中安装 NuGet 包 项目 B 中的程序集的更新版本
- sql - SELECT 的 CASE WHEN 中的相关子查询如何访问外部表别名?
- excel - 基于单元格值的 VBA 数据传输到其他工作簿
- html - 在 HTML 中转义 powershell 变量
- spring - spring boot 应用程序实际上在端口 0 上运行,而不是随机运行
- r - 修改 base::quit 默认值
- c# - 如何在 Kentico 开发过程中暴露错误
- mongodb - 如何用父文档展平动态字段 - Spring data Mongo DB