Giorgia Sambrotta Giorgia Sambrotta - 2 months ago 13
Javascript Question

filter list with nested loop: if first loop finish successfully, do something

It might be a silly question but i really cannot wrap my head around it.
I'm implementing a filter, which is made by select input and it should select divs with given value saved in data-* attribute.

I do so with a nested loop: I first loop through all divs and then i list through all given values coming from select inputs.
If even one value from the select doesn't mach, i move on to the next div.
If it does, i move on to the next value of the select inputs values's array.
I almost get there, i miss the last little step which is:
When i'm done looping all the values from the select and they all match with my div's data attr, then i should show this div.
I cannot get where i should put the code to show this div!

Here my (simplify) code. Please no comment about how i could just use javascript, i know it could work perfectly too but i cannot with this project so it has to be in jQuery.

html:

<select class="filter">
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
</select>

<select class="filter">
<option value="jan">Jan</option>
<option value="feb">feb</option>
<option value="march">march</option>
</select>

<div class="list-item" data-day="01" data-month="jan">01 jan </div>
<div class="list-item" data-day="02" data-month="feb">02 feb </div>
<div class="list-item" data-day="03" data-month="jan">03 jan </div>
<div class="list-item" data-day="02" data-month="march">02 march </div>
<div class="list-item" data-day="03" data-month="jan"> 03 jan</div>


jQuery:

function combinedFilters() {
var valuesArray = [];
var items = jQuery('.list-item');

jQuery('select').each(function() {
valuesArray.push(jQuery(this).val());
});

console.log(valuesArray);

jQuery(items).each(function(i, item) {

if (jQuery(this).data('month') && jQuery(this).data('day') ) {
var month = jQuery(this).data('month');
var day = jQuery(this).data('day').toString();

jQuery.each(valuesArray, function(i, value) {
if (value != null) {
console.log(value);

if (value == month || value == day) {
return true; // keep looping into values Array
} else {
return false; //go out of the Values loop to the next div
}
}
//jQuery(this).show();
console.log('show the div');
});
}

});
}


function trigger() {
jQuery('select').change(function() {

jQuery('.list-item').hide();
combinedFilters();

});
}

jQuery('.list-item').hide();
trigger();


And here a jsFiddle: https://jsfiddle.net/n2x5yc9g/1/

Any suggestion with explanation is really appreciated!

UPDATE:

Based on the solution proposed by @Michal Młoźniak i fix my filters, if anyone is interested in the final result here is the whole code:
https://codepen.io/designbygio/pen/NRxvWo

Answer

Will that work for you or do you really need to have nested loop?

function combinedFilters() {
  var valuesArray = [];
  var items = jQuery('.list-item');

  jQuery('select').each(function() {
    valuesArray.push(jQuery(this).val());
  });

  items.each(function(i, item) {
    if (jQuery(item).data('month') === valuesArray[1] && jQuery(item).data('day') === valuesArray[0] ) {
      jQuery(item).show();
    }
  });
}

function trigger() {
  jQuery('select').change(function() {

  jQuery('.list-item').hide();
    combinedFilters();
  });
}

jQuery(function() {
  jQuery('.list-item').hide();
  trigger();
});