changes in cities
This commit is contained in:
parent
2d5dec02ad
commit
95e2847b94
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -10,8 +10,8 @@ class UserRegistrationForm(forms.ModelForm):
|
|||||||
phone_number = forms.CharField(max_length=20, label=_("Phone Number"))
|
phone_number = forms.CharField(max_length=20, label=_("Phone Number"))
|
||||||
|
|
||||||
country = forms.ModelChoiceField(queryset=Country.objects.all(), required=False, label=_("Country"))
|
country = forms.ModelChoiceField(queryset=Country.objects.all(), required=False, label=_("Country"))
|
||||||
governate = forms.ModelChoiceField(queryset=Governate.objects.all(), required=False, label=_("Governate"))
|
governate = forms.ModelChoiceField(queryset=Governate.objects.none(), required=False, label=_("Governate"))
|
||||||
city = forms.ModelChoiceField(queryset=City.objects.all(), required=False, label=_("City"))
|
city = forms.ModelChoiceField(queryset=City.objects.none(), required=False, label=_("City"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
@ -23,6 +23,26 @@ class UserRegistrationForm(forms.ModelForm):
|
|||||||
'last_name': _('Last Name'),
|
'last_name': _('Last Name'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
if 'country' in self.data:
|
||||||
|
try:
|
||||||
|
country_id = int(self.data.get('country'))
|
||||||
|
self.fields['governate'].queryset = Governate.objects.filter(country_id=country_id).order_by('name')
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
elif self.instance.pk and hasattr(self.instance, 'profile') and self.instance.profile.country:
|
||||||
|
self.fields['governate'].queryset = self.instance.profile.country.governate_set.order_by('name')
|
||||||
|
|
||||||
|
if 'governate' in self.data:
|
||||||
|
try:
|
||||||
|
governate_id = int(self.data.get('governate'))
|
||||||
|
self.fields['city'].queryset = City.objects.filter(governate_id=governate_id).order_by('name')
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
elif self.instance.pk and hasattr(self.instance, 'profile') and self.instance.profile.governate:
|
||||||
|
self.fields['city'].queryset = self.instance.profile.governate.city_set.order_by('name')
|
||||||
|
|
||||||
def clean_password_confirm(self):
|
def clean_password_confirm(self):
|
||||||
password = self.cleaned_data.get('password')
|
password = self.cleaned_data.get('password')
|
||||||
password_confirm = self.cleaned_data.get('password_confirm')
|
password_confirm = self.cleaned_data.get('password_confirm')
|
||||||
@ -84,4 +104,42 @@ class ParcelForm(forms.ModelForm):
|
|||||||
'delivery_address': _('Delivery Address (Street/Building)'),
|
'delivery_address': _('Delivery Address (Street/Building)'),
|
||||||
'receiver_name': _('Receiver Name'),
|
'receiver_name': _('Receiver Name'),
|
||||||
'receiver_phone': _('Receiver Phone'),
|
'receiver_phone': _('Receiver Phone'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
# Pickup
|
||||||
|
self.fields['pickup_governate'].queryset = Governate.objects.none()
|
||||||
|
self.fields['pickup_city'].queryset = City.objects.none()
|
||||||
|
|
||||||
|
if 'pickup_country' in self.data:
|
||||||
|
try:
|
||||||
|
country_id = int(self.data.get('pickup_country'))
|
||||||
|
self.fields['pickup_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by('name')
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if 'pickup_governate' in self.data:
|
||||||
|
try:
|
||||||
|
gov_id = int(self.data.get('pickup_governate'))
|
||||||
|
self.fields['pickup_city'].queryset = City.objects.filter(governate_id=gov_id).order_by('name')
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Delivery
|
||||||
|
self.fields['delivery_governate'].queryset = Governate.objects.none()
|
||||||
|
self.fields['delivery_city'].queryset = City.objects.none()
|
||||||
|
|
||||||
|
if 'delivery_country' in self.data:
|
||||||
|
try:
|
||||||
|
country_id = int(self.data.get('delivery_country'))
|
||||||
|
self.fields['delivery_governate'].queryset = Governate.objects.filter(country_id=country_id).order_by('name')
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if 'delivery_governate' in self.data:
|
||||||
|
try:
|
||||||
|
gov_id = int(self.data.get('delivery_governate'))
|
||||||
|
self.fields['delivery_city'].queryset = City.objects.filter(governate_id=gov_id).order_by('name')
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
pass
|
||||||
|
|||||||
@ -11,11 +11,11 @@
|
|||||||
<div class="card shadow-sm border-0">
|
<div class="card shadow-sm border-0">
|
||||||
<div class="card-body p-5">
|
<div class="card-body p-5">
|
||||||
<h2 class="fw-bold mb-4 text-center">{% trans "Join masarX" %}</h2>
|
<h2 class="fw-bold mb-4 text-center">{% trans "Join masarX" %}</h2>
|
||||||
<form method="post">
|
<form method="post" id="registrationForm">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label fw-semibold">{{ field.label }}</label>
|
<label class="form-label fw-semibold" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||||
{{ field }}
|
{{ field }}
|
||||||
{% if field.help_text %}
|
{% if field.help_text %}
|
||||||
<div class="form-text small">{{ field.help_text }}</div>
|
<div class="form-text small">{{ field.help_text }}</div>
|
||||||
@ -37,6 +37,51 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const countrySelect = document.getElementById('id_country');
|
||||||
|
const governateSelect = document.getElementById('id_governate');
|
||||||
|
const citySelect = document.getElementById('id_city');
|
||||||
|
|
||||||
|
countrySelect.addEventListener('change', function() {
|
||||||
|
const countryId = this.value;
|
||||||
|
governateSelect.innerHTML = '<option value="">{% trans "Select Governate" %}</option>';
|
||||||
|
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||||
|
|
||||||
|
if (countryId) {
|
||||||
|
fetch(`/ajax/get-governates/?country_id=${countryId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
data.forEach(gov => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = gov.id;
|
||||||
|
option.textContent = gov.name;
|
||||||
|
governateSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
governateSelect.addEventListener('change', function() {
|
||||||
|
const governateId = this.value;
|
||||||
|
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||||
|
|
||||||
|
if (governateId) {
|
||||||
|
fetch(`/ajax/get-cities/?governate_id=${governateId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
data.forEach(city => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = city.id;
|
||||||
|
option.textContent = city.name;
|
||||||
|
citySelect.appendChild(option);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
input, select {
|
input, select {
|
||||||
display: block;
|
display: block;
|
||||||
@ -61,4 +106,4 @@
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<div class="row g-3">
|
<div class="row g-3">
|
||||||
{% for field in form %}
|
{% for field in form %}
|
||||||
<div class="{% if field.name == 'description' %}col-12{% else %}col-md-6{% endif %}">
|
<div class="{% if field.name == 'description' %}col-12{% else %}col-md-6{% endif %}">
|
||||||
<label class="form-label">{{ field.label }}</label>
|
<label class="form-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||||
{{ field }}
|
{{ field }}
|
||||||
{% if field.errors %}
|
{% if field.errors %}
|
||||||
<div class="text-danger small">{{ field.errors }}</div>
|
<div class="text-danger small">{{ field.errors }}</div>
|
||||||
@ -29,4 +29,56 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
function setupDependentDropdowns(countryId, governateId, cityId) {
|
||||||
|
const countrySelect = document.getElementById(countryId);
|
||||||
|
const governateSelect = document.getElementById(governateId);
|
||||||
|
const citySelect = document.getElementById(cityId);
|
||||||
|
|
||||||
|
if (!countrySelect || !governateSelect || !citySelect) return;
|
||||||
|
|
||||||
|
countrySelect.addEventListener('change', function() {
|
||||||
|
const val = this.value;
|
||||||
|
governateSelect.innerHTML = '<option value="">{% trans "Select Governate" %}</option>';
|
||||||
|
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
fetch(`/ajax/get-governates/?country_id=${val}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
data.forEach(item => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = item.id;
|
||||||
|
option.textContent = item.name;
|
||||||
|
governateSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
governateSelect.addEventListener('change', function() {
|
||||||
|
const val = this.value;
|
||||||
|
citySelect.innerHTML = '<option value="">{% trans "Select City" %}</option>';
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
fetch(`/ajax/get-cities/?governate_id=${val}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
data.forEach(item => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = item.id;
|
||||||
|
option.textContent = item.name;
|
||||||
|
citySelect.appendChild(option);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupDependentDropdowns('id_pickup_country', 'id_pickup_governate', 'id_pickup_city');
|
||||||
|
setupDependentDropdowns('id_delivery_country', 'id_delivery_governate', 'id_delivery_city');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@ -12,4 +12,8 @@ urlpatterns = [
|
|||||||
path('accept-parcel/<int:parcel_id>/', views.accept_parcel, name='accept_parcel'),
|
path('accept-parcel/<int:parcel_id>/', views.accept_parcel, name='accept_parcel'),
|
||||||
path('update-status/<int:parcel_id>/', views.update_status, name='update_status'),
|
path('update-status/<int:parcel_id>/', views.update_status, name='update_status'),
|
||||||
path('article/', views.article_detail, name='article_detail'),
|
path('article/', views.article_detail, name='article_detail'),
|
||||||
]
|
|
||||||
|
# AJAX for locations
|
||||||
|
path('ajax/get-governates/', views.get_governates, name='get_governates'),
|
||||||
|
path('ajax/get-cities/', views.get_cities, name='get_cities'),
|
||||||
|
]
|
||||||
|
|||||||
@ -2,10 +2,11 @@ from django.shortcuts import render, redirect, get_object_or_404
|
|||||||
from django.contrib.auth import login, authenticate, logout
|
from django.contrib.auth import login, authenticate, logout
|
||||||
from django.contrib.auth.forms import AuthenticationForm
|
from django.contrib.auth.forms import AuthenticationForm
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from .models import Parcel, Profile
|
from .models import Parcel, Profile, Country, Governate, City
|
||||||
from .forms import UserRegistrationForm, ParcelForm
|
from .forms import UserRegistrationForm, ParcelForm
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.http import JsonResponse
|
||||||
|
|
||||||
def index(request):
|
def index(request):
|
||||||
tracking_id = request.GET.get('tracking_id')
|
tracking_id = request.GET.get('tracking_id')
|
||||||
@ -96,4 +97,14 @@ def update_status(request, parcel_id):
|
|||||||
return redirect('dashboard')
|
return redirect('dashboard')
|
||||||
|
|
||||||
def article_detail(request):
|
def article_detail(request):
|
||||||
return render(request, 'core/article_detail.html')
|
return render(request, 'core/article_detail.html')
|
||||||
|
|
||||||
|
def get_governates(request):
|
||||||
|
country_id = request.GET.get('country_id')
|
||||||
|
governates = Governate.objects.filter(country_id=country_id).values('id', 'name')
|
||||||
|
return JsonResponse(list(governates), safe=False)
|
||||||
|
|
||||||
|
def get_cities(request):
|
||||||
|
governate_id = request.GET.get('governate_id')
|
||||||
|
cities = City.objects.filter(governate_id=governate_id).values('id', 'name')
|
||||||
|
return JsonResponse(list(cities), safe=False)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user