I am dynamically changing the options in 8 selects based on a separate selected option. The process handles counties in a state and updating all 8 selects for each county in a state is terribly repetitive as each option can only exist in one select.
My original code was thrown together quickly but worked fine:
FLCounties = [
"Alachua",
"Baker",
"Bay",
"etc."];
//Get the selects
var countyDrop1 = document.getElementById("county1");
var countyDrop2 = document.getElementById("county2");
var countyDrop3 = document.getElementById("county3");
var countyDrop4 = document.getElementById("county4");
var countyDrop5 = document.getElementById("county5");
var countyDrop6 = document.getElementById("county6");
var countyDrop7 = document.getElementById("county7");
var countyDrop8 = document.getElementById("county8");
//Get the default state if any
var initialState = document.getElementById("state").value;
getState(initialState);
//Called from onchange on the state select
function getState(sel) {
//Clear previous options and add a notice to select a state
while (countyDrop1.firstChild) {
countyDrop1.removeChild(countyDrop1.firstChild);
};
var defaultEl1= document.createElement("option");
defaultEl1.textContent = "Select a state above first.";
defaultEl1.value = "";
countyDrop1.appendChild(defaultEl1);
while (countyDrop2.firstChild) {
countyDrop2.removeChild(countyDrop2.firstChild);
};
var defaultEl2= document.createElement("option");
defaultEl2.textContent = "Select a state above first.";
defaultEl2.value = "";
countyDrop2.appendChild(defaultEl2);
while (countyDrop3.firstChild) {
countyDrop3.removeChild(countyDrop3.firstChild);
};
var defaultEl3= document.createElement("option");
defaultEl3.textContent = "Select a state above first.";
defaultEl3.value = "";
countyDrop3.appendChild(defaultEl3);
while (countyDrop4.firstChild) {
countyDrop4.removeChild(countyDrop4.firstChild);
};
var defaultEl4= document.createElement("option");
defaultEl4.textContent = "Select a state above first.";
defaultEl4.value = "";
countyDrop4.appendChild(defaultEl4);
while (countyDrop5.firstChild) {
countyDrop5.removeChild(countyDrop5.firstChild);
};
var defaultEl5= document.createElement("option");
defaultEl5.textContent = "Select a state above first.";
defaultEl5.value = "";
countyDrop5.appendChild(defaultEl5);
while (countyDrop6.firstChild) {
countyDrop6.removeChild(countyDrop6.firstChild);
};
var defaultEl6= document.createElement("option");
defaultEl6.textContent = "Select a state above first.";
defaultEl6.value = "";
countyDrop6.appendChild(defaultEl6);
while (countyDrop7.firstChild) {
countyDrop7.removeChild(countyDrop7.firstChild);
};
var defaultEl7= document.createElement("option");
defaultEl7.textContent = "Select a state above first.";
defaultEl7.value = "";
countyDrop7.appendChild(defaultEl7);
while (countyDrop8.firstChild) {
countyDrop8.removeChild(countyDrop8.firstChild);
};
var defaultEl8= document.createElement("option");
defaultEl8.textContent = "Select a state above first.";
defaultEl8.value = "";
countyDrop8.appendChild(defaultEl8);
//if no state is selected, do nothing
if (sel != ""){
switch (sel){
//value of option Florida
case "FL":
//change "select a state first" to "select a county"
countyDrop1.firstChild.textContent = "- Select a County -";
countyDrop2.firstChild.textContent = "- Select a County -";
countyDrop3.firstChild.textContent = "- Select a County -";
countyDrop4.firstChild.textContent = "- Select a County -";
countyDrop5.firstChild.textContent = "- Select a County -";
countyDrop6.firstChild.textContent = "- Select a County -";
countyDrop7.firstChild.textContent = "- Select a County -";
countyDrop8.firstChild.textContent = "- Select a County -";
for(var i = 0; i < FLCounties.length; i++) {
var opt = FLCounties[i];
var el1 = document.createElement("option");
el1.textContent = opt;
el1.value = opt;
var el2 = document.createElement("option");
el2.textContent = opt;
el2.value = opt;
var el3 = document.createElement("option");
el3.textContent = opt;
el3.value = opt;
var el4 = document.createElement("option");
el4.textContent = opt;
el4.value = opt;
var el5 = document.createElement("option");
el5.textContent = opt;
el5.value = opt;
var el6 = document.createElement("option");
el6.textContent = opt;
el6.value = opt;
var el7 = document.createElement("option");
el7.textContent = opt;
el7.value = opt;
var el8 = document.createElement("option");
el8.textContent = opt;
el8.value = opt;
countyDrop1.appendChild(el1);
countyDrop2.appendChild(el2);
countyDrop3.appendChild(el3);
countyDrop4.appendChild(el4);
countyDrop5.appendChild(el5);
countyDrop6.appendChild(el6);
countyDrop7.appendChild(el7);
countyDrop8.appendChild(el8);
}
break;
[rinse and repeat, 49 times]
I tried condensing it into a series of arrays and for loops, which really shortens the code, but it breaks the page (an infinite loop somewhere I'm sure).
New code (does not work):
var FLCounties = [
//same as above
];
var dropdowns = [
countyDrop1 = document.getElementById("county1"),
countyDrop2 = document.getElementById("county2"),
countyDrop3 = document.getElementById("county3"),
countyDrop4 = document.getElementById("county4"),
countyDrop5 = document.getElementById("county5"),
countyDrop6 = document.getElementById("county6"),
countyDrop7 = document.getElementById("county7"),
countyDrop8 = document.getElementById("county8")
];
var defaultOptions = [
defaultEl1 = document.createElement("option"),
defaultEl2 = document.createElement("option"),
defaultEl3 = document.createElement("option"),
defaultEl4 = document.createElement("option"),
defaultEl5 = document.createElement("option"),
defaultEl6 = document.createElement("option"),
defaultEl7 = document.createElement("option"),
defaultEl8 = document.createElement("option")
];
var options = [
el1 = document.createElement("option"),
el2 = document.createElement("option"),
el3 = document.createElement("option"),
el4 = document.createElement("option"),
el5 = document.createElement("option"),
el6 = document.createElement("option"),
el7 = document.createElement("option"),
el8 = document.createElement("option")
];
var initialState = document.getElementById("state").value;
getState(initialState);
function getState(sel) {
//new clear list
for(i=0;i<8;i++){
while (dropdowns[i].firstChild) {
dropdowns[i].removeChild(dropdowns[i].firstChild);
}
defaultOptions[i].textContent = "Select a state above first.";
defaultOptions[i].value = "";
dropdowns[i].appendChild(defaultOptions[i]);
}
if (sel != ""){
var opt;
switch (sel){
case "FL":
//new change "select a state first" to "select a county"
for (i=0;i<8;i++){
dropdowns[i].firstChild.textContent = "- Select a County -";
}
//new create 8 unique options and add them to the selects
for(i=0;i<FLCounties.length;i++){
opt = FLCounties[i];
for (i=0;i<8;i++){
options[i].textContent = opt;
options[i].value = opt;
for(i=0;i<8;i++){
dropdowns[i].appendChild(options[i]);
}
}
}
break;
}
}
}
Am I missing something? This should execute quicker right? Instead its holding the page from loading indefinitely.
Edit: I did find one glaring problem. The dropdowns[i].appendChild(options[i]);
loop should not be in the loop above it. It should run after options has been set.
New snippet:
//new create 8 unique options and add them to the selects
for(i=0;i<FLCounties.length;i++){
opt = FLCounties[i];
for (i=0;i<8;i++){
options[i].textContent = opt;
options[i].value = opt;
}
for(i=0;i<8;i++){
dropdowns[i].appendChild(options[i]);
}
}
Edit 2:
I ran into a problem when taking a step back. It stems from using the array of options in a loop. I knew each option element could only exist in a select once, but didn't follow that logic when writing the loop. The same option element (options[i]) is being changed and reused in each iteration, which wont work, you only get the last iteration's results. I believe this worked in the old code because it redefined the element in each iteration, not just changed it's attributes
Does this rule an array out for this use?
var options = [ el1 = document.createElement("option"),
is probably not doing what you think it is. If you want an associative array aka object or hash:var options = { el1: document.createElement("options"), …
– jacob Dec 19 '13 at 7:10for( var i=1; i<=8; i++ ) dropdowns.push( document.getElementById( 'county' + i ) );
– Ethan Brown Dec 19 '13 at 7:11