Marcel
Marcel

Reputation: 27

Convert Jquery code to filter list by checkbox into Vanilla JS

i have a code(found here) that filter a list by data-attribute element, and i need convert from jquery to js

$('.checkbox').change(function() {

  $('li.list').each(function(i, item) {
    var color = $(this).data('color');
    var visible = $('input.checkbox[data-color="' + color + '"]:checked').length > 0;
    visible ? $(this).show() : $(this).hide();
  });


  if ($('input.checkbox:checked').length === 0) {
    $('li.list').show();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="checkbox" data-color="blue"> Blue
<input type="checkbox" class="checkbox" data-color="green"> Green
<input type="checkbox" class="checkbox" data-color="red"> Red

<ul>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="green">Green</li>
  <li class="list" data-color="red">Red</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="green">Green</li>
</ul>

I tried to use a forEach loop but i don't know how to get the same result

const checkbox = document.querySelectorAll(".checkbox");
const list = document.querySelectorAll(".list");


 checkbox.forEach((item)=> {
  item.addEventListener('change', () => {

    var color = item.getAttribute('data-color');

    //Do another loop on list 




  })

 })

how to do that?

Upvotes: 1

Views: 525

Answers (2)

connexo
connexo

Reputation: 56754

I'd like to present a little more concise version of the accepted answer.

I've added labels and a wrapping element around the checkboxes that serves as an anchor point to apply delegate listening to (so only listener needed in this code).

colorfilter.addEventListener('change', (e) => {
  let selectedColors = [...colorfilter.querySelectorAll(':checked')].map(x => x.dataset.color);
  for (const listItem of document.querySelectorAll('.list')) {
    listItem.classList[selectedColors.includes(listItem.dataset.color) 
      ? 'add' 
      : 'remove']('show');
  }
})
.list {
  display: none;
}

.show {
  display: list-item;
}
<div id="colorfilter">
  <label><input type="checkbox" class="checkbox" data-color="blue"> Blue</label>
  <label><input type="checkbox" class="checkbox" data-color="green"> Green</label>
  <label><input type="checkbox" class="checkbox" data-color="red"> Red</label>
</div>

<ul>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="green">Green</li>
  <li class="list" data-color="red">Red</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="green">Green</li>
</ul>

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 370729

One option is to construct a standalone function that checks the :checked checkboxes for the colors to show, then iterates through the .lists and sets the display style appropriately. For every checkbox, add a change listener pointing to that function:

const checkbox = document.querySelectorAll(".checkbox");
const list = document.querySelectorAll(".list");

const examineList = () => {
  const checkedColors = [...document.querySelectorAll('.checkbox:checked')]
    .filter(input => input.checked)
    .map(input => input.dataset.color);
  const showColor = checkedColors.length
    ? color => checkedColors.includes(color)
    : color => true; // if no colors are selected, always show every <li>
  document.querySelectorAll('.list').forEach((li) => {
    li.style.display = showColor(li.dataset.color) ? 'list-item' : 'none';
  });
};

checkbox.forEach((item) => {
  item.addEventListener('change', examineList);
});
<label><input type="checkbox" class="checkbox" data-color="blue"> Blue</label>
<label><input type="checkbox" class="checkbox" data-color="green"> Green</label>
<label><input type="checkbox" class="checkbox" data-color="red"> Red</label>

<ul>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="green">Green</li>
  <li class="list" data-color="red">Red</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="blue">Blue</li>
  <li class="list" data-color="green">Green</li>
</ul>

Upvotes: 1

Related Questions