DEV Community

Rock
Rock

Posted on

How to Build a Dynamic Product Filtering System with Vanilla JavaScript

I’ve been diving into building a product recommendation engine for an e-commerce platform, and I wanted to share a practical approach I used to filter and showcase a specific category—like men’s footwear—while keeping the code clean and the user experience smooth.

The challenge was to create a dynamic filtering system that could handle multiple attributes: style (casual, formal), material (leather, canvas), and use case (work, weekend). Instead of writing complex SQL queries on the fly, I opted for a client-side JavaScript solution using data attributes.

Here’s a snippet of how I structured the HTML for each product card:

<div class="product-card" data-style="casual" data-material="canvas" data-use="weekend">
  <img src="sneaker.jpg" alt="Casual Sneaker">
  <h3>Everyday Sneaker</h3>
  <p>$49.99</p>
</div>
Enter fullscreen mode Exit fullscreen mode

Then, I created a filter function that listens to checkbox changes and hides or shows cards based on the selected criteria:

const filters = {
  style: [],
  material: [],
  use: []
};

function applyFilters() {
  document.querySelectorAll('.product-card').forEach(card => {
    const styleMatch = filters.style.length === 0 || filters.style.includes(card.dataset.style);
    const materialMatch = filters.material.length === 0 || filters.material.includes(card.dataset.material);
    const useMatch = filters.use.length === 0 || filters.use.includes(card.dataset.use);

    card.style.display = (styleMatch && materialMatch && useMatch) ? 'block' : 'none';
  });
}

document.querySelectorAll('.filter-checkbox').forEach(checkbox => {
  checkbox.addEventListener('change', function() {
    const filterType = this.dataset.filterType;
    const value = this.value;

    if (this.checked) {
      filters[filterType].push(value);
    } else {
      filters[filterType] = filters[filterType].filter(v => v !== value);
    }
    applyFilters();
  });
});
Enter fullscreen mode Exit fullscreen mode

This approach is lightweight and works perfectly for a medium-sized inventory. I applied it while building a demo for a men’s footwear collection that needed to highlight both comfort and durability—think shoes that transition from a business-casual office to a weekend outing. The filters let users quickly find leather formal shoes for a meeting or breathable sneakers for a park stroll.

One thing I learned: always add a “reset filters” button. Users appreciate being able to start fresh without refreshing the page. Also, consider lazy-loading images on filtered results to keep performance snappy.

If you’re building something similar, this pattern is easy to extend. You could add price range sliders or sort options without much overhead. It’s a solid foundation for any category-driven storefront, whether you’re selling sneakers or home decor.

Top comments (0)