Hi all. I am working on a very basic site and have been seeking a way to filter posts based on user input. Currently I am generating a list of tags for all of my posts via this code:
<div>
{{ range .Site.Taxonomies.tags }}
<button><a href="{{ .Page.Permalink }}">{{
.Page.Title
}}</a><sup> {{ .Count }}</sup></button>
{{ end }}
</div>
Now, I want a user to be able to click the button and dynamically filter the posts they want to see. Presently, I’m just linking to the list page that contains the posts with that tag but rather I want to change the visible posts based on user selection and not link to another list page. This is a pretty basic feature on many sites that allow user select but I cannot for the life of me figure it out in hugo.
Can anyone give me guidance on 1) if this is possible 2) if so, a way to get started on it?
Your html is invalid. You can’t have a link inside a button!
Buttons do things, links go somewhere; decide what you want.
This is nothing to do with Hugo. If you don’'t want a user to go to another page, use a button. Then you’ll need Javascript to show/hide results, again not a Hugo thing. This is functionality that you will need to implement yourself.
In case anyone ends up on this thread looking for the same functionality, here is the solution I ended up with based on the examples provided by @iaeiou
First I have a div that generates a button for each tag in any of my posts
<div id="tag-buttons">
<button>All</button>
{{ range .Site.Taxonomies.tags }}
<button>{{ .Page.Title }}</button>
{{ end }}
</div>
You need to display those posts somehow, in my case I’m generating a grid to place the posts in with this code (note, I’m using tailwind css so the grid is generated with the classes):
Finally you need to implement some javascript to hide and show your posts based on what button was clicked. I did so in an inline script tag:
<script>
// Wait for the page to load
window.addEventListener("DOMContentLoaded", function () {
// Get all the buttons and posts
const buttons = document.querySelectorAll("#tag-buttons button");
const posts = document.querySelectorAll(".post");
// Add click event listener to each button
buttons.forEach(function (button) {
button.addEventListener("click", function () {
// Remove 'active' class from all buttons
buttons.forEach(function (btn) {
btn.classList.remove("bg-blue-500", "text-white");
btn.classList.add("bg-gray-200", "text-gray-700");
});
// Add 'active' class to the clicked button
button.classList.remove("bg-gray-200", "text-gray-700");
button.classList.add("bg-blue-500", "text-white");
if (button.textContent === "All") {
// Show all posts if 'All' button is clicked
posts.forEach(function (post) {
post.style.display = "block";
});
} else {
const tag = button.textContent.trim();
// Hide all posts
posts.forEach(function (post) {
post.style.display = "none";
});
// Show only posts with the selected tag
const filteredPosts = document.querySelectorAll("." + tag);
filteredPosts.forEach(function (post) {
post.style.display = "block";
});
}
});
});
});
</script>