mardi 19 janvier 2021

Product filter - Show results based on multiple checkboxes selected/deselected

I'm building a product filter to narrow down monitor choices based on specs such as resolution, response time, brand etc.

I have created divs for each result, the specs are classes.

Each checkbox has a value attribute. When checked this attribute is stored in the map object. This is so that when I deselect a checkbox, it is removed from the map object and visa versa.

The results of the map object are joined together with "." between and then stored in variable assignedTo, this is being logged so you can see which have been selected.

My problem now is how do I show all the divs that contain the classes stored in assignedTo?

I've tried using document.querySelectorAll and then looping through that by displaying block but there are two issues:

  1. I get an "Uncaught SyntaxError: Failed to execute 'querySelectorAll' on 'Document': '...' is not a valid selector"
  2. If I am successful in looping through and displaying each result, if I uncheck a box, how do I get that result to disappear?
$(document).ready(function() {
  $(':checkbox[type="checkbox"]').on('change', function() {
    var assignedTo = $(':checkbox[type="checkbox"]:checked').map(function() {
        return $(this).attr('value');
      })
      .get().join(".");
    console.log(assignedTo);
    document.querySelectorAll("div.result." + assignedTo).forEach(div => div.style.display = "block")
  });
});
.result {
  width: 100%;
  border: 1px solid black;
  padding: 20px;
  line-height: 20px;
  text-align: left;
  margin: 10px;
  float: left;
  font-size: 11px;
  color: #000;
  font-family: sans-serif;
  display: none;
}

div.results {
  width: 70%;
  display: inline;
  float: left;
  position: relative;
  padding-right: 10%;
}

div#filters {
  width: 20%;
  display: inline;
  float: left;
  position: relative;
}

.btn {
  background-color: #0077ce;
  color: #fff;
  font-weight: bold;
  border-radius: 10px;
  padding: 10px;
  display: inline-block;
  position: relative;
  float: right;
}

.btn:hover {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<head>
  <title>Test</title>
</head>

<body>
  <h1>Find your monitor</h1>
  <div id="filters">
    <h3>Recommended For</h3>
    <ul class="recommended">
      <li>
        <input type="checkbox" value="home" id="filter-home" />
        <label for="filter-home">Home</label>
      </li>
      <li>
        <input type="checkbox" value="office" id="filter-office" />
        <label for="filter-office">Office</label>
      </li>
      <li>
        <input type="checkbox" value="gaming" id="filter-gaming" />
        <label for="filter-gaming">Gaming</label>
      </li>
    </ul>
    <h3>Size</h3>
    <ul class="-monitor-size">
      <li>
        <input type="checkbox" value="24inch" id="filter-24inch" />
        <label for="filter-24inch">24inch</label>
      </li>
      <li>
        <input type="checkbox" value="32inch" id="filter-32inch" />
        <label for="filter-32inch">32inch</label>
      </li>
      <li>
        <input type="checkbox" value="40inch" id="filter-40inch" />
        <label for="filter-40inch">40inch</label>
      </li>
    </ul>
    <h3>Resolution</h3>
    <ul class="monitor-resolution">
      <li>
        <input type="checkbox" value="1080p" id="filter-1080p" />
        <label for="filter-1080p">1080p</label>
      </li>
      <li>
        <input type="checkbox" value="4K" id="filter-4K" />
        <label for="filter-4K">4K</label>
      </li>
      <li>
        <input type="checkbox" value="5K" id="filter-5K" />
        <label for="filter-5K">5K</label>
      </li>
    </ul>
    <h3>Response Time</h3>
    <ul class="monitor-responsetime">
      <li>
        <input type="checkbox" value="1ms" id="filter-1ms" />
        <label for="filter-1ms">1ms</label>
      </li>
      <li>
        <input type="checkbox" value="5ms" id="filter-5ms" />
        <label for="filter-5ms">5ms</label>
      </li>
      <li>
        <input type="checkbox" value="10ms" id="filter-10ms" />
        <label for="filter-10ms">10ms</label>
      </li>

    </ul>
    <h3>Brand</h3>
    <ul class="monitor-brand">
      <li>
        <input type="checkbox" value="branda" id="filter-branda" />
        <label for="filter-branda">Brand A</label>
      </li>
      <li>
        <input type="checkbox" value="brandb" id="filter-brandb" />
        <label for="filter-brandb">Brand B</label>
      </li>
      <li>
        <input type="checkbox" value="brandc" id="filter-brandc" />
        <label for="filter-brandc">Brand C</label>
      </li>
      <li>
        <input type="checkbox" class="brandd" id="filter-brandd" />
        <label for="filter-brandd">Brand D</label>
      </li>
      <li>
        <input type="checkbox" value="brande" id="filter-brande" />
        <label for="filter-brande">Brand E</label>
      </li>
      <li>
        <input type="checkbox" value="brandf" id="filter-brandf" />
        <label for="filter-brandf">Brand F</label>
      </li>

    </ul>
  </div>
  <div class="results">
    <div class="result gaming monitor 32inch 4K 5ms branda">32inch 4K Monitor - Brand A <span class="btn">Order</span></div>
    <div class="result gaming monitor 32inch 4K 5ms branda">32inch 4K Monitor - Brand A <span class="btn">Order</span></div>
    <div class="result gaming monitor 32inch 5K 1ms brandb">32inch 5K Monitor - Brand B<span class="btn">Order</span></div>
    <div class="result gaming monitor 40inch 5K 1ms brandc">40inch 5K Monitor - Brand C<span class="btn">Order</span></div>
    <div class="result office monitor 24inch 1080p 10ms brandd">24inch 1080p Monitor - Brand D<span class="btn">Order</span></div>
    <div class="result home monitor 24inch 4K 5ms brandd">24inch 4K Monitor - Brand D <span class="btn">Order</span></div>


    <div class="result gaming monitor 32inch 5K 1ms brande">32inch 5K Monitor - Brand E<span class="btn">Order</span></div>
    <div class="result gaming monitor 40inch 5K 1ms brande">40inch 5K Monitor - Brand E<span class="btn">Order</span></div>
    <div class="result office monitor 24inch 1080p 10ms brande">24inch 1080p Monitor - Brand E<span class="btn">Order</span></div>
    <div class="result home monitor 24inch 4K 5ms brandf">24inch 4K Monitor - Brand F <span class="btn">Order</span></div>
    <div class="result home monitor 24inch 4K 5ms brandf">24inch 4K Monitor - Brand F <span class="btn">Order</span></div>
  </div>
</body>

</html>



Aucun commentaire:

Enregistrer un commentaire