使用搜索字词过滤json数组

时间:2019-03-03 11:18:03

标签: javascript arrays json ajax filter

我知道这个问题似乎已经被回答过了,但是我待了三天,并没有什么能真正帮助我彻底解决问题。我有一个很大的json文件,想要建立一个搜索栏以对其进行过滤。我希望搜索栏搜索整个json文件,但是我不知道该怎么做。 这就是我得到的。它的效果很好,但我只能搜索一个属性。 参见js代码的第73行。 我尝试使用变量或数组而不是属性,但是它不起作用。 我该如何过滤整个json文件。

var products;
var request = new XMLHttpRequest();
request.open('GET', 'json/ToS.json');
request.responseType = 'json';

request.onload = function() {
  if(request.status === 200) {
    products = request.response;
    initialize();
  } else {
    console.log('Network request for products.json failed with response ' + request.status + ': ' + request.statusText)
  }
};

request.send();

function initialize() {
  var category = document.querySelector('#category');
  var searchTerm = document.querySelector('#searchTerm');
  var searchBtn = document.querySelector('button');
  var main = document.querySelector('main');

  var lastCategory = category.value;
  var lastSearch = '';

  var categoryGroup;
  var finalGroup;

  finalGroup = products;
  updateDisplay();

  categoryGroup = [];
  finalGroup = [];

  searchBtn.onclick = selectCategory;

  function selectCategory(e) {
    e.preventDefault();

    // Set these back to empty arrays, to clear out the previous search
    categoryGroup = [];
    finalGroup = [];

    if(category.value === lastCategory && searchTerm.value.trim() === lastSearch) {
      return;
    } else {
      lastCategory = category.value;
      lastSearch = searchTerm.value.trim();
      if(category.value === 'All') {
        categoryGroup = products;
        selectProducts();
      } else {
        var lowerCaseType = category.value.toLowerCase();
        for(var i = 0; i < products.length ; i++) {
          if(products[i].type === lowerCaseType) {
            categoryGroup.push(products[i]);
          }
        }

        selectProducts();
      }
    }
  }

  function selectProducts() {
    if(searchTerm.value.trim() === '') {
      finalGroup = categoryGroup;
      updateDisplay();
    } else {
      var lowerCaseSearchTerm = searchTerm.value.trim();
      for(var i = 0; i < categoryGroup.length ; i++) {
        var searchField = ['Site', 'ID', 'Gorge', 'Quantity of Artefacts']; 
        if(categoryGroup[i].Gorge.indexOf(lowerCaseSearchTerm) !== -1) {
            finalGroup.push(categoryGroup[i]);
        }
      }

      updateDisplay();
    }

}

  function updateDisplay() {
    while (main.firstChild) {
      main.removeChild(main.firstChild);
    }

    if(finalGroup.length === 0) {
      var para = document.createElement('p');
      para.textContent = 'No results to display!';
      main.appendChild(para);
    } else {
      for(var i = 0; i < finalGroup.length; i++) {
        fetchBlob(finalGroup[i]);
      }
    }
  }

  function fetchBlob(product) {
    var url = 'img/' + product.ID +".jpg";

    var request = new XMLHttpRequest();
    request.open('GET', url);
    request.responseType = 'blob';

    request.onload = function() {
      if(request.status === 200) {
          var blob = request.response;
          var objectURL = URL.createObjectURL(blob);
          showProduct(objectURL, product);
      } else {
        console.log('Network request for "' + product.name + '" image failed with response ' + request.status + ': ' + request.statusText);
    showProduct(objectURL, product);
    }
    };

    request.send();
  }

  function showProduct(objectURL, product) {
    var section = document.createElement('section');
    var heading = document.createElement('h2');
    var para = document.createElement('p');
    var image = document.createElement('img');

    section.setAttribute('class', product.Site);
    heading.textContent = product.Site.replace(product.Site.charAt(0), product.Site.charAt(0).toUpperCase());

    para.setAttribute('style', 'white-space: pre;')
    para.textContent = "ID: " + product.ID + "\r\nSite: " + product.Site + "\r\nGorge: " + product.Gorge;

    image.src = objectURL;
    image.alt = product.Site;

    main.appendChild(section);
    section.appendChild(heading);
    section.appendChild(para);
    section.appendChild(image);
  }
}
* {
    box-sizing: border-box;
}

body {
    font-family: 'Lato';
    font-family: Arial;
    margin: 0;
}

.header {
    padding: 60px;
    text-align: center;
    background: #1abc9c;
    color: white;
}

.navbar {
    display: flex;
    top: 0;
    position: sticky;
    background-color: #333;
}

.navbar a {
    color: white;
    padding: 14px 20px;
    text-decoration: none;
    text-align: center;
}

.navbar a:hover {
    background-color: #ddd;
    color: black;
}

.row {
    display: flex;
    flex-wrap: wrap;
}

.filters {
    flex: 20%;
    background-color: #f1f1f1;
    padding: 20px;
}

.main {
    flex: 80%;
    background-color: white;
    padding: 20px;
}

.fakeimg {
    background-color: #aaa;
    width: 100%;
    padding: 20px;
}

.footer {
    padding: 20px;
    text-align: center;
    background: #ddd;
}

@media screen and (max-width: 700px) {

    .row,
    .navbar {
        flex-direction: column;
    }
}

#topBtn {
    display: none;
    height: 64px;
    width: 64px;
    position: fixed;
    bottom: 20px;
    right: 30px;
    border: none;
    outline: none;
    cursor: pointer;
    background-color: rgba(0, 0, 0, 0);
    background-image: url("../img/icons/back-top.png")
}
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Brandberg-Portal</title>
    <link rel="stylesheet" type="text/css" href="css/style.css">
    <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <header id="header"></header>
    <div class="header">
        <h1>Brandberg</h1>
        <p>Find <b>everything</b> about the Brandberg.</p>
    </div>
    <div class="navbar">
        <a href="#">Link</a>
        <a href="#">Link</a>
        <a href="#">Link</a>
        <a href="#">Link</a>
    </div>
    <div class="row">
        <div class="filters">
            <h2>Filters</h2>
            <form>
                <label for="searchTerm">Search:</label>
                <input type="text" id="searchTerm" name="searchTerm" placeholder="Search">
                <div id="returnJSONValue"></div>
                <h3>Categories</h3>
                <select id=category>
                    <option selected>All</option>
                    <option>Images </option>
                    <option>Books</option>
                    <option>Sites</option>
                </select>
                <button>Filter results</button>
            </form>
        </div>
        <div class="main">
            <main>

            </main>
        </div>
    </div>
    <div class="footer">
        <h2>Footer</h2>
        <button onclick="topFunction()" id="topBtn" title="Nach oben"></button>
        <script src="script.js"></script>
</body>

</html>

这是json文件的摘要:

[
 {
   "ID": 1,
   "Site": "A 1",
   "Longitude UTM": 446253.881,
   "Latitude UTM": 7657736.83,
   "Elevation": 1343.3374,
   "Gorge": "Amis",
   "Site Nickname": "",
   "Discoverer": "",
   "Date of Discovery": "",
   "Publication": "Pager; Harald: The Rock Paintings of the Upper Brandberg; Part 1 � Amis Gorge. Africa Praehistorica 1 (K�ln: Heinrich Barth Institut); 1989.",
   "ISBN 10": "3-927688-01-0",
   "Site Pager": "A 1",
   "Number of Figures": 44,
   "Figure Category": "4",
   "Distance to next Site": 590.7813,
   "Next Site": "A 4",
   "Cardinal Points": "SE",
   "Painting Location": "5; 6",
   "Water in Sight": null,
   "Water Availability": ">300m",
   "Open Field in Sight": null,
   "Open Field": "adjacent",
   "Living Place": "unfavourable",
   "Spatiality": "19",
   "Visibility": "<15m",
   "Context": "isolated",
   "View from Site": "magnificent",
   "Evidence of Human Occupation": "NA",
   "Degradation of Paintings": "NA",
   "Quantity of Artefacts": "medium quantity",
   "Lithics": "NA",
   "Pottery": "NA",
   "O.E.S.": "NA",
   "Bone": "NA",
   "Charcoal": "NA",
   "Grinding Implements": "NA",
   "Stone Structures": "NA",
   "Miscellenous Artefact": "NA",
   "Remarks": ""
 },
 {
   "ID": 2,
   "Site": "A 2",
   "Longitude UTM": 447469.166,
   "Latitude UTM": 7657906.65,
   "Elevation": 1349.5029,
   "Gorge": "Amis",
   "Site Nickname": "",
   "Discoverer": "",
   "Date of Discovery": "",
   "Publication": "Pager; Harald: The Rock Paintings of the Upper Brandberg; Part 1 � Amis Gorge. Africa Praehistorica 1 (K�ln: Heinrich Barth Institut); 1989.",
   "ISBN 10": "3-927688-01-0",
   "Site Pager": "A 2",
   "Number of Figures": 91,
   "Figure Category": "3",
   "Distance to next Site": 43.481,
   "Next Site": "A 3",
   "Cardinal Points": "NW",
   "Painting Location": "5; 8; 11",
   "Water in Sight": null,
   "Water Availability": "within shouting distance",
   "Open Field in Sight": true,
   "Open Field": "within shouting distance",
   "Living Place": "spacious",
   "Spatiality": "16",
   "Visibility": "<15m",
   "Context": "marginal",
   "View from Site": "poor",
   "Evidence of Human Occupation": "NA",
   "Degradation of Paintings": "NA",
   "Quantity of Artefacts": "none",
   "Lithics": "NA",
   "Pottery": "NA",
   "O.E.S.": "NA",
   "Bone": "NA",
   "Charcoal": "NA",
   "Grinding Implements": "NA",
   "Stone Structures": "NA",
   "Miscellenous Artefact": "NA",
   "Remarks": ""
 },
 {
   "ID": 3,
   "Site": "A 3",
   "Longitude UTM": 447975.713,
   "Latitude UTM": 7657099.186,
   "Elevation": 1354.0356,
   "Gorge": "Amis",
   "Site Nickname": "",
   "Discoverer": "",
   "Date of Discovery": "",
   "Publication": "Pager; Harald: The Rock Paintings of the Upper Brandberg; Part 1 � Amis Gorge. Africa Praehistorica 1 (K�ln: Heinrich Barth Institut); 1989.",
   "ISBN 10": "3-927688-01-0",
   "Site Pager": "A 3",
   "Number of Figures": 223,
   "Figure Category": "2",
   "Distance to next Site": 43.481,
   "Next Site": "A 2",
   "Cardinal Points": "NW",
   "Painting Location": "5; 6; 10",
   "Water in Sight": null,
   "Water Availability": "within shouting distance",
   "Open Field in Sight": null,
   "Open Field": "within shouting distance",
   "Living Place": "spacious",
   "Spatiality": "10",
   "Visibility": "<15m",
   "Context": "marginal",
   "View from Site": "poor",
   "Evidence of Human Occupation": "NA",
   "Degradation of Paintings": "NA",
   "Quantity of Artefacts": "many",
   "Lithics": "NA",
   "Pottery": "NA",
   "O.E.S.": "NA",
   "Bone": "NA",
   "Charcoal": "NA",
   "Grinding Implements": "NA",
   "Stone Structures": "NA",
   "Miscellenous Artefact": "NA",
   "Remarks": ""
 },
 {
   "ID": 831,
   "Site": "U 58",
   "Longitude UTM": 453634.054,
   "Latitude UTM": 7667435.316,
   "Elevation": 1878.5487,
   "Gorge": "Umuab",
   "Site Nickname": "",
   "Discoverer": "Shipahu",
   "Date of Discovery": "21.03.1983",
   "Publication": "Pager; Harald: The Rock Paintings of the Upper Brandberg; Part 4 � Umuab and Karoab Gorges. Africa Praehistorica 10 (K�ln: Heinrich Barth Institut); 1998.",
   "ISBN 10": "3-927688-16-9",
   "Site Pager": "U 58",
   "Number of Figures": 9,
   "Figure Category": "5",
   "Distance to next Site": 105.1026,
   "Next Site": "U 59",
   "Cardinal Points": "E",
   "Painting Location": "1",
   "Water in Sight": true,
   "Water Availability": "adjacent",
   "Open Field in Sight": null,
   "Open Field": ">300m",
   "Living Place": "� vertical rock",
   "Spatiality": "0",
   "Visibility": "<15m",
   "Context": "marginal",
   "View from Site": "rather nice",
   "Evidence of Human Occupation": "none",
   "Degradation of Paintings": "water run-off",
   "Quantity of Artefacts": "none",
   "Lithics": "NA",
   "Pottery": "NA",
   "O.E.S.": "NA",
   "Bone": "NA",
   "Charcoal": "NA",
   "Grinding Implements": "NA",
   "Stone Structures": "NA",
   "Miscellenous Artefact": "NA",
   "Remarks": ""
 },
 {
   "ID": 832,
   "Site": "U 59",
   "Longitude UTM": 453919.687,
   "Latitude UTM": 7667338.425,
   "Elevation": 1918.9147,
   "Gorge": "Umuab",
   "Site Nickname": "",
   "Discoverer": "Dr. D. Craven",
   "Date of Discovery": "18.08.1984",
   "Publication": "Pager; Harald: The Rock Paintings of the Upper Brandberg; Part 4 � Umuab and Karoab Gorges. Africa Praehistorica 10 (K�ln: Heinrich Barth Institut); 1998.",
   "ISBN 10": "3-927688-16-9",
   "Site Pager": "U 59",
   "Number of Figures": 3,
   "Figure Category": "6",
   "Distance to next Site": 105.1026,
   "Next Site": "U 58",
   "Cardinal Points": "NE",
   "Painting Location": "10",
   "Water in Sight": true,
   "Water Availability": "adjacent",
   "Open Field in Sight": null,
   "Open Field": ">300m",
   "Living Place": "spacious",
   "Spatiality": "5",
   "Visibility": "<3m",
   "Context": "isolated",
   "View from Site": "magnificent",
   "Evidence of Human Occupation": "none",
   "Degradation of Paintings": "water run-off",
   "Quantity of Artefacts": "medium quantity",
   "Lithics": "NA",
   "Pottery": "NA",
   "O.E.S.": "NA",
   "Bone": "NA",
   "Charcoal": "NA",
   "Grinding Implements": "NA",
   "Stone Structures": "NA",
   "Miscellenous Artefact": "NA",
   "Remarks": ""
 }]

1 个答案:

答案 0 :(得分:0)

以下函数将搜索预定义的products对象值数组,并从该数组中返回包含作为参数传递的搜索词的对象。 prop参数仅允许您搜索特定键。

This answer,提供了一些有关如何搜索值数组的见解。

我已经创建了这个JSFiddle,以使用下面的示例来举例说明。

 function searchJson(term, prop) {

    if (products.length < 1) {
      return;
    }

    const matches = [];

    for (let i = 0; i < products.length; i++) {

      var exists = Object.keys(products[i]).some((k) => {
        if (null !== products[i][k]) {
          if (prop === 'All') {
            return products[i][k].toString().indexOf(term) > -1;
          }
          return products[i][prop].toString().indexOf(term) > -1;
        }
      });

      if (exists) {
        matches.push(products[i]);
      }

    }
    return matches;

  }

希望这会有所帮助。