我目前正在开发一个网络应用的功能,允许用户动态搜索和过滤卡片列表。我已经完成了过滤和搜索,但随着搜索结果的增长,我最终得到了一个非常慢的页面或者大量的结果来筛选。我认为分页可能是一个解决方案,因为最大数量的结果是数千,最终我希望有非常广泛的过滤按钮,以及基于文本的搜索。
动态屏幕截图:
代码如下:
deckbuilder.js
document.addEventListener("turbolinks:load", function() {
$(document).on("click", ".deck-adjust-button", adjustDeck)
$(document).on("click", "#decklist-submit", submitDecklist)
$(document).on("input", "#list-search", updateMiniList)
})
function adjustDeck(e) {
card_name = $(this).parents('tr').data("name")
card_name_sanitized = card_name.replace(/\s+/g, '-').replace(/,/g, '').replace(/'/g, '').toLowerCase();
num_cards = $(this).parents('tr').find("#num-cards").val()
deck = $(this).text().toLowerCase() + "-deck"
console.log(card_name + "|" + num_cards + "|" + deck)
deck_div = $("#" + deck)
deck_div.find("#" + card_name_sanitized).remove()
if (parseInt(num_cards) > 0) {
deck_div.append("<div id=" + card_name_sanitized + ">" + num_cards + "x " + card_name + "</div>")
}
}
function submitDecklist(e) {
e.preventDefault()
deck_divs = $(".deck")
decklist_decks = []
decklist_name = $('#name').val()
decklist_description = $("#description").val()
deck_divs.each(function(div) {
deck = $(deck_divs[div])
deck_name_raw = deck.find('div').attr("id")
deck_name = deck_name_raw.split("-")[0]
deck_name = deck_name.charAt(0).toUpperCase() + deck_name.slice(1)
deck_div = deck.find('#' + deck_name_raw)
cards_array = []
deck_div.children().each(function() {
card_text = $(this).text().trim()
card_name = card_text.substr(card_text.indexOf(' ')+1)
card_num = parseInt(card_text.substr(0,card_text.indexOf(' ')).replace(/x/g, ''))
cards_array.push({
name: card_name,
num: card_num,
})
})
decklist_decks.push({
name: deck_name,
cards: cards_array
})
})
decklist = {
decklist: {
name: decklist_name,
description: decklist_description,
decks: decklist_decks
}
}
$.ajax({
method: "POST",
url: "/decklists",
data: decklist
})
.done(function( msg ) {
window.location.replace("/decklists/" + msg.id);
})
.fail(function( msg) {
window.location.replace("/decklists/new");
})
}
function updateMiniList(e) {
inputValue = $(this).val().toLowerCase()
listEntries = $(this).parents().siblings('#mini-card-list').find('tr')
listEntries.each(function() {
entry = $(this)
entryName = $(this).data("name").toLowerCase()
if (!entryName.includes(inputValue)) {
entry.hide()
} else {
entry.show()
}
})
if(inputValue.length > 2) {
data = { "name": inputValue }
ApiCall("POST", "/cards/search", data, appendCards)
}
}
function ApiCall(method, target, data, callback) {
$.ajax({
method: method,
url: target,
data: data,
success: callback
})
}
function appendCards(cards) {
cards.forEach(function(card) {
name = card.name
newCardDiv = $('<tr data-name="' + name + '">\
<td>\
<select class="form-control" id="num-cards">\
<option value=0>0</option>\
<option value=1>1</option>\
<option value=2>2</option>\
<option value=3>3</option>\
<option value=4>4</option>\
</select>\
</td>\n\
<td>' + name + '</td>\n\
<td>\
<div class="btn-group btn-group-sm" role="group">\
<button type="button" class="btn btn-secondary deck-adjust-button">Main</button>\
<button type="button" class="btn btn-secondary deck-adjust-button">Stone</button>\
<button type="button" class="btn btn-secondary deck-adjust-button">Side</button>\
<button type="button" class="btn btn-secondary deck-adjust-button">Ruler</button>\
</div>\
</td>\
</tr>')
$('#mini-card-list').find('table').append(newCardDiv)
});
}
new.html.erb(与JS互动的页面)
<div class="container">
<div class="row">
<div class="col">
<h2>Create a New Decklist</h2>
</div>
</div>
<div class="row">
<div class="col-md-5">
<hr>
<h4>Decks</h4>
<hr>
<%= render "decklists/deck_div", deck_name: "Ruler" %>
<%= render "decklists/deck_div", deck_name: "Main" %>
<%= render "decklists/deck_div", deck_name: "Stone" %>
<%= render "decklists/deck_div", deck_name: "Side" %>
<%= render "decklists/form", decklist: @decklist %>
</div>
<div class="col-md-7">
<%= render "cards/mini_list", cards: @cards %>
</div>
</div>
</div>
deck_div partial
<div class="row">
<div class="col deck">
<hr>
<h4><%= deck_name %></h4>
<hr>
<div id="<%= deck_name.downcase + "-deck" %>">
</div>
</div>
</div>
迷你列表部分
<div class="col">
<hr>
<h4>Cards</h4>
<hr>
<div>
<input type="text" placeholder="Search" class="form-control" id="list-search">
</div>
<div id="mini-card-list" style="overflow:scroll; height:400px;">
<table class="table">
</table>
</div>
</div>