You can send your questions to my email to get faster answer in 24 hours (free).
Buy me a coffee

23-07-2025 (08)

<!-- created on 23-07-2025 -->
<script>
document.addEventListener('DOMContentLoaded', function() {
  
  setTimeout(function() {
    initCategoryFilter();
  }, 1000);
  
  function initCategoryFilter() {
    const categoryLinks = document.querySelectorAll('.nested-category-breadcrumb-link');
    
    categoryLinks.forEach(link => {
      link.addEventListener('click', function(e) {
        e.preventDefault();
        
        const categoryName = this.textContent.trim();
        const categoryUrl = this.getAttribute('href');
        
        setActiveCategory(this);
        
        if (categoryName === 'All') {
          showAllProducts();
        } else {
          filterProductsByCategory(categoryUrl, categoryName);
        }
        
        updateURL(categoryUrl);
      });
    });
  }
  
  function setActiveCategory(clickedLink) {
    document.querySelectorAll('.nested-category-breadcrumb-link').forEach(link => {
      link.classList.remove('bold');
    });
    
    clickedLink.classList.add('bold');
  }
  
  function showAllProducts() {
    const productItems = document.querySelectorAll('.product-list-item');
    
    productItems.forEach((item, index) => {
      setTimeout(() => {
        item.style.display = 'block';
        item.style.animation = 'fadeInProduct 0.3s ease-out';
      }, index * 50);
    });
    
    updateProductCount();
  }
  
  async function filterProductsByCategory(categoryUrl, categoryName) {
    showLoader();
    
    try {
      const response = await fetch(categoryUrl + '?format=json');
      const data = await response.json();
      
      const categoryProductIds = data.items ? data.items.map(item => {
        const urlParts = item.fullUrl.split('/');
        return urlParts[urlParts.length - 1];
      }) : [];
      
      const allProductItems = document.querySelectorAll('.product-list-item');
      
      allProductItems.forEach((item, index) => {
        const productLink = item.querySelector('.product-list-item-link');
        const productUrl = productLink.getAttribute('href');
        const productId = productUrl.split('/').pop();
        
        const shouldShow = categoryProductIds.some(id => 
          productUrl.includes(id) || 
          productId.includes(id) ||
          id.includes(productId)
        );
        
        setTimeout(() => {
          if (shouldShow) {
            item.style.display = 'block';
            item.style.animation = 'fadeInProduct 0.3s ease-out';
          } else {
            item.style.animation = 'fadeOutProduct 0.2s ease-out';
            setTimeout(() => {
              item.style.display = 'none';
            }, 200);
          }
        }, index * 30);
      });
      
      setTimeout(() => {
        updateProductCount();
        hideLoader();
      }, 500);
      
    } catch (error) {
      console.log('Error filtering products:', error);
      hideLoader();
    }
  }
  
  function updateProductCount() {
    const visibleProducts = document.querySelectorAll('.product-list-item[style*="display: block"], .product-list-item:not([style*="display: none"])').length;
    
    let countElement = document.querySelector('.product-count');
    if (!countElement) {
      countElement = document.createElement('div');
      countElement.className = 'product-count';
      
      const container = document.querySelector('.product-list-container');
      if (container) {
        container.parentNode.insertBefore(countElement, container);
      }
    }
    
    countElement.textContent = `${visibleProducts} products`;
  }
  
  function updateURL(categoryUrl) {
    history.pushState(null, '', categoryUrl);
  }
  
  function showLoader() {
    let loader = document.querySelector('.category-filter-loader');
    if (!loader) {
      loader = document.createElement('div');
      loader.className = 'category-filter-loader';
      loader.innerHTML = '<div class="loader-spinner"></div>';
      
      const container = document.querySelector('.product-list-container');
      if (container) {
        container.appendChild(loader);
      }
    }
    
    loader.style.display = 'flex';
  }
  
  function hideLoader() {
    const loader = document.querySelector('.category-filter-loader');
    if (loader) {
      loader.style.display = 'none';
    }
  }
  
  window.addEventListener('popstate', function() {
    location.reload();
  });
  
});
</script>
<style>
@keyframes fadeInProduct {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes fadeOutProduct {
  from {
    opacity: 1;
    transform: translateY(0);
  }
  to {
    opacity: 0;
    transform: translateY(-20px);
  }
}
.nested-category-breadcrumb-link {
  cursor: pointer !important;
  transition: all 0.2s ease !important;
}
.nested-category-breadcrumb-link:hover {
  opacity: 0.7 !important;
}
.nested-category-breadcrumb-link.bold {
  font-weight: bold !important;
  color: #333 !important;
}
.product-count {
  text-align: center !important;
  margin: 20px 0 !important;
  color: #666 !important;
  font-size: 14px !important;
  font-weight: 500 !important;
}
.category-filter-loader {
  position: absolute !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  z-index: 100 !important;
  display: none !important;
  align-items: center !important;
  justify-content: center !important;
  background: rgba(255, 255, 255, 0.9) !important;
  width: 100% !important;
  height: 100% !important;
}
.loader-spinner {
  width: 30px !important;
  height: 30px !important;
  border: 3px solid #f3f3f3 !important;
  border-top: 3px solid #333 !important;
  border-radius: 50% !important;
  animation: spin 1s linear infinite !important;
}
@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
.product-list-container {
  position: relative !important;
}
@media (max-width: 768px) {
  .product-count {
    font-size: 12px !important;
    margin: 15px 0 !important;
  }
  
  .loader-spinner {
    width: 25px !important;
    height: 25px !important;
  }
}
</style>