[英]Making a Search Filter with JQuery?
所以我有一个由一些json数据制成的表格...
{
"AKH":{
"name": "Amonkhet",
"code": "AKH"
"cards": [
{
"artist": "Izzy",
"cmc": 3,
"colorIdentity": [
"W"
],
"colors": [
"White"
],
"id": "df3a6e0336684c901358f3ff53ec82ff5d7cdb9d",
"imageName": "gideon of the trials",
"layout": "normal",
"loyalty": 3,
"manaCost": "{1}{W}{W}",
"multiverseid": 426716,
"name": "Gideon of the Trials",
"number": "14",
"rarity": "Mythic Rare",
"subtypes": [
"Gideon"
],
"text": "+1: Until your next turn, prevent all damage target permanent would deal.\n0: Until end of turn, Gideon of the Trials becomes a 4/4 Human Soldier creature with indestructible that's still a planeswalker. Prevent all damage that would be dealt to him this turn.\n0: You get an emblem with \"As long as you control a Gideon planeswalker, you can't lose the game and your opponents can't win the game.\"",
"type": "Planeswalker — Gideon",
"types": [
"Planeswalker"
]
},
每张卡的“表格”行最终看起来都是这样。 目前,我仅将ID,卡名和法力消耗附加到每一行
<td><a href="#" onclick="showInfo(this.id)"
id="df3a6e0336684c901358f3ff53ec82ff5d7cdb9d">Gideon of the Trials</a></td>
现在,我想搜索这些卡片。 (请记住,列表中将有17,000多种不同的卡片),我可以找到它。.但是我遇到了几个不同的问题...要么找到了所有问题,但没有隐藏其余的问题,或隐藏整个列表,仅显示找到的一张牌。
所以问题A ...我缺少什么才能使搜索正常进行?
$(document).on('change', 'input[type=checkbox]', function() {
var lis = $('.cardsRow')
$('input[type=checkbox]').filter(':checked').each(function(){
filterKeyB = $(this).attr('id')
filterKeyA = $(this).attr('name')
$.each(json, function(setCode, setListing) {
$.each(setListing.cards,function(cardNum, cardListing){
var x = Object.keys(cardListing)
var y = Object.keys(cardListing).map(function (key){
return cardListing[key]
})
for (i = 0; (i < x.length); i++) {
if(x[i] === filterKeyA){
if (y[i] instanceof Array){
var holder = y[i]
var valueArr =[]
for(var k = 0; k < holder.length; k++){
valueArr = holder.join('|').toLowerCase().split('|')
var foundIt = valueArr.includes(filterKeyB)
}
}else{
var stringy = y[i]
var stringyA= stringy.toLowerCase().replace(/\s/g, '')
if (stringyA === filterKeyB){
var foundIt = true
}
}
if(foundIt === true){
$winner = cardListing.name
for (k = 0; (k < lis.length); k++){
if (lis[k].innerText.indexOf($winner) != -1) {
$(lis[k]).show()
}
}
}
}
}
})
问题B ...既然您已经在这里...更好的做法是将可以搜索的数据附加到元素本身? 也许只是搜索次数最多的(例如“名称”和“法力”),并且是否有更高级的查询再次遍历数据?
我不明白为什么代码无法正常工作,甚至无法正常工作,它似乎引用了一些示例中未定义的函数。 但我可以与您分享一种非常简单/直观的过滤方法,希望您觉得它有用。
本地过滤器方法对于您要尝试执行的操作非常有用,它接受一个将当前元素作为arg并返回true或false的回调,如果为true,则该元素包含在它生成的新数组中。
但是filter只需要一个函数,并且您有很多过滤器,因此让我们做一个将多个过滤器Fns组合为一个fn的函数,这样就可以一次全部传递它们:
const combineFilters = (...fns) => val => fns.reduce((prev, curr) => prev || curr(val), false);
OK,如何将过滤器功能的名称作为键存储在对象中,以便我们可以使用字符串引用它们? 这样,我们可以为每个复选框指定一个ID,该ID与应该应用的过滤器功能的名称相对应,并使事情真正易于实现(并易于阅读):
const filterFns = {
startsWithG(card) {
return card.name[0] === 'G';
},
//etc.
};
好了,该花点时间获取所有选中的复选框的ID,然后将它们映射到功能数组中。
const filters = $('input[type=checkbox]')
.filter(':checked')
.map((e, i) => $(i).attr('id'))
.get()
.map(fnName => filterFns[fnName])
(假设相关数据存储在名为... data的var中。)我们可以将CombineFilters与过滤器(Fns数组)结合使用以激活所有相关过滤器,然后将匹配对象的结果数组映射到HTML的HTML中选择。
const matches = data.cards
.filter(combineFilters(...filters))
.map(card => `<div>${card.name}</div>` );
然后用您的匹配项更新DOM!
正如其他人指出的那样,如果您需要对对象或数组进行任何更复杂的过滤,那么lodash库是您的朋友!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.