I'm putting together dependent drop-downs (Teacher -> Class -> Student) and am having issues with setting the initial state of the drop-downs. Here's the code:
edit_contract.html
{% load crispy_forms_tags %}
<div>
<form method="post" id="contractForm" novalidate
data-teachers-url="{% url 'wakemeup:ajax_load_teachers' %}"
data-classes-url="{% url 'wakemeup:ajax_load_classes' %}"
data-students-url="{% url 'wakemeup:ajax_load_students' %}"
>
{% crispy form %}
</form>
</div>
<script>
// Update class drop-down when teacher changes
$("#id_teacheruserid").change(function () {
update_classes($(this))
});
// Update students drop-down when class changes
$("#id_classid").change(function () {
update_students($(this))
});
function update_teachers() {
// Get form values
var url = $("#contractForm").attr("data-teachers-url");
var contractId = $(document.getElementById("id_contractid")).val();
$.ajax({ // initialize AJAX request
url: url,
data: {
'contractid': contractId
},
success: function (data) {
$("#id_teacheruserid").html(data); // Update "teacheruserid" field
}
})
update_classes(); // Update classes drop-down
};
function update_classes() {
// Get form values
var url = $("#contractForm").attr("data-classes-url");
var teacherUserId = $(document.getElementById("id_teacheruserid")).val();
var contractId = $(document.getElementById("id_contractid")).val();
$.ajax({ // initialize AJAX request
url: url,
data: {
'teacheruserid': teacherUserId,
'contractid': contractId
},
success: function (data) {
$("#id_classid").html(data); // Update "classid" field
}
})
update_students(); // Update students drop-down
};
function update_students() {
// Get form values
var url = $("#contractForm").attr("data-students-url");
var classId = $(document.getElementById("id_classid")).val();
var contractId = $(document.getElementById("id_contractid")).val();
$.ajax({ // initialize AJAX request
url: url,
data: {
'classid': classId,
'contractid': contractId
},
success: function (data) {
$("#id_partyuserinfo").html(data); // Update "partyuserinfo" field
}
})
};
window.onload = function() {
// Initial load of drop-down menus
update_teachers(); // Cascades to update_classes() and update_students()
};
</script>
Flow summary
update_teacher()
- update HTML (drop-down options) for "id_teacheruserid" field
update_classes()
- read value from "id_teacheruserid" field (undefined for initial load)
- update HTML (drop-down options) for "id_classid" field
update_students()
- read value from "id_classid" field (undefined for initial load)
- update HTML (drop-down options) for "id_partyuserinfo" field
The problem
The problem I'm seeing is that the script can't access the values in the form fields in the onload()
call. For example, this line in update_classes()
:
var teacherUserId = $(document.getElementById("id_teacheruserid")).val();
I added an alert(teacherUserId)
directly after this line. On initial page load, it returns undefined
. However, when I select a different value from the teacher drop-down, the alert displays the expected value.
My guess is that in the initial onload()
, the referenced field values/options (i.e. id_teacheruserid
) have not been loaded or made available yet. The fields themselves exist, but return undefined
values. Once this function completes, though, it seems they are then accessible and the menus behave as expected.
How can I run update_teachers()
to do the initial load and have it access the form field values?