(I) Category above Product (Store) – Filter Plugin

<!-- tuanphan category above product name on store page -->
<script>
window.addEventListener('DOMContentLoaded', () => {
    const config = { isLink: true };
    
    const bodyClasses = document.body.classList;
    if (!bodyClasses.contains('collection-type-products') || bodyClasses.contains('view-item')) return;
    
    const fetchJSON = async (path) => {
        const queryParams = '?format=json&' + Date.now();
        const response = await fetch(path + queryParams);
        return await response.json();
    };
    
    const addCategoriesToProducts = async () => {
        const visibleProducts = document.querySelectorAll('.product-list-item:not([style*="display: none"]) .product-list-item-link');
        
        const fetchPromises = Array.from(visibleProducts).map(productLink => {
            const productItem = productLink.closest('.product-list-item');
            
            if (!productItem || productItem.querySelector('.categories-product-labels')) return null;
            
            const itemUrl = productLink.getAttribute('href');
            if (!itemUrl) return null;
            
            return fetchJSON(itemUrl)
                .then(productJsonData => ({ productItem, productJsonData }))
                .catch(error => {
                    console.log('Error:', error);
                    return null;
                });
        });
        
        const results = await Promise.all(fetchPromises.filter(p => p !== null));
        
        results.forEach(result => {
            if (!result || !result.productJsonData) return;
            
            const { productItem, productJsonData } = result;
            
            if (!productJsonData.item?.categoryIds?.length) return;
            if (!productJsonData.nestedCategories?.itemCategories) return;
            
            const productTitle = productItem.querySelector('.product-list-item-title');
            if (!productTitle) return;
            
            if (productItem.querySelector('.categories-product-labels')) return;
            
            const categoriesContainer = document.createElement('div');
            categoriesContainer.className = 'categories-product-labels';
            
            productJsonData.nestedCategories.itemCategories.forEach(category => {
                const categoryElement = document.createElement(config.isLink ? 'a' : 'div');
                categoryElement.className = 'category-label';
                categoryElement.setAttribute('data-category-name', category.displayName);
                categoryElement.setAttribute('data-category-slug', category.shortSlug);
                categoryElement.textContent = category.displayName;
                
                if (config.isLink) {
                    categoryElement.href = category.fullUrl;
                }
                
                categoriesContainer.appendChild(categoryElement);
            });
            
            productTitle.insertAdjacentElement('beforebegin', categoriesContainer);
        });
        
        console.log('Categories added to', results.length, 'products');
    };
    
    addCategoriesToProducts();
    
    document.addEventListener('custom-filter:afterFilter', function(event) {
        console.log('afterFilter triggered!');
        setTimeout(() => {
            addCategoriesToProducts();
        }, 200);
    });
});
</script>

 

Buy me a coffee