Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
29
rated 0 times [  32] [ 3]  / answers: 1 / hits: 5180  / 5 Years ago, thu, october 24, 2019, 12:00:00

I try to create simple filtering with JS but I have problem with multiple select fields, they are not cooperate together, and results going crazy (sometimes nothing shows). Everything is good if I use only one select, when I try to add second one, or third one results are not correct or I got blank page.



Here is my code: https://jsfiddle.net/au6jbsL5/



And here is my filter function (I have 3 functions - one for each select group)



$('select#sort-cost').change(function() {
var filter = $(this).val()
filterList(filter);
});

function filterList(value) {
var list = $(.news-list .news-item);
$(list).fadeOut(fast);
if (value == All) {
$(.news-list).find(article).each(function (i) {
$(this).delay(100).slideDown(fast);
});
} else {
$(.news-list).find(article[data-category*= + value + ]).each(function (i) {
$(this).delay(100).slideDown(fast);
});
}
}

More From » jquery

 Answers
1

There's two problems here, one that you're overwriting your function, so you think you have three when you only have one, but also that you're not filtering by all the filters at once.



What you want here is not three copy-pasted functions, but instead one function that applies all three filters each time something changes.



I also changed it to use regular expressions instead of .find(), which is what allows them to be chained together and allows for a natural behavior of 'all' instead of using a bunch of if statements.



// If any of the filters change
$('select').change(function() {
runAllFilters();
});

function runAllFilters() {
var list = $(.news-list .news-item);
$(list).fadeOut(fast);

var filtered = $(.news-list article);

// Get all filter values
var cost = $('select#sort-cost').val();
var city = $('select#sort-city').val();
var age = $('select#sort-age').val();

// Filter based on all of them
filtered = filtered.filter(function() {
return RegExp(cost).test($(this).attr(data-category)) &&
RegExp(age).test($(this).attr(data-age)) &&
RegExp(city).test($(this).attr(data-city));
});

// Show message if there are no results
filtered.length === 0
? $('.news-list').append(<p id='noresults'>No Results!</p>)
: $('#noresults').remove()

// Display Them
filtered.each(function (i) {
$(this).delay(100).slideDown(fast);
});
};


This approach also takes a lot of the repetition out of the code.



The only thing I changed in the HTML is to change the value 'All' to just '.' so that you don't need a bunch of if statements; in RegEx . matches everything so it works as-is.



<select name=sort-cost id=sort-cost>
<option value=.>All</option>
<option value=1>Bestsellers</option>
<option value=2>Sales</option>
</select>




// If any of the filters change
$('select').change(function() {
runAllFilters();
});

function runAllFilters() {
var list = $(.news-list .news-item);
$(list).fadeOut(fast);

var filtered = $(.news-list article);

// Get all filter values
var cost = $('select#sort-cost').val();
var city = $('select#sort-city').val();
var age = $('select#sort-age').val();

// Filter based on all of them
filtered = filtered.filter(function() {
return RegExp(cost).test($(this).attr(data-category)) &&
RegExp(age).test($(this).attr(data-age)) &&
RegExp(city).test($(this).attr(data-city));
});

filtered.length === 0
? $('.news-list').append(<p id='noresults'>No Results!</p>)
: $('#noresults').remove()

// Display Them
filtered.each(function (i) {
$(this).delay(100).slideDown(fast);
});
};

.news-item{
display:inline-block;
vertical-align:top;
width:20%;
text-align:center;
background: #fff;
border:1px solid #333;
float:left;
}
.sort{
display:inline-block;
margin-right:30px;
}

<script src=https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js></script>
<h1>SORT NOW</h1>

<div class=sort>
COST
<select name=sort-cost id=sort-cost>
<option value=.>All</option>
<option value=1>Bestsellers</option>
<option value=2>Sales</option>
</select>
</div>

<div class=sort>
AGE
<select name=sort-age id=sort-age>
<option value=.>All</option>
<option value=a>3+</option>
<option value=b>5+</option>
<option value=c>9+</option>
</select>
</div>

<div class=sort>
CITY
<select name=sort-city id=sort-city>
<option value=.>All</option>
<option value=ny>New York</option>
<option value=la>Los Angeles</option>
<option value=lv>Las Vegas</option>
</select>
</div>
<br><br>

<section class=news-list>
<article class=news-item data-category=1 2 data-age=a data-city=la lv ny>
<div class=thumb>
<img src=http://placehold.it/100x100>
</div>
<div class=news-txt>
<p>First one</p>
</div>
</article>

<article class=news-item data-category=1 data-age=a b data-city=ny>
<div class=thumb>
<img src=http://placehold.it/100x100>
</div>
<div class=news-txt>
<p>Second one</p>
</div>
</article>

<article class=news-item data-category=2 data-age=a b data-city=la ny>
<div class=thumb>
<img src=http://placehold.it/100x100>
</div>
<div class=news-txt>
<p>Third one</p>
</div>
</article>

<article class=news-item data-category=1 2 data-age=c data-city=la lv ny>
<div class=thumb>
<img src=http://placehold.it/100x100>
</div>
<div class=news-txt>
<p>Fifth</p>
</div>
</article>
</section>




[#5823] Wednesday, October 23, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
albert

Total Points: 652
Total Questions: 105
Total Answers: 108

Location: Pitcairn Islands
Member since Fri, Oct 15, 2021
3 Years ago
;