Create the init() function. Within this function do the following:
a) Create a variable named allSelect that references all of the selection elements in
the document.
b) For each item within the allSelect object collection, add an onchange event
handler that runs the loadLink() function when the selection list changes.

Create the loadLink() function. The purpose of this function is to cause the browser
to load a URL from a selection list. Add the following commands to the function:
a) Create a variable named sIndex that points to the index of the selected option in
the current selection list. (Hint: Use the this keyword to reference the current
selection list.)
b) Web pages can be loaded using the command
location.href = url;
where url is the URL of theWeb page. Enter this command into the function using the
value of the selected option from the selection list as the value of url. (Hint: Use the
sIndex variable to point to the selected option from the current selection list.)

MY CODE:

window.onload = init;
var allSelect;
var sIndex;

function init() {
   allSelect = document.getElementsByTagName("select");      
   for (var i = 0; i < allselect.length; i++) {
      if (allselect[i].className == "optionLinks") allSelect.push(allSelect[i]);   
             allSelect[i].onchange = loadLink;
      }
   }
function loadLink(siteList) {
   var sIndex = this.id + "optionLinks";
   location.href = siteList.options[sIndex].value;
   }

Recommended Answers

All 9 Replies

javascript is case sensitive. To clarify, var greeting="..."; is different from: var Greeting="..."; In your case you declared and initialized a variable named allSelect (with uppercase "S"), but in the for you are using ... < all[b]s[/b]elect.length (notice the lowercase "s"). The same problem exists in if (all[B]s[/B]elect[i].className

javascript is case sensitive. To clarify, var greeting="..."; is different from: var Greeting="..."; In your case you declared and initialized a variable named allSelect (with uppercase "S"), but in the for you are using ... < all[b]s[/b]elect.length (notice the lowercase "s"). The same problem exists in if (all[B]s[/B]elect[i].className

(my apologies for the double post - I'm having connectivity issues and didn't realize it posted the first time)

Yes, I realized after the posting that I had some syntax/capitalization issues. But even after fixing the typo's I still can not get the links to change when they are selected from the drop down selection list.

In your init() function I don't see the need for allSelect.push(allSelect[i]); . If you have 10 select lists and only three have list of links all these three have class="optionLinks" then yes, I can see/understand why you have the if check/clause. However, the body of the if clause should simply attach the onchange event to the "current" (depending on the iteration) SELECT right away.

if (allselect[i].className == "optionLinks")
{
   allSelect[i].onchange = loadLink;
}

Having said that, here's what's wrong with what you have in init() :


a. the body of your if clause is NOT enclosed in braces. So only the first if statement if executed when the if condition is true. But the statement that follows allSelect[i].onchange = loadLink; will execute for ALL selects. If I am not mistaken, the purpose of the if (allselect[i].className == "optionLinks") statement was to pick and choose specific SELECT list to attach the onchange event to, but that is NOT what you are doing. You are attaching it to EVERY select list in your page. I suspect you had the intention of executing both statements within the if, but forgot to enclose them in braces. This type of mistake is easily avoided if you always put braces around the statements you intend to execute within an if - even it is a single statement.

b. Assuming allSelects currently has:

allSelects[0] ==> <SELECT class="optionLinks" id="Select1">...</SELECT>
allSelects[1] ==> <SELECT class="optionLinks" id="Select5">...</SELECT>
allSelects[2] ==> <SELECT class="optionLinks" id="Select12">...</SELECT>

(where "==>" means "has a reference to") because of that "if" clause that you have, where you are pushing() a SELECT onto allSelects whenever you find a SELECT that has class="optionLinks"

then when the select with id="Select1" is found your array would now be:

allSelects[0] ==> <SELECT class="optionLinks" id="Select1">...</SELECT>
allSelects[1] ==> <SELECT class="optionLinks" id="Select5">...</SELECT>
allSelects[2] ==> <SELECT class="optionLinks" id="Select12">...</SELECT>
allSelects[3] ==> <SELECT class="optionLinks" id="Select1">...</SELECT>

Similarly when it finds the select with id="Select3", your array would then be:

allSelects[0] ==> <SELECT class="optionLinks" id="Select1">...</SELECT>
allSelects[1] ==> <SELECT class="optionLinks" id="Select5">...</SELECT>
allSelects[2] ==> <SELECT class="optionLinks" id="Select12">...</SELECT>
allSelects[3] ==> <SELECT class="optionLinks" id="Select1">...</SELECT>
allSelects[4] ==> <SELECT class="optionLinks" id="Select1">...</SELECT>

Unfortunately for you it will NOT stop checking once it finds id="Select12" because your "for" condition is i < allselect.length Since you have been "re-pushing()" items onto allSelects, the length keeps growing. Initially it was three, but as you push more, the length property keeps incrementing by one on every push. The net effect is that it will never end. What you needed to do was to save the initial length and use that as your stop condition: for( var i=0, limit=allSelects.length; i < limit; ++i){ ... } the value of limit remains three always.

As for the loadLinks() function var sIndex = this.id + "optionLinks"; makes no sense. Given the sample lists I posted above, for the first list sIndex
will end up with "Select1optionLinks"

and your next statement: location.href = siteList.options[sIndex].value is equivalent to: location.href = siteList.options["Select1optionLinks"].value First of all, get rid of siteList. Just use "this" which is a reference to the currently executing select. There's a reason for:

(Hint: Use the this keyword to reference the current
selection list.)

Second, every SELECT should have some <OPTION> elements:

<select class="optionLinks">
<option value="http://www.yahoo.com">Yahoo</option>
<option value="http://www.google.com">Google</option>
</select>

those <OPTION> tags are "attached" to every element/select referenced in each member of allSelects via an options array. To find out which option was selected you need this.selectedIndex NOT whatever this is: var sIndex = this.id + "optionLinks";

function loadLink() {
  var sIndex = this.selectedIndex;
 location.href = siteList.options[sIndex].value;
}

I made a few changes and I am trying to wrap my head around this task....

I am with you on the creating the array allSelect and the numbering (0,1,2,3). I have 4 different selection lists with multiple URL's to select from.

This is my HTML code:

<td><select name="executive" id="executive" class="optionLinks">
      <option value="#">Select a Web site</option>
      <option value="http://www.whitehouse.gov">The White House</option>
        ......14 total urls....

<td><select name="legislative" id="legislative" class="optionLinks">
      <option value="#">Select a Web site</option>
      <option value="http://www.house.gov">House Web Site</option>
      <option value="http://www.house.gov/house/MemberWWW.shtml">Representatives'   
       ......13 total URL's.....

<td><select name="judicial" id="judicial" class="optionLinks">
      <option value="#">Select a Web site</option>
      <option value="http://www.uscourts.gov">U.S. Courts</option>
       ......4 total URL's.....

<td><select name="state" id="state" class="optionLinks">
      <option value="#">Select a Web site</option>
      <option value="http://www.statelocalgov.net/index.cfm">State and Local Government on the Net</option>
      <option value="http://www.loc.gov/global/state/al-gov.html">Alabama</option>
       ......52 total URL's.....

How am I assignning the onchange? My code looks like I am putting it on the allSelect instead of each of the URL's within the lists. I feel so lost right about now. I hate it when I can say what I need to do and cant get it on the paper the right way. I pasted in my code again:

window.onload = init;

  var allSelect = new Array();
  var sIndex;

  function init() {

     allSelect = document.getElementsByTagName("select");

     for (var i = 0; limit = allselect.length; i < limit; ++1) {

        if (allselect[i].className == "optionLinks"){

          allSelect[i].onchange = loadLink;
        }
     }
  }

  function loadLink() {

     var sIndex = this.selectedIndex;
     location.href = siteList.options[sIndex].value;
  }

In the future, please put you wrap your code in CODE tags (look for the word CODE wrapped in square brackets at the top of the editor).

My code looks like I am putting it on the allSelect

Exactly! It IS the SELECT list/element that ACTUALLY changes so it will trigger the onchange event.

... instead of each of the URL's within the lists

You probably meant "instead of each of the OPTION's", but the onchange does NOT go on the OPTION tags. Think about it. When you change from Google to Yahoo, the VALUE of the Google option REMAINS http://www.google.com. You simply selected a new item - Yahoo. So the SELECT now has a value that equals the value of the new selected/chosen item (namely http://yahoo.com).

BTW: on my Nov 12th, 2010, 15:03 post I thought I got rid of siteList everywhere but I missed one: location.href = siteList.options[sIndex].value; should be: location.href = [B]this[/B].options[sIndex].value;

I thank you for all your help and patience. It still has a few hiccups once in a while (depending on the browser) but it does work now. Thank you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.