user1486133 user1486133 - 1 month ago 14
jQuery Question

Hiding items based on data attribute, minimum and maximum values

I'm creating a basic filter to remove some items from a list. There are only 12 items so IMO not enough to bother with lazy loading or rendering. Just using jQuery to hide the items.

The items are filtered out using numbers from a

select
dropdown, one for
minValue
and one for
maxValue
. The value relating to each div is stored in
data-bedrooms
on the div.

HTML example

<div class="property-item" data-bedrooms="7">7 bedrooms</div>


I am triggering my logic on
.change
of one of my dropdowns. I am then using
filter()
to return items which match (or don't match) the conditions of the
minValue
and
maxValue
and fading them in/out.

Here is a full code pen where you can see everything in action: http://codepen.io/anon/pen/ALdOLW

What I am finding is that the first selection works (e.g, select min
4
and you will remove everything below
4
) but try to select a max value and things start misbehaving.

When you select the second value, it brings back all the previous results. I need to bind both the selections together.

Where am I going wrong?

I need to combine the
fadeIn
and
fadeOut
to check both
maxValue
and
minValue


return $(this).attr('data-bedrooms') < minValue || > maxValue;


but I'm aware the above is incorrect syntax

Answer

OP it seems like your code was generally working, my guess is that you were running into some race conditions because your code was animating multiple times. I've forked your codepen, and reorganized the code so you perform two operations instead of 4. I've also hoisted your filter function into a separate function. IMO By making this changes you improve readability, and maintainability of the code over time.

// Translating 'min' and 'max' to numbers that we can compare against
// This makes it easier to perform the <= >= checks
if (minValue === 'min-default') {
  minValue = 0;
}
if (maxValue === 'max-default') {
  maxValue = 1000; // This should probably find the highest value from the available options
}

// Moved this out to its own function that compares the entire range at once
function filterBedroomsRange(index, item) {
    var bedrooms = $(item).attr('data-bedrooms');

    // Validate against the selected range together to avoid double filter/double animation issues
    // The number of bedrooms must be greater than or equal to the min value, and less than, or equal to the maxValue
    return bedrooms >= minValue && <= maxValue;
}


// Hide items that don't match the range
properties.find('.property-item').filter(function(index, item) {
    // Return the negative of `filterBedroomsRange` to find items to hide
    return !filterBedroomsRange(index, item);
}).fadeOut('fast');


// Show items that do match the range
properties.find('.property-item').filter(filterBedroomsRange).fadeIn('fast');

Codepen: http://codepen.io/anon/pen/VKdPNB