使用 jQuery/AJAX 从 JSON 数据中过滤带有复选框的结果
Posted
技术标签:
【中文标题】使用 jQuery/AJAX 从 JSON 数据中过滤带有复选框的结果【英文标题】:Filtering results with checkboxes from JSON data using jQuery/AJAX 【发布时间】:2021-10-01 19:26:58 【问题描述】:我正在尝试制作具有高级过滤功能的搜索页面。董事、评级和年份应显示在侧边栏上,不得重复。选中一个框时,包含电影的过滤结果应显示在同一页面上,然后在没有选中框时消失。
例如,您应该能够选中“弗朗西斯·福特·科波拉”框并获得由他执导的电影列表(“教父”和“局外人”),或者如果您单击复选框进行评级5 同样,您应该只获得“教父”等。
我从来没有使用过 ajax 或 javascript,并且在 php 方面的经验非常有限,所以我很难让任何事情发挥作用
这是端点 api.php?films 中包含的 JSON 数据的摘录,其中包含 100 部影片:
[
"film": "The Bridge on the River Kwai",
"director": "David Lean",
"rating": "2",
"year": "1957"
,
"film": "A Night To Remember",
"director": "Roy Ward Baker",
"rating": "2",
"year": "1958"
,
"film": "The Outsiders",
"director": "Francis Ford Coppola",
"rating": "4",
"year": "1983"
,
"film": "Asylum",
"director": "Roy Ward Baker",
"rating": "3",
"year": "1966"
,
"film": "Trading Places",
"director": "John Landis",
"rating": "5",
"year": "1983"
,
"film": "The Godfather",
"director": "Francis Ford Coppola",
"rating": "5",
"year": "1983"
]
这是我用复选框显示年份的代码,但我需要没有重复的年份(我需要不同的 GET 请求来仅显示年份的唯一值吗?)。至于过滤和显示结果的 JavaScript,我真的需要帮助。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script>
</head>
<body>
<h1>Filter films by year</h1>
<div id='items-container'>
</div>
<script>
$.ajax(
url: "api.php",
method: "GET",
dataType: 'json',
data: 'films',
success: function(data)
console.log(typeof(data));
var html_to_append = '';
$.each(data, function(i, item)
html_to_append +=
'<div class="col-3 mb-3"><p>' +
item.year +
'<input type="checkbox"></p></div>';
);
$("#items-container").html(html_to_append);
,
error: function()
console.log(data);
);
</script>
</body>
</html>
任何帮助将不胜感激,因为我已经尝试这样做了一段时间。
【问题讨论】:
【参考方案1】:您可以执行以下操作来为条件“导演”、“评级”和“年份”生成过滤条件:
const data=["film":"The Bridge on the River Kwai","director":"David Lean","rating":"2","year":"1957",
"film":"A Night To Remember","director":"Roy Ward Baker","rating":"2","year": "1958",
"film":"The Outsiders","director":"Francis Ford Coppola","rating":"4","year": "1983",
"film":"Asylum","director":"Roy Ward Baker","rating":"3","year": "1966",
"film":"Trading Places","director":"John Landis","rating":"5","year": "1983",
"film":"The Godfather","director":"Francis Ford Coppola","rating":"5","year": "1983"];
// define globally: constants, variables and delegated event attachment:
// ---------------------------------------------------------------------
const filt=document.getElementById("filt"),
list=document.querySelector("#list tbody");
let cols=, trs; // arrays for columns sequence in data and all table records
// set up filtering (needs be done only once, before the AJAX call):
filt.addEventListener("change",ev=>let cb=ev.target;
let tst=Object.entries([...filt.querySelectorAll(":checked")].reduce((a,c)=>((a[c.name]=a[c.name]||[]).push(c.value),a), ));
trs.forEach(tr=>
tr.style.display=tst.length==0 || tst.every(([n,arr])=>arr.includes(tr.children[cols[n]].textContent))
?"":"none"
)
);
// put the following code into the "success" function of your AJAX call:
// ---------------------------------------------------------------------
if (data.length) // only if data array is not empty
// columns sequence:
Object.keys(data[0]).forEach((c,i)=>cols[c]=i);
// build the filter-menu structure:
const menu=director:,rating:,year:;
data.forEach(f=>Object.entries(menu).forEach(([k,o])=>o[f[k]]=1));
// translate the filter-menu structure into HTML:
filt.innerHTML=Object.entries(menu).map(([k,o])=>k+':<br>'+
Object.keys(o).map(c=>'<label><input type="checkbox" value="'+c+'" name="'+k+'">'+c+'</label>').join('<br>')
).join('<br>\n');
// fill the main film list with data entries:
list.innerHTML=data.map(f=>'<tr><td>'+Object.values(f).join('</td><td>')+'</td></tr>').join('\n');
trs=[...list.children];
#filt width: 200px; display:inline-block
#list display:inline-block; vertical-align:top
th text-align:left
tbody>tr:nth-child(odd) background-color:#ddd
<div id="filt"></div>
<div id="list"><table><thead><tr><th>Title</th><th>Director</th><th>Rating</th><th>Year</th></tr></thead>
<tbody></tbody></table</tdiv>
您可能已经注意到,将这些放在一起花了我一段时间,我分几期完成了。在编码中,我经常写东西,看看它,然后很快又把它扔掉。对我来说,设计需要流畅地发展,允许频繁重写,直到“最终”(没有这样的东西?)布局类似于我正在寻找的。p>
【讨论】:
这正是我所需要的,谢谢!【参考方案2】:年份不应是复选框,而应是用户可以输入的文本框(四字符数字)。 API 调用应使用参数,如年份(文本框)、评级(选择)、导演(文本框)等来过滤电影,而不是一次调用 100 部电影。 您还可以对导演和头衔进行自动完成,当用户填写字段时,API 仅检索导演或头衔。
【讨论】:
以上是关于使用 jQuery/AJAX 从 JSON 数据中过滤带有复选框的结果的主要内容,如果未能解决你的问题,请参考以下文章
dataType json 的 jQuery $.ajax 请求不会从 PHP 脚本中检索数据
使用jQuery $ .ajax方法显示包含MySQL表数据的JSON [关闭]