¿Cómo "cargar" el menú desplegable dependiente de la carga de la página?

9

Tengo un formulario con un menú desplegable dependiente. Este menú desplegable secundario se oculta cuando la opción principal seleccionada no tiene ninguna opción secundaria, y cuando la página se carga por primera vez. Cuando se envía el formulario, solo se borra el primer campo, ya que la mayoría de las veces los menús desplegables siguen siendo los mismos, ya que el script funciona cada vez que hay un cambio en el menú desplegable primario, ya que la carga sobre no constituye un cambio, solo mantiene la opción seleccionada / enviada en el menú desplegable principal y solo mostrará un menú desplegable secundario vacío, incluso cuando la opción primaria seleccionada tenga opciones secundarias. Obtuve la mayor parte del JS del menú desplegable de un tutorial, ya que no estoy muy familiarizado con él. Para una comprensión más visual:

Este es el formulario cuando la página se carga por primera vez

ingrese la descripción de la imagen aquí

Cuando selecciona una opción que tiene opciones secundarias, aparece el otro menú desplegable

ingrese la descripción de la imagen aquí

Después de seleccionar una Estación y enviarla, el Número de empleado se borra, pero se supone que las otras dos permanecen, sin embargo, cuando la página se recarga al enviarla, se ve así, y la estación se ha borrado de acuerdo con el depurador ya que no hay ninguna técnicamente. No me importa mucho el despeje de la estación, sino más bien no tener un menú desplegable vacío que no debería estar vacío.

ingrese la descripción de la imagen aquí

Y cuando miro los datos que permanecieron en el formulario, solo se mantuvo el área de trabajo, porque el menú desplegable dependiente no se carga hasta que selecciona otra opción del menú desplegable, y si desea poder volver a ver las opciones de Ensamblaje de caja , tendría que hacer clic en otra opción y luego volver al Ensamblaje de caja (por ejemplo)

¿Cómo podría solucionar este problema? ¿Hay alguna forma de obligar al javascript a intentar cargar primero para que verifique si la opción que queda tiene las opciones secundarias, ya sea que se haya activado o no?

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

Al final de este html está el script que maneja el menú desplegable dependiente

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 Gómez-Kusnecov
fuente

Respuestas:

3

Veo que tienes $(document).ready(loadStations);.

Pero el problema es que loadStationsvar workAreaId = $(this).val();.

thisserá document, y $(document).val()es una cadena vacía.

Ya sea codificar el selector en loadStations:

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

O desencadenar el cambio desde el elemento en su lugar:

$("#id_work_area").change(loadStations);
// $(document).ready(loadStations);
$("#id_work_area").change();
aaron
fuente
La primera opción no funcionó (no cargaría nada) pero la segunda sí, ¡gracias!
Otorgaré