diff --git a/myproject/products/static/products/js/batch-selection.js b/myproject/products/static/products/js/batch-selection.js index 1ebf047..d24316a 100644 --- a/myproject/products/static/products/js/batch-selection.js +++ b/myproject/products/static/products/js/batch-selection.js @@ -101,6 +101,11 @@ * Update the "Select All" checkbox state based on individual checkboxes */ function updateSelectAllCheckbox() { + // Проверяем наличие чекбокса перед работой с ним + if (!selectAllCheckbox) { + return; + } + const itemCheckboxes = document.querySelectorAll('.item-checkbox'); const totalCheckboxes = itemCheckboxes.length; const checkedCheckboxes = document.querySelectorAll('.item-checkbox:checked').length; diff --git a/myproject/products/static/products/js/bulk-category-modal.js b/myproject/products/static/products/js/bulk-category-modal.js index d5f753b..d410644 100644 --- a/myproject/products/static/products/js/bulk-category-modal.js +++ b/myproject/products/static/products/js/bulk-category-modal.js @@ -15,13 +15,13 @@ const modal = document.getElementById('bulkCategoryModal'); const bulkCategoryAction = document.getElementById('bulk-category-action'); const applyBtn = document.getElementById('applyBulkCategoriesBtn'); - const clearAllBtn = document.getElementById('clearAllCategoriesBtn'); const categoryListContainer = document.getElementById('categoryListContainer'); const categorySearchInput = document.getElementById('categorySearchInput'); - const clearExistingToggle = document.getElementById('clearExistingCategoriesToggle'); const errorAlert = document.getElementById('bulkCategoryError'); const selectedItemsCountSpan = document.getElementById('selectedItemsCount'); const selectedItemsBreakdownSpan = document.getElementById('selectedItemsBreakdown'); + const modeHint = document.getElementById('bulkCategoryModeHint'); + const categoryListSection = document.getElementById('bulkCategoryListSection'); /** * Initialize the bulk category modal functionality @@ -38,12 +38,27 @@ // Event listeners bulkCategoryAction.addEventListener('click', handleOpenModal); applyBtn.addEventListener('click', handleApply); - clearAllBtn.addEventListener('click', handleClearAll); - categorySearchInput.addEventListener('input', handleCategorySearch); + if (categorySearchInput) { + categorySearchInput.addEventListener('input', handleCategorySearch); + } + + // Listen for mode changes + const modeRadios = document.querySelectorAll('input[name="bulkCategoryMode"]'); + modeRadios.forEach(radio => { + radio.addEventListener('change', () => { + hideError(); + updateModeUI(); + updateApplyButtonState(); + }); + }); // Listen for modal close to reset state modal.addEventListener('hidden.bs.modal', resetModalState); + // Initial UI state + updateModeUI(); + updateApplyButtonState(); + console.log('Bulk category modal initialized'); } @@ -120,6 +135,43 @@ selectedItemsBreakdownSpan.textContent = breakdown; } + /** + * Get current mode: add | replace | clear + */ + function getCurrentMode() { + const checked = document.querySelector('input[name="bulkCategoryMode"]:checked'); + return checked ? checked.value : 'add'; + } + + /** + * Update UI depending on selected mode + */ + function updateModeUI() { + const mode = getCurrentMode(); + + if (categorySearchInput) { + categorySearchInput.disabled = (mode === 'clear'); + } + + if (categoryListSection) { + if (mode === 'clear') { + categoryListSection.classList.add('opacity-50'); + } else { + categoryListSection.classList.remove('opacity-50'); + } + } + + if (modeHint) { + if (mode === 'add') { + modeHint.textContent = 'Добавленные категории будут присоединены к уже существующим.'; + } else if (mode === 'replace') { + modeHint.textContent = 'Существующие категории будут полностью заменены выбранными ниже.'; + } else if (mode === 'clear') { + modeHint.textContent = 'Все категории будут удалены. Список ниже будет проигнорирован.'; + } + } + } + /** * Load categories from server */ @@ -265,8 +317,15 @@ * Update apply button state */ function updateApplyButtonState() { - // Кнопка Применить активна только если выбрана хотя бы одна категория - applyBtn.disabled = selectedCategoryIds.size === 0; + const mode = getCurrentMode(); + + if (mode === 'clear') { + // В режиме очистки категории не требуются + applyBtn.disabled = false; + } else { + // Для add/replace нужна хотя бы одна выбранная категория + applyBtn.disabled = selectedCategoryIds.size === 0; + } } /** diff --git a/myproject/products/templates/products/products_list.html b/myproject/products/templates/products/products_list.html index aadd977..3d88b79 100644 --- a/myproject/products/templates/products/products_list.html +++ b/myproject/products/templates/products/products_list.html @@ -415,22 +415,41 @@ - +