Wie kann ich ein abhängiges Dropdown-Menü beim Laden der Seite "laden"?

9

Ich habe ein Formular mit einem abhängigen Dropdown. Dieses sekundäre Dropdown-Menü wird ausgeblendet, wenn die ausgewählte primäre Option keine sekundären Optionen enthält und wenn die Seite zum ersten Mal geladen wird. Immer wenn das Formular gesendet wird, wird nur das erste Feld gelöscht, da die Dropdown-Listen die meiste Zeit gleich bleiben, da das Skript jedoch immer dann funktioniert, wenn sich die primäre Dropdown-Liste ändert, da das Laden erfolgt stellt keine Änderung dar, sondern behält nur die ausgewählte / übermittelte Option in der primären Dropdown-Liste bei und zeigt nur eine leere sekundäre Dropdown-Liste an, selbst wenn die ausgewählte primäre Option sekundäre Optionen enthält. Ich habe den größten Teil des JS aus dem Dropdown-Menü eines Tutorials erhalten, da ich damit nicht sehr vertraut bin. Für ein besseres visuelles Verständnis:

Dies ist das Formular, wenn die Seite zum ersten Mal geladen wird

Geben Sie hier die Bildbeschreibung ein

Wenn Sie eine Option mit sekundären Optionen auswählen, wird die andere Dropdown-Liste angezeigt

Geben Sie hier die Bildbeschreibung ein

Nachdem Sie eine Station ausgewählt und gesendet haben, wird die Employee # gelöscht, die anderen beiden sollen jedoch erhalten bleiben. Wenn die Seite beim Senden neu geladen wird, sieht dies jedoch so aus, und die Station wurde laut Debugger gelöscht, da keine vorhanden sind technisch. Ich kümmere mich nicht so sehr um das Löschen der Station, sondern darum, kein leeres Dropdown-Menü zu haben, das nicht leer sein sollte.

Geben Sie hier die Bildbeschreibung ein

Und wenn ich mir die Daten ansehe, die im Formular verblieben sind, ist nur der Arbeitsbereich geblieben, da das abhängige Dropdown-Menü erst geladen wird, wenn Sie eine andere Option aus dem Dropdown-Menü auswählen und wenn Sie die Optionen für die Box-Baugruppe erneut anzeigen möchten , müssten Sie auf eine andere Option klicken und dann zu Box Assembly zurückkehren (zum Beispiel)

Wie kann ich dieses Problem beheben? Gibt es eine Möglichkeit, das Javascript zu zwingen, zuerst zu versuchen, es zu laden, damit überprüft wird, ob die verbleibende Option die sekundären Optionen enthält, ob sie ausgelöst wurde oder nicht?

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'),
]

Am Ende dieses HTML-Codes befindet sich das Skript, das das abhängige Dropdown-Menü verarbeitet

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 %}
Mariana Gomez-Kusnecov
quelle

Antworten:

3

Ich sehe, dass du hast $(document).ready(loadStations);.

Aber das Problem ist, dass loadStationsSie es tun var workAreaId = $(this).val();.

thiswird sein documentund $(document).val()ist eine leere Zeichenfolge.

Entweder den Selektor fest codieren in loadStations:

// var workAreaId = $(this).val();
var workAreaId = $("#id_work_area").val();

Oder lösen Sie stattdessen die Änderung aus dem Element aus:

$("#id_work_area").change(loadStations);
// $(document).ready(loadStations);
$("#id_work_area").change();
Aaron
quelle
Die erste Option hat nicht funktioniert (es wurde nichts geladen), die zweite jedoch, danke! Ich werde das Kopfgeld in einer Stunde vergeben, es lässt mich noch nicht
Mariana Gomez-Kusnecov