繁体   English   中英

使用 jQuery/AJAX 过滤来自 JSON 数据的复选框的结果

[英]Filtering results with checkboxes from JSON data using jQuery/AJAX

我正在尝试使用高级过滤功能制作搜索页面。 董事、评级和年份应显示在侧边栏中,不得重复。 选中一个框时,包含电影的过滤结果应显示在同一页面上,然后在未选中任何框时消失。

例如,您应该能够选中“弗朗西斯·福特·科波拉”框并获得由他执导的电影列表(“教父”和“局外人”),或者如果您也单击复选框以获得评级 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>

任何帮助将不胜感激,因为我已经尝试这样做了一段时间。

您可以执行以下操作来为标准“导演”、“评级”和“年份”生成过滤条件:

 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>

你可能已经注意到,把这些放在一起花了我一段时间,我分几期完成。 就像在编码中一样,我倾向于写东西,看看它,然后很快又把它扔掉。 对我来说,设计需要流畅地发展,允许频繁重写,直到“最终”(没有这样的东西😁)布局类似于我正在寻找的。

年份不应该是一个复选框,它应该是一个用户可以输入的文本框(四个字符的数字)。
API 调用应使用参数,如年份(文本框)、评级(选择)、导演(文本框)等来过滤电影,而不是在一次调用中转储 100 部电影。
您还可以为导演和头衔自动完成,当用户填写字段时,API 仅检索导演或头衔。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM