2017-06-19 92 views
0

所以我有一些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 ...因为您已经在这里......将搜索数据附加到元素本身会是更好的做法吗?也许只是搜索次数最多的(如名称和法力),并有更先进的查询再次通过数据?

+0

你可以做的第一件事是正确地缩进你的代码?目前它是不可读的。 – Tomalak

+0

对于搜索过滤器,如果您有兴趣,可以使用'lodash'库轻松过滤数据。 https://lodash.com/docs/4.17.4#filter –

+0

对于问题B,我会说是。只是好奇,你在你的应用程序中使用任何服务器端代码?在你的服务器上使用ajax进行搜索会更好也更容易 – Silencer310

回答

0

我不明白为什么代码不工作,甚至它是如何工作的,它看起来像引用了一些未在示例中定义的函数。但我可以与你分享一个非常简单/直观的方式来过滤东西,我希望你觉得它很有用。

本机过滤器方法对于您要做的事情非常有用,它需要一个将当前元素作为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库就是你的朋友!