Reputation: 392
I have a list of content that I'd like to filter based on their class names. When someone clicks on one of the two menus, the content with that menu item's class should show. Some content items have more than one class and users can filter from both menus.
The problem with my code is that each menu click doesn't reset the list of items. It filters on the items left over after the first menu click.
Thanks in advance for your help.
$(document).ready(function () {
$('.filter li a').click(function () {
var partnerResources = $(this).attr('class');
$('.filter li').removeClass('active');
$(this).parent().addClass('active');
if (partnerResources == 'all') {
$('#list-area').children('div').fadeIn(500);
} else {
$('#list-area').children('div:not(.' + partnerResources + ')').fadeOut(500);
$('#list-area').children('div:has(.' + partnerResources + ')').fadeIn(500);
}
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<ul class="filter">
<li class="active"><a href="#" class="all">All</a>
</li>
<li><a href="#" class="welcome-kit">Welcome Kit</a>
</li>
<li><a href="#" class="forms">Forms</a>
</li>
</ul>
<hr />
<ul class="filter">
<li class="active"><a href="#" class="all">All</a>
</li>
<li><a href="#" class="automotive">Automotive</a>
</li>
<li><a href="#" class="retail">Retail</a>
</li>
</ul>
<hr />
<div id="list-area">
<div class="welcome-kit retail">welcome retail</div>
<div class="forms">forms</div>
<div class="forms retail">forms retail</div>
<div class="welcome-kit automotive">welcome autmotive</div>
<div class="forms">forms</div>
<div class="welcome-kit forms">welcome forms</div>
<div class="welcome-kit automotive">welcome automotive</div>
<div class="welcome-kit">welcome</div>
<div class="welcome-kit forms">welcome forms</div>
<div class="forms">forms</div>
</div>
Upvotes: 0
Views: 1807
Reputation: 4848
You made a simple mistake: your div:has
class selector isn't selecting the elements you want to show!
Simply replace that line with a plain-jane class selector:
$('#list-area').children('div.' + partnerResources).fadeIn(500);
Working JSFiddle: http://jsfiddle.net/1t1b7gzf/
:has
selects elements that have children matching the given selector. It doesn't check the current matched element. Reference the .has
documentation:
:has()
selectorSelects elements which contain at least one element that matches the specified selector.
The expression
$( "div:has(p)" )
matches a<div>
if a<p>
exists anywhere among its descendants, not just as a direct child.
Upvotes: 1
Reputation: 15715
you can do like this, http://jsfiddle.net/vwwyqpvc/,
$(document).ready(function () {
$('.filter li a').click(function () {
var partnerResources = $(this).attr('class');
$('.filter li').removeClass('active');
$(this).parent().addClass('active');
if (partnerResources == 'all') {
$('#list-area').children('div').fadeIn(500);
} else {
$('#list-area').children('div').fadeIn(500).end().children('div:not(.' + partnerResources + ')').fadeOut(500).end().children('div:has(.' + partnerResources + ')').fadeIn(500);
}
return false;
});
});
Add the elements again to the div, and then filter out, on each click of menu
Upvotes: 1
Reputation: 36703
Do it with .hasClass
$(document).ready(function () {
$('.filter li a').click(function () {
var partnerResources = $(this).hasClass('all');
$('.filter li').removeClass('active');
$(this).parent().addClass('active');
if (partnerResources) {
$('#list-area').children('div').fadeIn(500);
} else {
$('#list-area').children('div:not(.' + partnerResources + ')').fadeOut(500);
$('#list-area').children('div:has(.' + partnerResources + ')').fadeIn(500);
}
return false;
});
});
Upvotes: 1