使用JQuery制作搜索过滤器?
所以我有一些JSON数据做了一个表...使用JQuery制作搜索过滤器?
{
"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,则该元素将包含在它生成的新数组中。
但过滤只需要一个功能,你有很多的过滤器,所以让我们一起集多种过滤器FNS成一个FN功能,让您可以一次全部通过他们:
const combineFilters = (...fns) => val => fns.reduce((prev, curr) => prev || curr(val), false);
OK ,如何将过滤函数的名称作为键存储在对象中,以便我们可以使用字符串引用它们?这样,我们可以给每个复选框对应于他们应该应用滤镜功能名称的ID,并且使事情变得很容易实现(读):
const filterFns = {
startsWithG(card) {
return card.name[0] === 'G';
},
//etc.
};
OK,时间得到的ID点击所有复选框,然后将它们映射到一个函数数组中。
const filters = $('input[type=checkbox]')
.filter(':checked')
.map((e, i) => $(i).attr('id'))
.get()
.map(fnName => filterFns[fnName])
(假设相关的数据被存储在一个名为VAR ......数据)。我们可以使用combineFilters有过滤器(FNS的阵列)相结合,激活所有的相关的过滤器,然后映射产生的阵列将对象匹配到您选择的HTML中。
const matches = data.cards
.filter(combineFilters(...filters))
.map(card => `<div>${card.name}</div>`);
然后用你的匹配更新DOM的时间!正如其他人已经指出的,如果你需要对对象或数组做更复杂的过滤,lodash库就是你的朋友!
你可以做的第一件事是正确地缩进你的代码?目前它是不可读的。 – Tomalak
对于搜索过滤器,如果您有兴趣,可以使用'lodash'库轻松过滤数据。 https://lodash.com/docs/4.17.4#filter –
对于问题B,我会说是。只是好奇,你在你的应用程序中使用任何服务器端代码?在你的服务器上使用ajax进行搜索会更好也更容易 – Silencer310