J'ai un formulaire avec une liste déroulante dépendante. Cette liste déroulante secondaire est masquée chaque fois que l'option principale sélectionnée n'a pas d'options secondaires et lors du premier chargement de la page. Chaque fois que le formulaire est soumis, seul le premier champ est effacé, car la plupart du temps les listes déroulantes restent les mêmes, cependant, car le script fonctionne chaque fois qu'il y a un changement dans la liste déroulante principale, car la charge sur ne ne constitue pas un changement, il conserve simplement l'option sélectionnée / soumise dans la liste déroulante principale et affiche simplement une liste déroulante secondaire vide, même lorsque l'option principale sélectionnée a des options secondaires. J'ai obtenu la plupart des JS à partir du menu déroulant d'un tutoriel, car je ne le connais pas très bien. Pour une compréhension plus visuelle:
Voici le formulaire lors du premier chargement de la page
Lorsque vous sélectionnez une option qui a des options secondaires, l'autre liste déroulante apparaît
Après avoir sélectionné une station et soumis, l'employé # efface, mais les deux autres sont censés rester, cependant, lorsque la page se recharge lors de la soumission, cela ressemble à ceci, et la station a été effacée selon le débogueur car il n'y en a pas techniquement. Je ne me soucie pas tellement du nettoyage de la station, mais plutôt du fait de ne pas avoir de liste déroulante vide qui ne devrait pas être vide.
Et quand je regarde les données qui sont restées dans le formulaire, seule la zone de travail est restée, car la liste déroulante dépendante ne se charge pas jusqu'à ce que vous sélectionniez une autre option dans la liste déroulante et si vous vouliez pouvoir voir à nouveau les options d'assemblage de boîtes , vous devez cliquer sur une autre option, puis revenir à l'assemblage de la boîte (par exemple)
Comment pourrais-je résoudre ce problème? Existe-t-il un moyen de forcer le javascript à tenter de se charger en premier pour qu'il vérifie si l'option qui reste a les options secondaires, si elle a été déclenchée ou non?
forms.py
class WarehouseForm(AppsModelForm):
class Meta:
model = EmployeeWorkAreaLog
widgets = {
'employee_number': ForeignKeyRawIdWidget(EmployeeWorkAreaLog._meta.get_field('employee_number').remote_field, site, attrs={'id':'employee_number_field'}),
}
fields = ('employee_number', 'work_area', 'station_number')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['station_number'].queryset = Station.objects.none()
if 'work_area' in self.data:
try:
work_area_id = int(self.data.get('work_area'))
self.fields['station_number'].queryset = Station.objects.filter(work_area_id=work_area_id).order_by('name')
except (ValueError, TypeError):
pass
elif self.instance.pk:
self.fields['station_number'].queryset = self.instance.work_area.stations.order_by('name')
views.py
def enter_exit_area(request):
enter_without_exit = None
exit_without_enter = None
if request.method == 'POST':
form = WarehouseForm(request.POST)
if form.is_valid():
emp_num = form.cleaned_data['employee_number']
area = form.cleaned_data['work_area']
station = form.cleaned_data['station_number']
# Submission logic
form = WarehouseForm(initial={'employee_number': '', 'work_area': area, 'station_number': station})
else:
form = WarehouseForm()
return render(request, "operations/enter_exit_area.html", {
'form': form,
'enter_without_exit': enter_without_exit,
'exit_without_enter': exit_without_enter,
})
urls.py
urlpatterns = [
url(r'enter-exit-area/$', views.enter_exit_area, name='enter_exit_area'),
path('ajax/load-stations/', views.load_stations, name='ajax_load_stations'),
]
À la fin de ce code HTML se trouve le script qui gère la liste déroulante dépendante
enter_exit_area.html
{% extends "operations/base.html" %}
{% block main %}
<form id="warehouseForm" action="" method="POST" data-stations-url="{% url 'operations:ajax_load_stations' %}" novalidate >
{% csrf_token %}
<div>
<div>
<label>Employee #</label>
{{ form.employee_number }}
</div>
<div>
<label>Work Area</label>
{{ form.work_area }}
</div>
<div class="col-xs-8" id="my-hidden-div">
<label>Station</label>
{{ form.station_number }}
</div>
</div>
</form>
<script>
function loadStations() {
var url = $("#warehouseForm").attr("data-stations-url");
var workAreaId = $(this).val();
var $stationNumberField = $("#{{ form.station_number.id_for_label }}");
$.ajax({
url: url,
data: {
'work_area': workAreaId
},
success: function (data) {
$("#my-hidden-div").show(); // show it
$stationNumberField.html(data);
// Check the length of the options child elements of the select
if ($stationNumberField.find("option").length === 1) {
$stationNumberField.parent().hide(); // Hide parent of the select node
} else {
// If any option, ensure the select is shown
$stationNumberField.parent().show();
}
}
});
}
$("#id_work_area").change(loadStations);
$(document).ready(loadStations);
</script>
{% endblock main %}
station_number_dropdown_options.html
<option value="">---------</option>
{% for station in stations %}
<option value="{{ station.pk }}">{{ station.name }}</option>
{% endfor %}