I had a similar issue last month where we were not allowed to use Ajax and reloading the page every time someone changed an option was tedious and long. My coworker found a javascript function that allowed dynamic loading of the child dropdown based on a selection from a parent dropdown. I made it generic and reusable and use it throughout my project. Doing the tripple dropdown was tricky so here is what I did.
<script type="text/javascript>
/**************************************************
function: populate a child drop-down dynamically depending
on what parent value was choosen.
Parameters:
mstParent (hidden parent select whose options are (pk, parent text)) not null
mstChild (hidden child select whose options are (pk, child text)) not null
selectedParentValue (the value that the user seleted) not null
childDropdownBox (the box to populate with new values) not null
selectedChildValue (the value that the user selected) can be null
***************************************************/
function setChildDropdownBox(mstParent, mstChild,
selectedParentValue, childDropdownBox, selectedChildValue){
childDropdownBox.options.length = 0;
/*
* If there is no parent selected then set the child to
* disabled and inform them to select an option from the primary
* drop-down
*/
if(selectedParentValue == ""){
childDropdownBox.disabled = true;
childDropdownBox.options[childDropdownBox.options.length] =
new Option("Please select primary dropdown first","");
}else{
childDropdownBox.disabled = false;
childDropdownBox.options[childDropdownBox.options.length] =
new Option("-- Please select a value --","");
var index1;
for(index1=0; index1<mstParent.length; index1++){
if(mstParent.options[index1].text == selectedParentValue){
childDropdownBox.options[childDropdownBox.options.length] =
new Option(mstChild.options[index1].text,mstChild.options[index1].value);
if(selectedChildValue != "" && selectedChildValue == mstChild.options[index1].value){
childDropdownBox.options[childDropdownBox.options.length-1].selected = true;
}
}
}
}
return childDropdownBox.options;
}
/**************************************************
function: populate Secondary drop-down when primary drop-down
is choosen, then populates the Tertiary drop-down based on
the first value in the secondary drop-down
***************************************************/
function updateSecondaryDropdown(selectedParentValue){
var mstParentList = document.getElementById("masterPrimaryList");
var mstChildList = document.getElementById("masterSecondaryList");
var childSelectBox = document.getElementById("secondaryBox");
var childIdHidden = document.getElementById("secondaryBoxHidden").value;
setChildDropdownBox(mstParentList, mstChildList, selectedParentValue, childSelectBox, childIdHidden);
var selectedSecondaryValue = document.getElementById("secondaryBox").value;
updateTertiaryDropdown(selectedSecondaryValue);
}
</script> "secondaryBox" was the id for the select box that the user sees with "secondaryBoxHidden" containing the original value of the secondary box (my page did have to reload at some point and I had to load those boxes on page load so I saved the value in a hidden then call the javascript functions to load the boxes according to the user's selected values before the reload)
Inside the jsp I put several hidden select boxes that contain the values that I want. Two for each parent/child option. The "secondaryList" was a custome class that contained two strings, a primary value and a secondary value. I then inside my controller populated that with unique combinations of those two and excluded the third for now.
I then did the same for the tertiary drop-down with a complete list of all values from the database and constructed the first invisible select with:
secondary
and for the tertiary:
tertiary<div style="display:none;">
<c:if test="${secondaryList ne null}">
<select id="masterPrimaryList">
<c:forEach items="${secondaryList }" var="view">
<option value="${view.primary}">${view.primary}</option>
</c:forEach>
</select>
<select id="masterSecondaryList">
<c:forEach items="${secondaryList }" var="view">
<option value="${view.secondary}">${view.secondary}</option>
</c:forEach>
</select>
</c:if>
</div>
I hope this helps.