Улучшен интерфейс ввода даты и времени доставки

- Исправлены имена полей времени (time_from/time_to вместо delivery_time_start/end)
- Поля времени сделаны необязательными (дата остается обязательной)
- Добавлен улучшенный UI с быстрыми кнопками для даты и времени
- Поля ввода расположены в один ряд, кнопки быстрого выбора ниже
- Добавлены CSS и JS файлы для улучшенного интерфейса
- Обновлена валидация: время необязательно, но если указано одно - должно быть и другое
This commit is contained in:
2025-12-24 18:25:20 +03:00
parent d62caa924b
commit 61ce3f550d
7 changed files with 459 additions and 46 deletions

View File

@@ -6,6 +6,7 @@
{% block extra_css %}
<meta name="csrf-token" content="{{ csrf_token }}">
<link rel="stylesheet" href="{% static 'orders/css/delivery_datetime.css' %}">
<style>
/* Скрываем DELETE checkbox */
input[name$="-DELETE"] {
@@ -200,34 +201,40 @@
<h5 class="mb-0">Дата и время доставки</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.delivery_date.id_for_label }}" class="form-label">Дата</label>
<div class="delivery-datetime-wrapper">
<!-- Поля ввода в один ряд -->
<div class="row g-3 mb-3">
<div class="col-md-4">
<label for="{{ form.delivery_date.id_for_label }}" class="form-label">
Дата <span class="text-danger">*</span>
</label>
{{ form.delivery_date }}
{% if form.delivery_date.errors %}
<div class="text-danger">{{ form.delivery_date.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.delivery_time_start.id_for_label }}" class="form-label">Время от</label>
{{ form.delivery_time_start }}
{% if form.delivery_time_start.errors %}
<div class="text-danger">{{ form.delivery_time_start.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.delivery_time_end.id_for_label }}" class="form-label">Время до</label>
{{ form.delivery_time_end }}
{% if form.delivery_time_end.errors %}
<div class="text-danger">{{ form.delivery_time_end.errors }}</div>
<div class="col-md-4">
<label for="{{ form.time_from.id_for_label }}" class="form-label">
Время от
</label>
{{ form.time_from }}
{% if form.time_from.errors %}
<div class="text-danger">{{ form.time_from.errors }}</div>
{% endif %}
</div>
<div class="col-md-4">
<label for="{{ form.time_to.id_for_label }}" class="form-label">
Время до
</label>
{{ form.time_to }}
{% if form.time_to.errors %}
<div class="text-danger">{{ form.time_to.errors }}</div>
{% endif %}
</div>
</div>
<!-- Кнопки быстрого выбора ниже полей -->
<div id="delivery-datetime-quick-buttons"></div>
</div>
</div>
</div>
@@ -910,6 +917,9 @@ document.addEventListener('DOMContentLoaded', function() {
});
</script>
<!-- Delivery Date/Time Widget -->
<script src="{% static 'orders/js/delivery_datetime.js' %}"></script>
<!-- Unified Transaction Form -->
<script src="{% static 'orders/js/unified_transaction_form.js' %}"></script>
{% if order.pk %}
@@ -971,24 +981,36 @@ document.addEventListener('DOMContentLoaded', function() {
}
function syncUIFromCheckbox() {
if (!isDeliveryCheckbox) return; // Защита от null
if (isDeliveryCheckbox.checked) {
document.getElementById('delivery-type-delivery').checked = true;
deliveryModeFields.style.display = 'block';
pickupFields.style.display = 'none';
const deliveryRadio = document.getElementById('delivery-type-delivery');
if (deliveryRadio) {
deliveryRadio.checked = true;
}
if (deliveryModeFields) deliveryModeFields.style.display = 'block';
if (pickupFields) pickupFields.style.display = 'none';
} else {
document.getElementById('delivery-type-pickup').checked = true;
deliveryModeFields.style.display = 'none';
pickupFields.style.display = 'block';
const pickupRadio = document.getElementById('delivery-type-pickup');
if (pickupRadio) {
pickupRadio.checked = true;
}
if (deliveryModeFields) deliveryModeFields.style.display = 'none';
if (pickupFields) pickupFields.style.display = 'block';
}
}
// Обработчики для кнопок
deliveryTypeRadios.forEach(radio => {
radio.addEventListener('change', syncDeliveryTypeFromRadio);
});
if (deliveryTypeRadios && deliveryTypeRadios.length > 0) {
deliveryTypeRadios.forEach(radio => {
radio.addEventListener('change', syncDeliveryTypeFromRadio);
});
}
// Инициализация при загрузке
syncUIFromCheckbox();
if (isDeliveryCheckbox) {
syncUIFromCheckbox();
}
// Показ/скрытие полей получателя
const otherRecipientCheckbox = document.getElementById('{{ form.other_recipient.id_for_label }}');