fix(products): improve bulk category modal and batch selection handling
- Add null check for selectAllCheckbox to avoid errors in batch-selection.js - Replace clear existing categories toggle with radio buttons for add, replace, and clear modes - Disable category search input and fade category list when 'clear' mode is selected - Update mode hint text dynamically based on selected mode with explanatory messages - Enable apply button when 'clear' mode is selected regardless of category selection - Remove clear all categories button from modal footer - Add event listeners for mode radio buttons to update UI and error states on change - Initialize mode UI and apply button state on modal setup - Bump static JS files versions for batch-selection and bulk-category-modal to 1.2 and 1.4 respectively
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
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,9 +317,16 @@
|
||||
* Update apply button state
|
||||
*/
|
||||
function updateApplyButtonState() {
|
||||
// Кнопка Применить активна только если выбрана хотя бы одна категория
|
||||
const mode = getCurrentMode();
|
||||
|
||||
if (mode === 'clear') {
|
||||
// В режиме очистки категории не требуются
|
||||
applyBtn.disabled = false;
|
||||
} else {
|
||||
// Для add/replace нужна хотя бы одна выбранная категория
|
||||
applyBtn.disabled = selectedCategoryIds.size === 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle apply button click
|
||||
|
||||
@@ -415,22 +415,41 @@
|
||||
<span id="selectedItemsBreakdown" class="ms-2 text-muted"></span>
|
||||
</div>
|
||||
|
||||
<!-- Опции применения -->
|
||||
<!-- Режим изменения категорий -->
|
||||
<div class="mb-4">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" id="clearExistingCategoriesToggle" role="switch">
|
||||
<label class="form-check-label" for="clearExistingCategoriesToggle">
|
||||
<i class="bi bi-trash"></i> Очистить существующие категории перед сохранением
|
||||
<label class="form-label fw-bold">Что сделать с категориями выбранных товаров?</label>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="bulkCategoryMode"
|
||||
id="bulkCategoryModeAdd" value="add" checked>
|
||||
<label class="form-check-label" for="bulkCategoryModeAdd">
|
||||
Добавить выбранные категории к существующим
|
||||
</label>
|
||||
<div class="form-text text-warning">
|
||||
<i class="bi bi-exclamation-triangle"></i>
|
||||
При включении все текущие категории товаров будут удалены, а затем применены только выбранные ниже
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input" type="radio" name="bulkCategoryMode"
|
||||
id="bulkCategoryModeReplace" value="replace">
|
||||
<label class="form-check-label" for="bulkCategoryModeReplace">
|
||||
Заменить существующие категории выбранными
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input" type="radio" name="bulkCategoryMode"
|
||||
id="bulkCategoryModeClear" value="clear">
|
||||
<label class="form-check-label text-danger" for="bulkCategoryModeClear">
|
||||
<strong>Удалить все категории</strong>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div id="bulkCategoryModeHint" class="form-text text-muted mt-2">
|
||||
Добавленные категории будут присоединены к уже существующим.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Выбор категорий -->
|
||||
<div class="mb-3">
|
||||
<div class="mb-3" id="bulkCategoryListSection">
|
||||
<label class="form-label fw-bold">Выберите категории:</label>
|
||||
|
||||
<!-- Поиск по категориям -->
|
||||
@@ -452,9 +471,6 @@
|
||||
<div id="bulkCategoryError" class="alert alert-danger d-none" role="alert"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-danger me-auto" id="clearAllCategoriesBtn">
|
||||
<i class="bi bi-trash3"></i> Очистить все категории
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
|
||||
<i class="bi bi-x-circle"></i> Отмена
|
||||
</button>
|
||||
@@ -469,6 +485,6 @@
|
||||
|
||||
{% block extra_js %}
|
||||
{% load static %}
|
||||
<script src="{% static 'products/js/batch-selection.js' %}?v=1.1"></script>
|
||||
<script src="{% static 'products/js/bulk-category-modal.js' %}?v=1.3"></script>
|
||||
<script src="{% static 'products/js/batch-selection.js' %}?v=1.2"></script>
|
||||
<script src="{% static 'products/js/bulk-category-modal.js' %}?v=1.4"></script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user