【问题标题】:Need to apply multiple filters to JSON data需要对 JSON 数据应用多个过滤器
【发布时间】:2020-01-01 16:09:53
【问题描述】:

在我的项目中,我有一个 JSON 文件,其中包含吉他及其相关数据。我正在尝试创建三个过滤器(品牌、类别和条件),在单击它们时立即加载相应的数据。我的功能适用于一个过滤器,但我不知道如何结合所有三个。

最初会显示所有吉他,然后在应用每个过滤器时立即过滤。我该怎么办?我意识到一系列点击过滤器是有序的,但目前完成这项工作超出了我的能力。

示例 JSON

{
    "product_id": "0",
    "category": "electric",
    "condition": "used",
    "justIn": "true",
    "brand": "gibson",
    "year": "1952",
    "code": "456def",
    "img1": "../img/sale/gibson/295-1.jpg",
    "img2": "../img/sale/gibson/295-2.jpg",
    "img3": "../img/sale/gibson/295-3.jpg",
    "img4": "../img/sale/gibson/295-4.jpg",
    "alt": "gibson guitar",
    "title": "Gibson ES-295 1952",
    "price": "6000.00",
    "description": "A beautiful ES-295 with wear you can't fake! The ES-295 was originally produced from 1952 to 1958 and is best known for being the model played by Scotty Moore with Elvis. This particular example plays well with a fantastic feeling neck! The guitar has heavy finish wear with the beautiful greening that you often see on '50s goldtops. Glaser has refretted the guitar and replaced the tailpiece crossbar. The pickguard is missing.",
    "specs": ["Body Wood - Laminated Maple",
              "Neck Wood - Mahogany",
              "Fingerboard Wood - Rosewood",
              "Scale Length - 24.75",
              "Nut Width - 1 11/16",
              "Pickup(s) - Original P-90s",
              "Case - Hard Case"
            ]
  }

过滤点击监听器

  $("#collapseOne, #collapseTwo, #collapseThree").change("click", e => {
    const checkbox = e.target
    const key = e.target.getAttribute('data-name')
    const id = e.target.id

    loadWithFilter(checkbox, key, id)
  })

数据加载功能。根据我提供的 JSON,key = brand, value = fender

const loadWithFilter = (checkbox, key, value) => {
    $.getJSON("../../json/guitars.json", data => {

      let dataArr = data
      let filterArr = []
      let guitar_data = ""


      for(let i in dataArr) {

        // data
        const image1 = dataArr[i].img1
        const alt = dataArr[i].alt
        const title = dataArr[i].title
        const price = dataArr[i].price

        // filters
        const id = dataArr[i].product_id
        const brand = dataArr[i].brand
        const category = dataArr[i].category
        const condition = dataArr[i].condition

        if (value === brand && $(checkbox).prop("checked") == true) {
          cardElements()
        }
        if ($(checkbox).prop("checked") == false) {
          cardElements()
        }

        function cardElements() {
          guitar_data += `<div class="gallery-card" data-brand="${brand}" data-category="${category}" data-condition="${condition}">`
          guitar_data += `<img class="more-info img-fluid" src="../${image1}" alt="${alt}" data-id="${id}">`
          guitar_data += `<h6>${title}</h6>`
          guitar_data += `<p class="text-center"><strong>$ ${price}</strong></p>`
          guitar_data += '</div>'

          $('#img-gallery').html(guitar_data)
        }
      }
    })
  }

【问题讨论】:

    标签: javascript jquery json filter


    【解决方案1】:

    构建过滤器需要结合各种 javascript 方法(如 filtermap),请查看以下设置,该设置演示了过滤数据的可能设置。

    尝试将过滤器输入(参见演示)从 new 更改为 used 或清除它以查看结果变化。

       const resultElem = document.querySelector('#results');
        const filtersElem = document.querySelector('#filters');
    
        const products = [
            {
                "product_id": "0",
                "category": "electric",
                "condition": "used",
                "justIn": "true",
                "brand": "gibson",
                "year": "1952",
                "code": "456def",
                "alt": "used gibson guitar",
                "title": "Gibson ES-295 1952",
                "price": "6000.00",
                "description": "A beautiful ES-295 with wear you can't fake! The ES-295 was originally produced from 1952 to 1958 and is best known for being the model played by Scotty Moore with Elvis. This particular example plays well with a fantastic feeling neck! The guitar has heavy finish wear with the beautiful greening that you often see on '50s goldtops. Glaser has refretted the guitar and replaced the tailpiece crossbar. The pickguard is missing.",
            },
            {
                "product_id": "0",
                "category": "electric",
                "condition": "new",
                "justIn": "true",
                "brand": "yama",
                "year": "1952",
                "code": "456def",
                "img1": "../img/sale/gibson/295-1.jpg",
                "img2": "../img/sale/gibson/295-2.jpg",
                "img3": "../img/sale/gibson/295-3.jpg",
                "img4": "../img/sale/gibson/295-4.jpg",
                "alt": "yama guitar",
                "title": "new yama ES-295 1952",
                "price": "6000.00",
                "description": "A beautiful ES-295 with wear you can't fake! The ES-295 was originally produced from 1952 to 1958 and is best known for being the model played by Scotty Moore with Elvis. This particular example plays well with a fantastic feeling neck! The guitar has heavy finish wear with the beautiful greening that you often see on '50s goldtops. Glaser has refretted the guitar and replaced the tailpiece crossbar. The pickguard is missing.",
            }
        ];
    
        const buildResult = ({product_id: id, title, price, brand, category, condition, image1, alt}) => {
            return `<div class="gallery-card" data-brand="${brand}" data-category="${category}" data-condition="${condition}">
             <img class="more-info img-fluid" src="../${image1}" alt="${alt}" data-id="${id}">
             <h6>${title}</h6>
             <p class="text-center"><strong>$ ${price}</strong></p>
             </div>`
        };
    
        const filterResults = () => {
            const currentFilters = [...document.querySelectorAll('.filter')].map(filterElem => ({
                field: filterElem.dataset.field,
                value: filterElem.value
            }));
    
            const productsThatMatchCriteria = products.filter(product => {
                return currentFilters.every(filter => {
                    return filter.value === '-1' || product[filter.field] === filter.value
                })
            });
    
            const resultsFormattedAtHtml = productsThatMatchCriteria.map(product => buildResult(product)).join('');
    
            resultElem.innerHTML = resultsFormattedAtHtml;
        };
    
        const loadFilters = (fields) => {
            const possibleValues = {};
    
            products.forEach(product => {
                fields.forEach(fieldName => {
                    if (!possibleValues.hasOwnProperty(fieldName)) {
                        possibleValues[fieldName] = new Set();
                    }
    
                    possibleValues[fieldName].add(product[fieldName]);
                })
            });
    
            const selectors = Object.keys(possibleValues).map(fieldName => {
                return `<select class="filter" name="filter[${fieldName}]" data-field="${fieldName}">
                        <option value="-1">All</option>
                        ${[...possibleValues[fieldName]].map(option => `<option value="${option}">${option}</option>`).join('')}
                    </select>`
            }).join('');
    
            filtersElem.innerHTML = selectors;
    
            document.querySelectorAll('.filter').forEach(filter => {
                filter.addEventListener('change', e => {
                    filterResults();
                })
            })
        };
    
        loadFilters(['brand', 'year', 'condition'])
        filterResults();
    <h1>Filter</h1>
    <div>
        <div id="filters">
    
        </div>
    </div>
    <h2>Results</h2>
    <div>
        <div id="results"></div>
    </div>

    【讨论】:

    • 这很有帮助,但即使在您的示例中,它也只是一个过滤器。我无法应用多个过滤器。假设我只想查看 Gibson 吉他,然后从该列表中我只想查看使用过的型号。我需要应用三个相互独立的过滤器。我总是可以选择过滤器然后作为一个提交,但我希望能够独立添加或删除过滤器。
    • 啊,我明白了,我更新了示例以包含各种过滤器的组合。 @JeffS
    • 太棒了!我会研究这个,看看我能学到什么,并在我合并代码后报告回来。谢谢
    • 过滤器设置有帮助吗? @JeffS
    • 说实话,代码有点超出我的能力,我很难理解它,更不用说合并它了。我打算逐字删除它,但我的过滤器不是动态生成的,所以我不知道如何调整代码。它显然像你的 sn-p 节目一样工作,让它为我工作是一个挑战。这是我第一次尝试自己做某事,所以我预料到会遇到这些障碍。
    【解决方案2】:

    您可以使用filter 方法来迭代您的数据数组

    const data = [{
      "product_id": "0",
      "category": "electric",
      "condition": "used",
      "justIn": "true",
      "brand": "gibson",
      "year": "1952",
      "code": "456def",
      "img1": "../img/sale/gibson/295-1.jpg",
      "img2": "../img/sale/gibson/295-2.jpg",
      "img3": "../img/sale/gibson/295-3.jpg",
      "img4": "../img/sale/gibson/295-4.jpg",
      "alt": "gibson guitar",
      "title": "Gibson ES-295 1952",
      "price": "6000.00",
      "description": "A beautiful ES-295 with wear you can't fake! The ES-295 was originally produced from 1952 to 1958 and is best known for being the model played by Scotty Moore with Elvis. This particular example plays well with a fantastic feeling neck! The guitar has heavy finish wear with the beautiful greening that you often see on '50s goldtops. Glaser has refretted the guitar and replaced the tailpiece crossbar. The pickguard is missing.",
      "specs": ["Body Wood - Laminated Maple",
        "Neck Wood - Mahogany",
        "Fingerboard Wood - Rosewood",
        "Scale Length - 24.75",
        "Nut Width - 1 11/16",
        "Pickup(s) - Original P-90s",
        "Case - Hard Case"
      ]
    }]
    
    data.filter(item => {
    console.log({
      brand: item.brand,
      condition: item.condition,
      category: item.category
    })
    })

    【讨论】:

    • 我很欣赏 Ahmet 的尝试,但这根本不是我想要做的。过滤器将在我的网页上,如果过滤器参数匹配,我将加载整个对象。此页面提供了我希望完成的示例cartervintage.com/collections/electric-guitars?
    猜你喜欢
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-31
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    相关资源
    最近更新 更多