I have a blog that outputs posts from multiple categories and want to be able to filter them based on category while staying on the page. For instance, if I click Tag 2 I want all posts to show up with Tag 2. Since there isn't an easy way to do this in the CMS I figured I would add another field to the post that displays the category, and use jQuery to see if there's a match and return the results.
- By default I'd like to display all posts
- After clicking a "filter" (from tr-nav) I'd like to only show posts from that category (from tr-category).
- If tr-title and tr-category are the same then only those posts should show
Does anyone know of an easy way to handle this?
I've found the following snippet which auto sorts based on category, but I want this to happen on click. I've tried messing with this but can't get anything to work.
Any help would be greatly appreciated!
$(function() {
for (var i = 0; i < $('.tr-wrap .tr-category').length; i ) {
var name = $('.tr-wrap .tr-category').eq( i );
for (var d = 0; d < $('.tr-title').length; d ) {
var title = $('.tr-title').eq( d );
if ( title.text() == name.text() ) {
var parent = name.closest('.tr-item');
var titleContain = title.closest('.tr-contain').find('.tr-list');
parent.clone(true, true).appendTo( titleContain );
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div >
<a href="#"><div >All</div></a>
<a href="#"><div >Tag 1</div></a>
<a href="#"><div >Tag 2</div></a>
<a href="#"><div >Tag 3</div></a>
</div>
<div >
<div >
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 2</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 1</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 2</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
</div>
</div>
CodePudding user response:
You can filter your posts by adding the tag name
as a class to each post. I hope this will help you
function filterPosts(tag) {
const postsList = document.querySelectorAll('.tr-item');
if (tag === 'all') {
postsList.forEach(post => {
post.classList.remove('hidden');
});
} else {
postsList.forEach(post => {
if (post.classList.contains(tag)) {
post.classList.remove('hidden');
} else {
post.classList.add('hidden');
}
});
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.hidden {
display: none;
}
</style>
</head>
<body>
<div >
<a href="#" onclick="filterPosts('all')">
<div >All</div>
</a>
<a href="#" onclick="filterPosts('tag-1')">
<div >Tag 1</div>
</a>
<a href="#" onclick="filterPosts('tag-2')">
<div >Tag 2</div>
</a>
<a href="#" onclick="filterPosts('tag-3')">
<div >Tag 3</div>
</a>
</div>
<div >
<div >
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 2</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 1</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 2</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
</div>
</div>
</body>
</html>
CodePudding user response:
Also, you can use this JavaScript code without adding any classes, but you should make sure the text in tr-category
elements is the same as the text in tr-title
elements.
function filterPosts(tag) {
const postsList = document.querySelectorAll('.tr-item');
let tagName = tag.children[0].innerText;
tagName = tagName.toLowerCase();
if (tagName == 'all') {
for (let i = 0; i < postsList.length; i ) {
let postTag = postsList[i].children[1].innerText;
postTag = postTag.toLowerCase();
for (let i = 0; i < postsList.length; i ) {
postsList[i].classList.remove('hidden');
}
}
} else {
for (let i = 0; i < postsList.length; i ) {
let postTag = postsList[i].children[1].innerText;
postTag = postTag.toLowerCase();
if (postTag === tagName) {
postsList[i].classList.remove('hidden');
} else {
postsList[i].classList.add('hidden');
}
}
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.hidden {
display: none;
}
</style>
</head>
<body>
<div >
<a href="#" onclick="filterPosts(this)">
<div >All</div>
</a>
<a href="#" onclick="filterPosts(this)">
<div >Tag 1</div>
</a>
<a href="#" onclick="filterPosts(this)">
<div >Tag 2</div>
</a>
<a href="#" onclick="filterPosts(this)">
<div >Tag 3</div>
</a>
</div>
<div >
<div >
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3 </div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 2</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 1</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 2</div>
</div>
<div >
<h5>Lorem ipsum dolor sit amet, consectetur</h5>
<div >Tag 3</div>
</div>
</div>
</div>
</body>
</html>