Dynamic drop down problem

I am trying to create a small drynamic drop down where by selecting an option in one changes the options in the other, I have some code which I thought would work, but somethine is just not quite correct and I can’t figure out what?

Any help would be greatly appreciated!


<form id="selTopic" action="#"method="post">
<h2>Select</h2>
select topic <select name="topic" onchange="setOptions(document.selTopic.topic.options[document.selTopic.topic.selectedIndex].value);">
<option value="" selected="selected">Select topic</option>
<option value="1">Arts</option>
<option value="2">Science</option>
</select>

<select name="subType">
<option value=" " selected="selected">Choose an area</option>
</select>

This is the javascript,


<script type="text/javascript">
 function setOptions(chosen) {
var selbox = document.selTopic.subType;
 
selbox.options.length = 0;
if (chosen == " ") {
  selbox.options[selbox.options.length] = new Option('Please select one of the options above first',' ');
 
}
if (chosen == "1") {
  selbox.options[selbox.options.length] = new Option('Classical','oneClass');
  selbox.options[selbox.options.length] = new Option('Modern','oneMod');
}
if (chosen == "2") {
  selbox.options[selbox.options.length] = new Option('Biology','twoBio');
  selbox.options[selbox.options.length] = new Option('chemistry','twoChem');
}
}
</script>

The function refers to selbox, which is currently undefined.

Try passing the select element to the function instead. You can then crate the chosen variable from the selbox one.


<select name="topic" onchange="setOptions(this);">


function setOptions(selbox) {
    var chosen = selbox.options[document.selTopic.topic.selectedIndex].value
    ...
}

Then, if you wish to earn bonus points, you can then remove the inline javascript event from your HTML completely.

You do that by removing the onchange event from the select element


<select name="topic">

and place a script just before the </body> tag to attaches the onchange event onto the form element.


var form = document.getElementById('selTopic');
form.elements.topic.onchange = setOptions;

Attaching the onchange event in this manner means that the element is accessible as the this keyword from within the attached function.


function setOptions() {
    var selbox = this;
    var chosen = selbox.options[document.selTopic.topic.selectedIndex].value
    ...
}

I edited the code like you suggested and still nothing happens,

the code now reads.


<form id="selTopic" action="#"method="post">
<h2>Select</h2>
select topic <select name="topic" onchange="setOptions(this);">
<option value="" selected="selected">Select topic</option>
<option value="1">Arts</option>
<option value="2">Science</option>
</select>

<select name="subType">
<option value=" " selected="selected">Choose an area</option>
</select>


<script type="text/javascript">
 function setOptions(selbox) {
var chosen = selbox.options[document.selTopic.topic.selectedIndex].value;
var selbox = document.selTopic.subType;

selbox.options.length = 0;
if (chosen == " ") {
  selbox.options[selbox.options.length] = new Option('Please select one of the options above first',' ');

}
if (chosen == "1") {
  selbox.options[selbox.options.length] = new Option('Classical','oneClass');
  selbox.options[selbox.options.length] = new Option('Modern','oneMod');
}
if (chosen == "2") {
  selbox.options[selbox.options.length] = new Option('Biology','twoBio');
  selbox.options[selbox.options.length] = new Option('chemistry','twoChem');
}
}
</script>

Thanks

Here’s how the start of the function should look.


function setOptions(selbox) {
    var chosen = selbox.options[selbox.selectedIndex].value;
    // var selbox ... delete this line

The

that does work in a way and thankyou for that, but when I select an option from that first drop down it then changes the value of that first drop down rather then the second?

i thought perhaps changing the

<select name="topic" onchange="setOptions(this);">

to

<select name="topic" onchange="setOptions(subType);">

might work, however this changes the second drop down but only shows the default option saying, please select one the topics. Is it an error calling the option values to the function?

What needs to occur is for you to become clear about what you want to achieve. Thanks for spelling it out as clearly as you did.

What the script needs to do is to get the chosen option from the first box, and to assign to selbox the second select field.

Leave the HTML code alone, passing only the (this) parameter is exactly what it needs to do.


function setOptions(topic) {
    var chosen = topic.options[topic.selectedIndex].value;
    var selbox = document.selTopic.subType;
    ...
}

If you later feel that you want to pass the second select field for selbox, you can have the onchange event trigger a different function, which then calls the setOptions function. It is not appropriate for the onchange event itself to know about the other fields involved as that interferes with the Law of Demeter or the prinsiple of least knowledge.


<select name="topic" onchange="setTypeOptions(this);">


function setSubtypeOptions(topic) {
    var form = document.getElementById('selTopic');
    var subtype = form.elements.subType;
    return setOptions(topic, subtype);
}
function setOptions(select, selbox) {
    var chosen = select.options[select.selectedIndex].value;
    // var selbox ... now not needed, delete this line
    ...
}

It is not appropriate to

On this bit of code your posted I don’t understand where the selTopic is coming from and what that second line is therefore referring to?


function setOptions(topic) {
    var chosen = topic.options[topic.selectedIndex].value;
    var selbox = document.selTopic.subType;
    ...
}

Thanks for reposting, that code was copy/pasted from your earlier example and I forgot to update that part of it.
The selTopic was a historical refrence to your form via the forms identifier.

The function will have less dependencies when you don’t refer explicitly to externally identified elements.
You can instead , by using the same form that the topic field is in.

Try using this instead, which obtains the selbox implicitly, from the same form that the topic one is in.


function setOptions(topic) {
    var chosen = topic.options[topic.selectedIndex].value;
    var form = topic.form;
    var selbox = form.elements.subType;
    ...
}

The form variable is not mandetory, but it makes the code clearer than when using topic.form.elements.subType - anything that make code clearer is a win in my books.

that works perfectly! thankyou for all your help and helping me understand this