Исправлена отображение полей адреса и стили формы заказа

## Основные изменения:

### 1. Исправлена логика выбора режима адреса
- Переместил функцию initAddressModeToggle() из jQuery блока в отдельную функцию
- Теперь инициализация адреса работает независимо от jQuery
- Добавлены подробные логи в консоль для отладки ([ADDRESS MODE] префикс)

### 2. Добавлены CSS классы для управления видимостью
- address-history-mode: display: none !important (по умолчанию скрыт)
- address-new-mode: display: none !important (по умолчанию скрыт)
- .visible класс переводит элементы на display: block !important
- Использование classList.add/remove вместо inline styles

### 3. Исправлены стили полей формы (OrderForm)
- Добавлена явная обработка для Select полей - получают form-select
- Поле "Статус" и другие Select теперь имеют правильные стили Bootstrap
- Разделена логика для RadioSelect, Select и остальных полей

### 4. Улучшена отладка
- Добавлены console.log сообщения на каждом этапе инициализации
- Префикс [ADDRESS MODE] помогает отличить логи системы адреса от других

## Технические детали:

- Address сервис использует метод format_address_for_display() для красивого вывода
- AJAX endpoint get_customer_address_history() загружает адреса клиента
- Три режима адреса: history (из истории), new (новый адрес), empty (без адреса)
- Режим empty выбирается по умолчанию

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-11 02:49:25 +03:00
parent 7d82d67b5f
commit ddbb4f963b
16 changed files with 956 additions and 188 deletions

View File

@@ -16,6 +16,23 @@
pointer-events: none;
}
/* Явное управление видимостью режимов адреса */
#address-history-mode {
display: none !important;
}
#address-new-mode {
display: none !important;
}
#address-history-mode.visible {
display: block !important;
}
#address-new-mode.visible {
display: block !important;
}
/* Стили для поиска клиента */
.customer-option {
padding: 5px 0;
@@ -193,17 +210,141 @@
</div>
<div class="row" id="delivery-fields">
<div class="col-md-6">
<!-- Способ указания адреса -->
<div class="col-12">
<div class="mb-3">
<label for="{{ form.delivery_address.id_for_label }}" class="form-label">
Адрес доставки
</label>
{{ form.delivery_address }}
{% if form.delivery_address.errors %}
<div class="text-danger">{{ form.delivery_address.errors }}</div>
<label class="form-label">{{ form.address_mode.label }}</label>
<div class="mt-2">
{% for choice in form.address_mode %}
<div class="form-check">
{{ choice.tag }}
<label class="form-check-label" for="{{ choice.id_for_label }}">
{{ choice.choice_label }}
</label>
</div>
{% endfor %}
</div>
{% if form.address_mode.errors %}
<div class="text-danger">{{ form.address_mode.errors }}</div>
{% endif %}
</div>
</div>
<!-- Режим 1: Выбор из истории -->
<div class="col-md-6" id="address-history-mode">
<div class="mb-3">
<label for="{{ form.address_from_history.id_for_label }}" class="form-label">
{{ form.address_from_history.label }}
</label>
{{ form.address_from_history }}
{% if form.address_from_history.errors %}
<div class="text-danger">{{ form.address_from_history.errors }}</div>
{% endif %}
<small class="text-muted d-block mt-2">Загрузка адресов из истории...</small>
</div>
</div>
<!-- Режим 2: Ввод нового адреса -->
<div class="col-12" id="address-new-mode">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.address_street.id_for_label }}" class="form-label">
{{ form.address_street.label }} <span class="text-danger">*</span>
</label>
{{ form.address_street }}
{% if form.address_street.errors %}
<div class="text-danger">{{ form.address_street.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.address_building_number.id_for_label }}" class="form-label">
{{ form.address_building_number.label }} <span class="text-danger">*</span>
</label>
{{ form.address_building_number }}
{% if form.address_building_number.errors %}
<div class="text-danger">{{ form.address_building_number.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.address_apartment_number.id_for_label }}" class="form-label">
{{ form.address_apartment_number.label }}
</label>
{{ form.address_apartment_number }}
{% if form.address_apartment_number.errors %}
<div class="text-danger">{{ form.address_apartment_number.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.address_entrance.id_for_label }}" class="form-label">
{{ form.address_entrance.label }}
</label>
{{ form.address_entrance }}
{% if form.address_entrance.errors %}
<div class="text-danger">{{ form.address_entrance.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.address_floor.id_for_label }}" class="form-label">
{{ form.address_floor.label }}
</label>
{{ form.address_floor }}
{% if form.address_floor.errors %}
<div class="text-danger">{{ form.address_floor.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.address_intercom_code.id_for_label }}" class="form-label">
{{ form.address_intercom_code.label }}
</label>
{{ form.address_intercom_code }}
{% if form.address_intercom_code.errors %}
<div class="text-danger">{{ form.address_intercom_code.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-3">
<label for="{{ form.address_delivery_instructions.id_for_label }}" class="form-label">
{{ form.address_delivery_instructions.label }}
</label>
{{ form.address_delivery_instructions }}
{% if form.address_delivery_instructions.errors %}
<div class="text-danger">{{ form.address_delivery_instructions.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="mb-3 form-check">
{{ form.address_confirm_with_recipient }}
<label class="form-check-label" for="{{ form.address_confirm_with_recipient.id_for_label }}">
{{ form.address_confirm_with_recipient.label }}
</label>
</div>
</div>
</div>
</div>
<!-- Стоимость доставки -->
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.delivery_cost.id_for_label }}" class="form-label">Стоимость доставки</label>
@@ -697,7 +838,116 @@ window.openCreateCustomerModal = function(searchText = '') {
createCustomerModal.show();
};
// Вызываем инициализацию
// === ИНИЦИАЛИЗАЦИЯ РЕЖИМОВ АДРЕСА (вне jQuery зависимости) ===
function initAddressModeToggle() {
console.log('[ADDRESS MODE] Initializing address mode toggle');
const addressModeRadios = document.querySelectorAll('input[name="address_mode"]');
const addressHistoryMode = document.getElementById('address-history-mode');
const addressNewMode = document.getElementById('address-new-mode');
const customerSelect = document.getElementById('id_customer');
if (!addressHistoryMode || !addressNewMode) {
console.error('[ADDRESS MODE] address-history-mode or address-new-mode not found in DOM');
return;
}
function toggleAddressMode() {
console.log('[ADDRESS MODE] toggleAddressMode() called');
const checkedRadio = document.querySelector('input[name="address_mode"]:checked');
if (!checkedRadio) {
console.log('[ADDRESS MODE] No radio checked, setting default to "empty"');
const emptyRadio = document.querySelector('input[name="address_mode"][value="empty"]');
if (emptyRadio) {
emptyRadio.checked = true;
}
}
const selectedMode = document.querySelector('input[name="address_mode"]:checked').value;
console.log('[ADDRESS MODE] Selected mode:', selectedMode);
// Убираем класс visible со всех режимов
addressHistoryMode.classList.remove('visible');
addressNewMode.classList.remove('visible');
if (selectedMode === 'history') {
console.log('[ADDRESS MODE] Showing history mode');
addressHistoryMode.classList.add('visible');
loadAddressHistory();
} else if (selectedMode === 'new') {
console.log('[ADDRESS MODE] Showing new address mode');
addressNewMode.classList.add('visible');
} else {
console.log('[ADDRESS MODE] Empty mode - hiding all sections');
}
}
function loadAddressHistory() {
console.log('[ADDRESS MODE] loadAddressHistory() called');
const customerId = customerSelect.value;
console.log('[ADDRESS MODE] Customer ID:', customerId);
if (!customerId) {
const addressSelect = document.getElementById('id_address_from_history');
addressSelect.innerHTML = '<option value="">-- История недоступна (клиент не выбран) --</option>';
return;
}
fetch(`{% url 'orders:api-customer-address-history' %}?customer_id=${customerId}`)
.then(response => response.json())
.then(data => {
console.log('[ADDRESS MODE] Address history data:', data);
const addressSelect = document.getElementById('id_address_from_history');
if (!data.success || data.count === 0) {
addressSelect.innerHTML = '<option value="">-- История адресов не найдена --</option>';
return;
}
let optionsHTML = '<option value="">-- Выберите адрес --</option>';
data.addresses.forEach(addr => {
optionsHTML += `<option value="${addr.id}">${addr.display}</option>`;
});
addressSelect.innerHTML = optionsHTML;
// Если есть Select2, обновляем его
if (typeof $ !== 'undefined' && $(addressSelect).data('select2')) {
$(addressSelect).trigger('change');
}
})
.catch(error => {
console.error('[ADDRESS MODE] Error loading address history:', error);
const addressSelect = document.getElementById('id_address_from_history');
addressSelect.innerHTML = '<option value="">-- Ошибка загрузки --</option>';
});
}
// Добавляем обработчики на radio кнопки
addressModeRadios.forEach(radio => {
console.log('[ADDRESS MODE] Adding listener to radio:', radio.value);
radio.addEventListener('change', function() {
console.log('[ADDRESS MODE] Radio changed to:', this.value);
toggleAddressMode();
});
});
// Загружаем адреса при изменении клиента
if (customerSelect) {
customerSelect.addEventListener('change', function() {
console.log('[ADDRESS MODE] Customer changed');
loadAddressHistory();
});
}
// Инициализация при загрузке
console.log('[ADDRESS MODE] Initial toggle call');
toggleAddressMode();
}
// Вызываем инициализацию адреса СРАЗУ (не зависит от jQuery)
initAddressModeToggle();
// Вызываем инициализацию Select2 для customer
initCustomerSelect2();
// Инициализация Select2 для остальных полей (после jQuery загружен)