mardi 25 janvier 2022

Multiple Checkbox Filter is giving me duplicate results

I have a checkbox filter for a product page I'm working on, and it works, but I'm getting duplicate results if an item matches multiple criteria. For example, if I check both 'Size 1' and 'Nike', the resulting product card displays twice. I would like it to only display once. Here's what I have:

let show_sizes_array = []; //Where the filtered sizes get stored

$(document).ready(function() {
  showAllItems(); //Display all items with no filter applied

  $(".size-filter-check").click(function() {
    //When a checkbox is clicked
    let size_clicked = $(this).attr("data-size"); //The certain size checkbox clicked

    if ($(this).is(":checked")) {
      show_sizes_array.push(size_clicked); //Was not checked so add to filter array
      showItemsFiltered(); //Show items grid with filters
    } else {
      //Unchecked so remove from the array
      show_sizes_array = show_sizes_array.filter(function(elem) {
        return elem !== size_clicked;
      });
      showItemsFiltered(); //Show items grid with new filters
    }

    if (!$("input[type=checkbox]").is(":checked")) {
      //No checkboxes are checked
      show_sizes_array = []; //Clear size filter array
      showAllItems(); //Show all items with NO filters applied
    }
  });
});



//Mock API data:
let category_items = [{
    id: 1,
    category_id: 8,
    price: 39.42,
    title: "Shoes with id #1",
    thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
    sizes: ["Size1"],
    brand: ["Nike"]
  },
  {
    id: 2,
    category_id: 8,
    price: 31.93,
    title: "Shoes with id #2",
    thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
    sizes: ["Size2"],
    brand: ["Adidas"]
  },
  {
    id: 3,
    category_id: 8,
    price: 49.44,
    title: "Shoes with id #3",
    thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
    sizes: ["Size3"],
    brand: ["Nike"]
  },
  {
    id: 4,
    category_id: 8,
    price: 65.38,
    title: "Shoes with id #4",
    thumbnail: "https://www.transparentpng.com/download/adidas-shoes/a4xO3G-adidas-shoes-adidas-shoe-kids-superstar-daddy-grade.png",
    sizes: ["Size4"],
    brand: ["Other"]
  },
];

function showAllItems() {
  //Default grid to show all items on page load in
  $("#display-items-div").empty();
  for (let i = 0; i < category_items.length; i++) {
    let item_content =
      '<div class="product-card" data-available-sizes="' +
      category_items[i]["sizes"] +
      '"><b>' +
      category_items[i]["title"] +
      '</b><br><img src="' +
      category_items[i]["thumbnail"] +
      '" height="64" width="64" alt="shoe thumbnail"><p>$' +
      category_items[i]["price"] +
      "</p></div>";
    $("#display-items-div").append(item_content);
  }
}

function showItemsFiltered() {
  //Default grid to show all items on page load in
  $("#display-items-div").empty();
  for (let i = 0; i < category_items.length; i++) {
    //Go through the items but only show items that have size from show_sizes_array
    if (show_sizes_array.some((v) => category_items[i]["sizes"].includes(v))) {
      let item_content =
        '<div class="product-card" data-available-sizes="' +
        category_items[i]["sizes"] +
        '"><b>' +
        category_items[i]["title"] +
        '</b><br><img src="' +
        category_items[i]["thumbnail"] +
        '" height="64" width="64" alt="shoe thumbnail"><p>$' +
        category_items[i]["price"] +
        "</p></div>";
      $("#display-items-div").append(item_content); //Display in grid
    }

    //Test filter for speeds//
    if (show_sizes_array.some((v) => category_items[i]["brand"].includes(v))) {
      let item_content =
        '<div class="product-card" data-available-speed="' +
        category_items[i]["sizes"] +
        '"><b>' +
        category_items[i]["title"] +
        '</b><br><img src="' +
        category_items[i]["thumbnail"] +
        '" height="64" width="64" alt="shoe thumbnail"><p>$' +
        category_items[i]["price"] +
        "</p></div>";
      $("#display-items-div").append(item_content); //Display in grid
    }
    //end test filter//

  }
}
.product-page-wrapper {
  display: flex;
  padding: 20px;
}

.filter-wrapper {
  border: 1px solid #eee;
  width: 20%;
}

.items-wrapper {
  width: 80%
}

.items {
  padding: 20px;
}

.product-card {
  width: 23%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="product-page-wrapper">
  <!--Product Filter-->
  <div class="filter-wrapper">
    <h2>Filter by</h2>
    <hr>
    <h3>Size:</h3>
    <form id="size-form">
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size1">
        <label class="form-check-label" for="size-check">Size 1</label>
      </div>
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size2">
        <label class="form-check-label" for="size-check">Size 2</label>
      </div>
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size3r">
        <label class="form-check-label" for="size-check">Size 3</label>
      </div>
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="size-check" data-size="Size4">
        <label class="form-check-label" for="size-check">Size 4</label>
      </div>
    </form>

    <h3>Brand:</h3>
    <form id="brand-form">
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Other">
        <label class="form-check-label" for="size-check">Other</label>
      </div>
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Nike">
        <label class="form-check-label" for="size-check">Nike</label>
      </div>
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Adidas">
        <label class="form-check-label" for="size-check">Adidas</label>
      </div>
      <div class="form-check">
        <input class="form-check-input size-filter-check" type="checkbox" value="" id="brand-check" data-size="Sketchers">
        <label class="form-check-label" for="size-check">Sketchers</label>
      </div>

    </form>
  </div>

  <!--Display Items-->
  <div class="items-wrapper">
    <div class="items" id="display-items-div"></div>
  </div>

</div>

I'm still rather new to JS, so I'm pleased that I've come as far as I have. Any help is appreciated, or if I'm using bad practices, please correct me now.




Aucun commentaire:

Enregistrer un commentaire