diff --git a/myproject/products/static/products/js/catalog.js b/myproject/products/static/products/js/catalog.js index 122f20c..ad05756 100644 --- a/myproject/products/static/products/js/catalog.js +++ b/myproject/products/static/products/js/catalog.js @@ -55,6 +55,108 @@ document.addEventListener('DOMContentLoaded', function() { }); } + // ======================================== + // Фильтрация по категории + // ======================================== + let selectedCategoryId = null; + + // Добавляем обработчик клика на категорию для фильтрации + document.querySelectorAll('.category-header').forEach(header => { + header.addEventListener('click', function(e) { + // Игнорируем клики на кнопки управления и toggle + if (e.target.classList.contains('category-rename-btn') || + e.target.classList.contains('category-add-child-btn') || + e.target.classList.contains('category-name-input') || + e.target.classList.contains('category-toggle') || + e.target.closest('.category-toggle')) { + return; + } + + const categoryNode = this.closest('.category-node'); + const categoryId = categoryNode.dataset.categoryId; + + // Toggle selection + if (selectedCategoryId === categoryId) { + // Deselect - show all + selectedCategoryId = null; + document.querySelectorAll('.category-header').forEach(h => h.classList.remove('active')); + } else { + // Select this category + selectedCategoryId = categoryId; + document.querySelectorAll('.category-header').forEach(h => h.classList.remove('active')); + this.classList.add('active'); + } + + filterProducts(); + }); + }); + + // Проверяет, находится ли категория в дереве выбранной категории + function isInCategoryTree(categoryId, rootCategoryId) { + if (categoryId === rootCategoryId) return true; + + // Находим узел категории + const categoryNode = document.querySelector(`.category-node[data-category-id="${categoryId}"]`); + if (!categoryNode) return false; + + // Проверяем всех предков + let currentNode = categoryNode; + while (currentNode) { + const nodeId = currentNode.dataset.categoryId; + if (nodeId === rootCategoryId) return true; + + // Переходим к родительскому .category-node + const parentContainer = currentNode.parentElement.closest('.category-children'); + if (parentContainer) { + currentNode = parentContainer.closest('.category-node'); + } else { + break; + } + } + + return false; + } + + // Единая функция фильтрации товаров + function filterProducts() { + const catalogItems = document.querySelectorAll('.catalog-item'); + + catalogItems.forEach(item => { + let shouldShow = true; + + // Применяем фильтр по категории + if (selectedCategoryId) { + const itemCategories = item.dataset.categoryIds ? + item.dataset.categoryIds.split(',').filter(id => id.trim()) : []; + + // Проверяем, принадлежит ли товар выбранной категории или её потомкам + shouldShow = itemCategories.length > 0 && itemCategories.some(catId => { + return isInCategoryTree(catId.trim(), selectedCategoryId); + }); + } + + // Применяем фильтр по типу + const activeTypeBtn = document.querySelector('[data-filter].active'); + if (activeTypeBtn && shouldShow) { + const filterType = activeTypeBtn.dataset.filter; + if (filterType !== 'all' && item.dataset.type !== filterType) { + shouldShow = false; + } + } + + // Применяем поиск + const searchInput = document.getElementById('catalog-search'); + if (searchInput && shouldShow) { + const query = searchInput.value.toLowerCase(); + if (query && !item.textContent.toLowerCase().includes(query)) { + shouldShow = false; + } + } + + item.style.display = shouldShow ? '' : 'none'; + }); + } + // ======================================== // Фильтр по типу (товары/комплекты) // ======================================== @@ -67,10 +169,8 @@ document.addEventListener('DOMContentLoaded', function() { this.classList.add('active', 'btn-primary'); this.classList.remove('btn-outline-primary'); - const filter = this.dataset.filter; - document.querySelectorAll('.catalog-item').forEach(item => { - item.style.display = (filter === 'all' || item.dataset.type === filter) ? '' : 'none'; - }); + // Используем единую функцию фильтрации + filterProducts(); }); }); @@ -80,11 +180,8 @@ document.addEventListener('DOMContentLoaded', function() { const searchInput = document.getElementById('catalog-search'); if (searchInput) { searchInput.addEventListener('input', function() { - const query = this.value.toLowerCase(); - document.querySelectorAll('.catalog-item').forEach(item => { - const text = item.textContent.toLowerCase(); - item.style.display = text.includes(query) ? '' : 'none'; - }); + // Используем единую функцию фильтрации + filterProducts(); }); } diff --git a/myproject/products/templates/products/catalog.html b/myproject/products/templates/products/catalog.html index 1a033ca..6f03d27 100644 --- a/myproject/products/templates/products/catalog.html +++ b/myproject/products/templates/products/catalog.html @@ -194,7 +194,7 @@
{% for item in items %} -
+
{% if item.main_photo %} @@ -217,7 +217,7 @@ {% endif %}
- {{ item.actual_price|floatformat:0 }} ₽ + {{ item.actual_price|floatformat:0 }} руб. {{ item.sku }}