модерн
This commit is contained in:
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
<div class="card-body">
|
||||
<div class="row g-3 catalog-list" id="catalog-grid">
|
||||
{% for item in items %}
|
||||
<div class="col-12 catalog-item" data-type="{{ item.item_type }}">
|
||||
<div class="col-12 catalog-item" data-type="{{ item.item_type }}" data-category-ids="{% for cat in item.categories.all %}{{ cat.pk }}{% if not forloop.last %},{% endif %}{% endfor %}">
|
||||
<div class="card h-100 shadow-sm border-0">
|
||||
<div class="position-relative">
|
||||
{% if item.main_photo %}
|
||||
@@ -217,7 +217,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center mt-1">
|
||||
<span class="fw-bold text-primary small">{{ item.actual_price|floatformat:0 }} ₽</span>
|
||||
<span class="fw-bold text-primary small">{{ item.actual_price|floatformat:0 }} руб.</span>
|
||||
<small class="text-muted">{{ item.sku }}</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user