[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 315
  • Last Modified:

3 tier Javascript switch statement madness

Hi -
I need some help making this work correctly.  It's basically a Country, State, City project.

There are 3 drop down (DD) lists; " Networks"(N), "Branches"(B), and "Sections"(S).  When the user selects from the first DD list, the second DD is populated with related options.  When the user then selects from the second DD, the third DD is populated with related options.

Here's a more detailed description -
When the user comes to the page  the first DD says "Select a Network" and the other 2 say "none".  When he selects a Network (N1, N2, or N3) from the first, the 2nd DD changes to say "Select Branch".  The Branches on that list are associated with the  Network  that was selected in the first DD. For example if N3 was selected first, then N3B1, N3B2, N3B3 will appear on the second DD.  After he selects a Branch, the third DD says "Select Section" and the Sections offered are related to the Network and the Branch previously selected.

As you will see if you run the code I've attached, it only sorta, kinda works.  The DD's populate correctly but the options don't  "line up" correctly. For example: If I select Network 1, I get N2 in the second DD, and so on.  

There must be a way to do this.   I'm OK with hard-coding the options - I don't want to use a DB or XML.  Can someone please show me how to get this to work as I have described?

TIA for your help.
d2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script language="javascript">
var i;
function fill_Branches(i){
var form1 = document.getElementById("form1a");
document.form1aa.Branches.options.length=0;
switch(i)
{
case 0:
form1.Branches.options[0] =new Option('Select Branch','Select Branch');
form1.Branches.options[1] =new Option('N1_Branch1','N1, Branch 1');
form1.Branches.options[2] =new Option('N1_Branch2','N1, Branch 2');
form1.Branches.options[3] =new Option('N1_Branch3','N1, Branch 3');
break;
case 1:
form1.Branches.options[0] =new Option('Select Branch','Select Branch');
form1.Branches.options[1] =new Option('N2_Branch1','N2, Branch 1');
form1.Branches.options[2] =new Option('N2_Branch2','N2, Branch 2');
form1.Branches.options[3] =new Option('N2_Branch3','N2, Branch 3');
break;
case 2:
form1.Branches.options[0] =new Option('Select Branch','Select Branch');
form1.Branches.options[1] =new Option('N3_Branch1','N3, Branch 1');
form1.Branches.options[2] =new Option('N3_Branch2','N3, Branch 2');
form1.Branches.options[3] =new Option('N3_Branch3','N3, Branch 3');
}
}
function fill_Sections(i){
var form1 = document.getElementById("form1a");
document.form1aa.Sections.options.length=0;
switch(i)
{
case 0:
form1.Sections.options[0] =new Option('Select Section','Select Section');
form1.Sections.options[1] =new Option('N1B1_Section1','N1B1, Section1');
form1.Sections.options[2] =new Option('N1B1_Section2','N1B1, Section2');
form1.Sections.options[3] =new Option('N1B1_Section3','N1B1, Section3');
form1.Sections.options[4] =new Option('N1B1_Section3','N1B1, Section4');
form1.Sections.options[5] =new Option('N1B1_Section5','N1B1, Section5');
break;
case 1:
form1.Sections.options[0] =new Option('Select Section','Select Section');
form1.Sections.options[1] =new Option('N1B2_Section1','N1B2_Section1');
form1.Sections.options[2] =new Option('N1B2_Section2','N1B2_Section2');
form1.Sections.options[3] =new Option('N1B2_Section3','N1B2_Section3');
break;
case 2:
form1.Sections.options[0] =new Option('Select Section','Select Section');
form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section1');
form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section2');
form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section3');
}
}
</script>
 
</head> 
<body>
  
<form name="form1aa" method="post" action="" id="form1a" >
 
<select name="network" id="network" title="Select a Network" 
onchange=" fill_Branches(document.form1aa.network.selectedIndex);" >
	<option value="N0">Select Network</option>
	<option value="N1">Network1</option>
	<option value="N2">Network2</option>
	<option value="N3">Network3</option>
</select>
 
<br />
 
<select name="Branches" id="Branches" title="Select a Branch"
onchange=" fill_Sections (document.form1aa.Branches.selectedIndex);" >
<option value="noBranch">no branch</option>
</select>
 
<br />
 
<select name="Sections" id="Sections" title="Select a Section">
<option value="noSection">no section</option>
</select>
 
</form>
  
</body>
</html>

Open in new window

0
dzash2000
Asked:
dzash2000
  • 19
  • 16
1 Solution
 
HonorGodCommented:
You were very close...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script type='text/javascript'>
var i;
  function fill_Branches(i){
    var form1 = document.getElementById("form1a");
    document.form1aa.Branches.options.length=0;
    switch( i ) {
      case 0:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N0_Branch1','N0, Branch 1');
        form1.Branches.options[2] =new Option('N0_Branch2','N0, Branch 2');
        form1.Branches.options[3] =new Option('N0_Branch3','N0, Branch 3');
        break;
      case 1:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N1_Branch1','N1, Branch 1');
        form1.Branches.options[2] =new Option('N1_Branch2','N1, Branch 2');
        form1.Branches.options[3] =new Option('N1_Branch3','N1, Branch 3');
        break;
      case 2:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N2_Branch1','N2, Branch 1');
        form1.Branches.options[2] =new Option('N2_Branch2','N2, Branch 2');
        form1.Branches.options[3] =new Option('N2_Branch3','N2, Branch 3');
        break;
      case 3:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N3_Branch1','N3, Branch 1');
        form1.Branches.options[2] =new Option('N3_Branch2','N3, Branch 2');
        form1.Branches.options[3] =new Option('N3_Branch3','N3, Branch 3');
    }
  }
 
  function fill_Sections( i ) {
    var form1 = document.getElementById("form1a");
    document.form1aa.Sections.options.length=0;
    switch(i) {
      case 0:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B1_Section1','N1B1, Section1');
        form1.Sections.options[2] =new Option('N1B1_Section2','N1B1, Section2');
        form1.Sections.options[3] =new Option('N1B1_Section3','N1B1, Section3');
        form1.Sections.options[4] =new Option('N1B1_Section3','N1B1, Section4');
        form1.Sections.options[5] =new Option('N1B1_Section5','N1B1, Section5');
        break;
      case 1:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B2_Section1','N1B2_Section1');
        form1.Sections.options[2] =new Option('N1B2_Section2','N1B2_Section2');
        form1.Sections.options[3] =new Option('N1B2_Section3','N1B2_Section3');
        break;
      case 2:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section1');
        form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section2');
        form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section3');
    }
  }
</script>
 
</head>
<body>
 
<form name="form1aa" method="post" action="" id="form1a" >
 
<select name="network" id="network" title="Select a Network"
onchange=" fill_Branches(document.form1aa.network.selectedIndex);" >
        <option value="N0">Select Network</option>
        <option value="N1">Network1</option>
        <option value="N2">Network2</option>
        <option value="N3">Network3</option>
</select>
 
<br />
 
<select name="Branches" id="Branches" title="Select a Branch"
onchange=" fill_Sections (document.form1aa.Branches.selectedIndex);" >
<option value="noBranch">no branch</option>
</select>
 
<br />
 
<select name="Sections" id="Sections" title="Select a Section">
<option value="noSection">no section</option>
</select>
 
</form>
 
</body>
</html>

Open in new window

0
 
dzash2000Author Commented:
HonorGod -
Thanks for the attempt. The first 2 DDs are cooperating.
But if I select any Branch for any Network - the Section options are 1 digit off.  That means if I select Branch 3 under any Network - the third DD becomes vacant.  Can you help me to get this right?
TIA your assistance and encouragement.
d2
0
 
HonorGodCommented:
You hadn't provided "case 3"...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script type='text/javascript'>
var i;
  function fill_Branches(i){
    var form1 = document.getElementById("form1a");
    document.form1aa.Branches.options.length=0;
    switch( i ) {
      case 0:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N0_Branch1','N0, Branch 1');
        form1.Branches.options[2] =new Option('N0_Branch2','N0, Branch 2');
        form1.Branches.options[3] =new Option('N0_Branch3','N0, Branch 3');
        break;
      case 1:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N1_Branch1','N1, Branch 1');
        form1.Branches.options[2] =new Option('N1_Branch2','N1, Branch 2');
        form1.Branches.options[3] =new Option('N1_Branch3','N1, Branch 3');
        break;
      case 2:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N2_Branch1','N2, Branch 1');
        form1.Branches.options[2] =new Option('N2_Branch2','N2, Branch 2');
        form1.Branches.options[3] =new Option('N2_Branch3','N2, Branch 3');
        break;
      case 3:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N3_Branch1','N3, Branch 1');
        form1.Branches.options[2] =new Option('N3_Branch2','N3, Branch 2');
        form1.Branches.options[3] =new Option('N3_Branch3','N3, Branch 3');
    }
  }
 
  function fill_Sections( i ) {
    var form1 = document.getElementById("form1a");
    document.form1aa.Sections.options.length=0;
    switch( i ) {
      case 0:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B0_Section1','N1B0, Section1');
        form1.Sections.options[2] =new Option('N1B0_Section2','N1B0, Section2');
        form1.Sections.options[3] =new Option('N1B0_Section3','N1B0, Section3');
        form1.Sections.options[4] =new Option('N1B0_Section3','N1B0, Section4');
        form1.Sections.options[5] =new Option('N1B0_Section5','N1B0, Section5');
        break;
      case 1:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B1_Section1','N1B1_Section1');
        form1.Sections.options[2] =new Option('N1B1_Section2','N1B1_Section2');
        form1.Sections.options[3] =new Option('N1B1_Section3','N1B1_Section3');
        break;
      case 2:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B2_Section1','N1B2_Section1');
        form1.Sections.options[2] =new Option('N1B2_Section2','N1B2_Section2');
        form1.Sections.options[3] =new Option('N1B2_Section3','N1B2_Section3');
        break;
      case 3:
        form1.Sections.options[0] =new Option('Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section 1');
        form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section 2');
        form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section 3');
    }
  }
</script>
 
</head>
<body>
 
<form name="form1aa" method="post" action="" id="form1a" >
 
<select name="network" id="network" title="Select a Network"
onchange="fill_Branches(this.selectedIndex);" >
        <option value="N0">Select Network</option>
        <option value="N1">Network1</option>
        <option value="N2">Network2</option>
        <option value="N3">Network3</option>
</select>
 
<br />
 
<select name="Branches" id="Branches" title="Select a Branch"
onchange="fill_Sections(this.selectedIndex);" >
<option value="noBranch">no branch</option>
</select>
 
<br />
 
<select name="Sections" id="Sections" title="Select a Section">
<option value="noSection">no section</option>
</select>
 
</form>
 
</body>
</html>

Open in new window

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
dzash2000Author Commented:
HonorGod -

First, I must apologize.  I thought you had moved on to other questions after your one response to me (this has happened to me a majority of times here at EE).  In my haste I submitted a "request for additional attention".  I hope this doesn't cause you any inconvenience.

Second, thank you for this code and especially the comment.  If I understand you correctly,  I should possibly add a "case" for every possible "B" situation. If I include option[0] in my count, there are 16 possible replies out of  the 4 "fill_Branches" cases.  Does that mean I should have 16 cases under "fill_Sections"?  I will test this assumption.
0
 
HonorGodCommented:
Not at all.  I completely understand.

I try to keep an eye on questions, and drive them to conclusion.

>> I should possibly add a "case" for every possible "B" situation...

  Well, what happens is that when you make a selection (i.e., change the value), the "onchange" event handler gets invoked.

Note: I made a minor change, so that the one for tier 2 is now:

onchange="fill_Sections(this.selectedIndex);"

Which means that the "selectedIndex" value, is what gets passed to the fill_Selections() function.  So, you have to have a case value for each of the option entries specified.

Does this make sense?
0
 
dzash2000Author Commented:
Hi - I made several changes to the code.  

I found I could comment out all but "option[0]" under "fill_Branches" and "fill_Sections" and get correct output when "Select Network" and "Select Branch" are chosen from the DDs.

Testing my previous assumption (which was incorrect), I added up to case 9 under "fill_Sections".  When I selected Network3, then Branch3, I did NOT get case 9 under Section but rather case 4.  That's odd.

In fact, when I select Branch3 under ANY Network - I get case 4 under Section.   Why not case 3??

It seems I still don't understand how this works.

TIA your continued guidance.
d2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script type='text/javascript'>
var i;
  function fill_Branches(i){
    var form1 = document.getElementById("form1a");
    document.form1aa.Branches.options.length=0;
    switch( i ) {
      case 0:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
       // form1.Branches.options[1] =new Option('N0_Branch1','N0, Branch 1');
        //form1.Branches.options[2] =new Option('N0_Branch2','N0, Branch 2');
        //form1.Branches.options[3] =new Option('N0_Branch3','N0, Branch 3');
        break;
      case 1:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N1_Branch1','N1, Branch 1');
        form1.Branches.options[2] =new Option('N1_Branch2','N1, Branch 2');
        form1.Branches.options[3] =new Option('N1_Branch3','N1, Branch 3');
        break;
      case 2:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N2_Branch1','N2, Branch 1');
        form1.Branches.options[2] =new Option('N2_Branch2','N2, Branch 2');
        form1.Branches.options[3] =new Option('N2_Branch3','N2, Branch 3');
        break;
      case 3:
        form1.Branches.options[0] =new Option('Select Branch','Select Branch');
        form1.Branches.options[1] =new Option('N3_Branch1','N3, Branch 1');
        form1.Branches.options[2] =new Option('N3_Branch2','N3, Branch 2');
        form1.Branches.options[3] =new Option('N3_Branch3','N3, Branch 3');
    }
  }
 
  function fill_Sections( i ) {
    var form1 = document.getElementById("form1a");
    document.form1aa.Sections.options.length=0;
    switch( i ) {
      case 0:
        form1.Sections.options[0] =new Option('case 0 Section','Select Section');
       // form1.Sections.options[1] =new Option('N1B0_Section1','N1B0, Section1');
       // form1.Sections.options[2] =new Option('N1B0_Section2','N1B0, Section2');
       // form1.Sections.options[3] =new Option('N1B0_Section3','N1B0, Section3');
        break;
      case 1:
        form1.Sections.options[0] =new Option('case1 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B1_Section1','N1B1_Section1');
        form1.Sections.options[2] =new Option('N1B1_Section2','N1B1_Section2');
        form1.Sections.options[3] =new Option('N1B1_Section3','N1B1_Section3');
        break;
      case 2:
        form1.Sections.options[0] =new Option('case2 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B2_Section1','N1B2_Section1');
        form1.Sections.options[2] =new Option('N1B2_Section2','N1B2_Section2');
        form1.Sections.options[3] =new Option('N1B2_Section3','N1B2_Section3');
        break;
      case 3:
        form1.Sections.options[0] =new Option('case3 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section 1');
        form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section 2');
        form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section 3');
      case 4:
        form1.Sections.options[0] =new Option('case4 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B1_Section1','N2B1_Section1');
        form1.Sections.options[2] =new Option('N2B1_Section2','N2B1_Section2');
        form1.Sections.options[3] =new Option('N2B1_Section3','N2B1_Section3');
        break;
      case 5:
        form1.Sections.options[0] =new Option('case5 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B2_Section1','N2B2_Section1');
        form1.Sections.options[2] =new Option('N2B2_Section2','N2B2_Section2');
        form1.Sections.options[3] =new Option('N2B2_Section3','N2B2_Section3');
        break;
      case 6:
        form1.Sections.options[0] =new Option('case6 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B3_Section1','N2B3_Section 1');
        form1.Sections.options[2] =new Option('N2B3_Section2','N2B3_Section 2');
        form1.Sections.options[3] =new Option('N2B3_Section3','N2B3_Section 3');
      case 7:
        form1.Sections.options[0] =new Option('case7 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B1_Section1','N3B1_Section1');
        form1.Sections.options[2] =new Option('N3B1_Section2','N3B1_Section2');
        form1.Sections.options[3] =new Option('N3B1_Section3','N3B1_Section3');
        break;
      case 8:
        form1.Sections.options[0] =new Option('case8 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B2_Section1','N3B2_Section1');
        form1.Sections.options[2] =new Option('N3B2_Section2','N3B2_Section2');
        form1.Sections.options[3] =new Option('N3B2_Section3','N3B2_Section3');
        break;
      case 9:
        form1.Sections.options[0] =new Option('case9 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B3_Section1','N3B3_Section 1');
        form1.Sections.options[2] =new Option('N3B3_Section2','N3B3_Section 2');
        form1.Sections.options[3] =new Option('N3B3_Section3','N3B3_Section 3');
    }
  }
</script>
 
</head>
<body>
 
<form name="form1aa" method="post" action="" id="form1a" >
<p>Network</p> 
<select name="network" id="network" title="Select a Network"
onchange="fill_Branches(this.selectedIndex);" >
        <option value="N0">Select Network</option>
        <option value="N1">Network1</option>
        <option value="N2">Network2</option>
        <option value="N3">Network3</option>
</select>
 
<br />
<p>Branch</p> 
<select name="Branches" id="Branches" title="Select a Branch"
onchange="fill_Sections(this.selectedIndex);" >
<option value="noBranch">no branch</option>
</select>
 
<br />
<p>Section</p> 
<select name="Sections" id="Sections" title="Select a Section">
<option value="noSection">no section</option>
</select>
 
</form>
 
</body>
</html>

Open in new window

0
 
HonorGodCommented:
Alright, let's start at the top, and work our way down...

Line 7 is not needed.  You declare i as a global variable, but never use it.

In line 8, by declaring i as a formal parameter to the function, you are, in fact, declaring i as local to the function.

Line 9, isn't really necessary because you never use this object to refer to any element on the document.

Line 10 uses the syntax:
  document. <formName> . <elementName> .options.length = 0 to set the specified SELECT element length to zero, and thus discard any existing options.

  You could, in effect, combine lines 9 & 10 by using the "document.getElementById()" to locate the select element directly.  For example:

  var sel = document.getElementById( "Branches" )
  sel.options.length = 0

  The problem that I have with this is the fact that this sequence of statements doesn't include any error checking.  What happens if, for some reason, the HTML gets changes, and the SELECT statement identified by that particular id attribute no longer exists?  If so, then the value returned by the getElementById() function will be null.  That is why I much prefer code like:

  var sel = document.getElementById( "Branches" )
  if ( sel ) {
    sel.options.length = 0
    ...
  } else {
    alert( 'Specified selection element not found. id="' + id + '"' )
  }

Lines 11-35 use a switch statement to determine how to populate a specific Select statement based upon the user specified selection.

ok, now we get back to your question:

>> In fact, when I select Branch3 under ANY Network - I get case 4 under Section.   Why not case 3??

Let's take a close look at "case 3", what do we find:

If you look really closely, you will see that you don't "end" case 3 using a "break" statement.  So, execution continues with those statements after "case 4"...  and all the stuff you did in "case 3" gets lost.
   
      case 3:
        form1.Sections.options[0] =new Option('case3 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section 1');
        form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section 2');
        form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section 3');
      case 4:
        form1.Sections.options[0] =new Option('case4 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B1_Section1','N2B1_Section1');
        form1.Sections.options[2] =new Option('N2B1_Section2','N2B1_Section2');
        form1.Sections.options[3] =new Option('N2B1_Section3','N2B1_Section3');
        break;

Open in new window

0
 
dzash2000Author Commented:
Hi -  Thanks for that explanation.
 
I commented out line 7, and as you predictd nothing changed.  
I added the break statements and when I select Branch 3 under ANY Network - I get case 3.  THAT's an improvement.

Now to the last part of my question  -  how do I get the correct Section options with ANY Branch under Networks 2 & 3?   Right now I'm getting case 1, 2 or 3 when the correct information is in cases 4 to 9.
For example; Network 2, Branch 2 still yields N1B2 options when I'd like to get N2B2 options.
I started out thinking this problem had a simple answer that just required a lot of repetitious coding.

Thanks again for your continuing help.
d2
0
 
HonorGodCommented:
In order to have the correct "Section" options displayed, the Branch drop down must be populated correctly.

Here is a revised page that uses the information in a data structure (which happens to be a dictionary) to populate the Branches Drop Down.

See if it makes sense to you, and if you can extrapolate it to do what you are trying to do.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script type='text/javascript'>
  var BranchOptions = {
    0 : [ 'Select Branch' ],
    1 : 'N1, Branch 1;N1, Branch 2;N1, Branch 3'.split( ';' ),
    2 : 'N2, Branch 1;N2, Branch 2;N2, Branch 3'.split( ';' ),
    3 : 'N3, Branch 1;N3, Branch 2;N3, Branch 3'.split( ';' )
  }
 
  function field( id ) {
    var ele = document.getElementById( id )
    if ( !ele ) {
      alert( 'Specified element not found. id="' + id + '"' )
    }
    return ele
  }
 
  function fill_Branches( i ) {
    var sel = field( 'Branches' )
    if ( sel  ) {
      if ( i in BranchOptions ) {
        sel.options.length = 0
        var BO = BranchOptions[ i ]
        for ( var j = 0; j < BO.length; j++ ) {
          sel.options[ j ] = new Option( BO[ j ] )
        }
      } else {
        alert( 'fill_Branches(): Invalid selection made: ' + i )
      }
    }
  }
 
  function fill_Sections( i ) {
    var form1 = document.getElementById("form1a");
    document.form1aa.Sections.options.length=0;
    alert( 'fill_Sections(' + i + ')' )
    switch( i ) {
      case 0:
        form1.Sections.options[0] =new Option('case 0 Section','Select Section');
       // form1.Sections.options[1] =new Option('N1B0_Section1','N1B0, Section1');
       // form1.Sections.options[2] =new Option('N1B0_Section2','N1B0, Section2');
       // form1.Sections.options[3] =new Option('N1B0_Section3','N1B0, Section3');
        break;
      case 1:
        form1.Sections.options[0] =new Option('case1 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B1_Section1','N1B1_Section1');
        form1.Sections.options[2] =new Option('N1B1_Section2','N1B1_Section2');
        form1.Sections.options[3] =new Option('N1B1_Section3','N1B1_Section3');
        break;
      case 2:
        form1.Sections.options[0] =new Option('case2 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B2_Section1','N1B2_Section1');
        form1.Sections.options[2] =new Option('N1B2_Section2','N1B2_Section2');
        form1.Sections.options[3] =new Option('N1B2_Section3','N1B2_Section3');
        break;
      case 3:
        form1.Sections.options[0] =new Option('case3 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section 1');
        form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section 2');
        form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section 3');
        break;
      case 4:
        form1.Sections.options[0] =new Option('case4 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B1_Section1','N2B1_Section1');
        form1.Sections.options[2] =new Option('N2B1_Section2','N2B1_Section2');
        form1.Sections.options[3] =new Option('N2B1_Section3','N2B1_Section3');
        break;
      case 5:
        form1.Sections.options[0] =new Option('case5 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B2_Section1','N2B2_Section1');
        form1.Sections.options[2] =new Option('N2B2_Section2','N2B2_Section2');
        form1.Sections.options[3] =new Option('N2B2_Section3','N2B2_Section3');
        break;
      case 6:
        form1.Sections.options[0] =new Option('case6 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B3_Section1','N2B3_Section 1');
        form1.Sections.options[2] =new Option('N2B3_Section2','N2B3_Section 2');
        form1.Sections.options[3] =new Option('N2B3_Section3','N2B3_Section 3');
      case 7:
        form1.Sections.options[0] =new Option('case7 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B1_Section1','N3B1_Section1');
        form1.Sections.options[2] =new Option('N3B1_Section2','N3B1_Section2');
        form1.Sections.options[3] =new Option('N3B1_Section3','N3B1_Section3');
        break;
      case 8:
        form1.Sections.options[0] =new Option('case8 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B2_Section1','N3B2_Section1');
        form1.Sections.options[2] =new Option('N3B2_Section2','N3B2_Section2');
        form1.Sections.options[3] =new Option('N3B2_Section3','N3B2_Section3');
        break;
      case 9:
        form1.Sections.options[0] =new Option('case9 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B3_Section1','N3B3_Section 1');
        form1.Sections.options[2] =new Option('N3B3_Section2','N3B3_Section 2');
        form1.Sections.options[3] =new Option('N3B3_Section3','N3B3_Section 3');
    }
  }
</script>
 
</head>
<body>
 
<form name="form1aa" method="post" action="" id="form1a" >
<p>Network</p>
<select name="network" id="network" title="Select a Network"
onchange="fill_Branches(this.selectedIndex);" >
        <option value="N0">Select Network</option>
        <option value="N1">Network1</option>
        <option value="N2">Network2</option>
        <option value="N3">Network3</option>
</select>
 
<br />
<p>Branch</p>
<select name="Branches" id="Branches" title="Select a Branch"
onchange="fill_Sections(this.selectedIndex);" >
<option value="noBranch">no branch</option>
</select>
 
<br />
<p>Section</p>
<select name="Sections" id="Sections" title="Select a Section">
<option value="noSection">no section</option>
</select>
 
</form>
 
</body>
</html>

Open in new window

0
 
dzash2000Author Commented:
HonorGod - This is mostly strange to me.  I'll have to stare at it for a few hours and get back to you.
d2
0
 
HonorGodCommented:
That's alright.  When you encounter something strange, and/or confusing, let me know.

Here is a modified version.  I left the "Select Branch" (i.e., Option 0) off the data used to populate the Branches select statement.  Sorry about that.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script type='text/javascript'>
  var BranchOptions = {
    0 : [ 'Select Branch' ],
    1 : 'Select Branch;N1, Branch 1;N1, Branch 2;N1, Branch 3'.split( ';' ),
    2 : 'Select Branch;N2, Branch 1;N2, Branch 2;N2, Branch 3'.split( ';' ),
    3 : 'Select Branch;N3, Branch 1;N3, Branch 2;N3, Branch 3'.split( ';' )
  }
 
  function field( id ) {
    var ele = document.getElementById( id )
    if ( !ele ) {
      alert( 'Specified element not found. id="' + id + '"' )
    }
    return ele
  }
 
  function fill_Branches( i ) {
    alert( 'fill_Branches( ' + i + ' )' )
    var sel = field( 'Branches' )
    if ( sel  ) {
      if ( i in BranchOptions ) {
        sel.options.length = 0
        var BO = BranchOptions[ i ]
        for ( var j = 0; j < BO.length; j++ ) {
          sel.options[ j ] = new Option( BO[ j ] )
        }
      } else {
        alert( 'fill_Branches(): Invalid selection made: ' + i )
      }
    }
  }
 
  function fill_Sections( i ) {
    alert( 'fill_Sections( ' + i + ' )' )
    var form1 = document.getElementById("form1a");
    document.form1aa.Sections.options.length=0;
    switch( i ) {
      case 0:
        form1.Sections.options[0] =new Option('case 0 Section','Select Section');
       // form1.Sections.options[1] =new Option('N1B0_Section1','N1B0, Section1');
       // form1.Sections.options[2] =new Option('N1B0_Section2','N1B0, Section2');
       // form1.Sections.options[3] =new Option('N1B0_Section3','N1B0, Section3');
        break;
      case 1:
        form1.Sections.options[0] =new Option('case1 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B1_Section1','N1B1_Section1');
        form1.Sections.options[2] =new Option('N1B1_Section2','N1B1_Section2');
        form1.Sections.options[3] =new Option('N1B1_Section3','N1B1_Section3');
        break;
      case 2:
        form1.Sections.options[0] =new Option('case2 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B2_Section1','N1B2_Section1');
        form1.Sections.options[2] =new Option('N1B2_Section2','N1B2_Section2');
        form1.Sections.options[3] =new Option('N1B2_Section3','N1B2_Section3');
        break;
      case 3:
        form1.Sections.options[0] =new Option('case3 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N1B3_Section1','N1B3_Section 1');
        form1.Sections.options[2] =new Option('N1B3_Section2','N1B3_Section 2');
        form1.Sections.options[3] =new Option('N1B3_Section3','N1B3_Section 3');
        break;
      case 4:
        form1.Sections.options[0] =new Option('case4 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B1_Section1','N2B1_Section1');
        form1.Sections.options[2] =new Option('N2B1_Section2','N2B1_Section2');
        form1.Sections.options[3] =new Option('N2B1_Section3','N2B1_Section3');
        break;
      case 5:
        form1.Sections.options[0] =new Option('case5 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B2_Section1','N2B2_Section1');
        form1.Sections.options[2] =new Option('N2B2_Section2','N2B2_Section2');
        form1.Sections.options[3] =new Option('N2B2_Section3','N2B2_Section3');
        break;
      case 6:
        form1.Sections.options[0] =new Option('case6 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N2B3_Section1','N2B3_Section 1');
        form1.Sections.options[2] =new Option('N2B3_Section2','N2B3_Section 2');
        form1.Sections.options[3] =new Option('N2B3_Section3','N2B3_Section 3');
      case 7:
        form1.Sections.options[0] =new Option('case7 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B1_Section1','N3B1_Section1');
        form1.Sections.options[2] =new Option('N3B1_Section2','N3B1_Section2');
        form1.Sections.options[3] =new Option('N3B1_Section3','N3B1_Section3');
        break;
      case 8:
        form1.Sections.options[0] =new Option('case8 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B2_Section1','N3B2_Section1');
        form1.Sections.options[2] =new Option('N3B2_Section2','N3B2_Section2');
        form1.Sections.options[3] =new Option('N3B2_Section3','N3B2_Section3');
        break;
      case 9:
        form1.Sections.options[0] =new Option('case9 Select Section','Select Section');
        form1.Sections.options[1] =new Option('N3B3_Section1','N3B3_Section 1');
        form1.Sections.options[2] =new Option('N3B3_Section2','N3B3_Section 2');
        form1.Sections.options[3] =new Option('N3B3_Section3','N3B3_Section 3');
    }
  }
</script>
 
</head>
<body>
 
<form name="form1aa" method="post" action="" id="form1a" >
<p>Network</p>
<select name="network" id="network" title="Select a Network"
onchange="fill_Branches(this.selectedIndex);" >
        <option value="N0">Select Network</option>
        <option value="N1">Network1</option>
        <option value="N2">Network2</option>
        <option value="N3">Network3</option>
</select>
 
<br />
<p>Branch</p>
<select name="Branches" id="Branches" title="Select a Branch"
onchange="fill_Sections(this.selectedIndex);" >
<option value="noBranch">no branch</option>
</select>
 
<br />
<p>Section</p>
<select name="Sections" id="Sections" title="Select a Section">
<option value="noSection">no section</option>
</select>
 
</form>
 
</body>
</html>

Open in new window

0
 
dzash2000Author Commented:
I see the split function somehow replaces the second select list html.  I don't understand why the alert messages are valuable or what purposes the if/else statements serve.  Most importantly, the third DD (Sections) is STILL not showing the correct information when any Branch is selected under Networks 2 or 3.  I don't understand how any of these scripted enhancements are leading me to reach that goal.  This is all over my head.  Thanks anyway.

0
 
HonorGodCommented:
The split takes the text string, and separates it into a list at the semi-colon.
This makes the syntax simpler.  Which is easier for you to type, and understand?  This:

'Select Branch;N1, Branch 1;N1, Branch 2;N1, Branch 3'.split( ';' ),

or this?

[ 'Select Branch', 'N1, Branch 1', 'N1, Branch 2', 'N1, Branch 3' ],

They result in identical array values.

The field function is useful for those situations when you are developing a page, and would like to know when you try to access a field on the page using its id attribute, and that field, or element doesn't exist.

The alert messages within the "fill" functions show:
- Which function is being invoked, and with what value

>> Most importantly, the third DD (Sections) is STILL not showing the correct
>> information when any Branch is selected under Networks 2 or 3.

In order to understand why the Sections DD doesn't get populated correctly, we need to investigate how, and why they get populated.  Then, we need to understand how to populate the Branches DD so that when a Branches selection is made the appropriate Sections call will be made to populate the Sections DD with the right values.

Does this make sense?

Maybe a detailed example would help.

To begin, the "Branches" and "Section" DD's are essentially empty.
When a "Network" selection is made, the "fill_Branches()" function is called with a value of 1, 2, or 3.

After displaying the alert dialog box with the name of the routine called, and the parameter value specified, an attempt is make to locate the HTML document with the id attribute of 'Branches'.  It is found, and a reference to it is assigned to the variable named sel.  So far, so good. Then, the parameter value i is used to see if a key of that value exists in the BranchOptions object.
Since it does, it is used to populate the Branches DD list.

Does that make sense?
0
 
dzash2000Author Commented:
Let me see if I follow...

>>Which is easier for you to type, and understand?  
I would say...
[ 'Select Branch', 'N1, Branch 1', 'N1, Branch 2', 'N1, Branch 3' ]

function fill_Branches( i ) {    
// I know that the "i" stands for "this.selectedIndex" down on the onchange event
//    but I don't know why "i" is used.  But I don't see where "i" is declared or defined as such.  
//    Is this one of those "reserved" javascript conventions or would "z" work just as well?  



    alert( 'fill_Branches( ' + i + ' )' )  // this is really a disposable alert
    var sel = field( 'Branches' )  // variable called "sel" is the field* with the id 'Branches'

//  *Is the use of the word "field" here the same field in the field function established earlier??
//  What I mean is - could this variable "sel" be established as the "field called Branches"
//     without the earlier statement "function field(id)" ?
// (I get confused between terms used by Javascript with strict definitions,
//     and terms defined by you - the programmer ).



//  This next section bounces around in my brain but doesn't settle anywhere
// the function fill_Branches will fire if sel  (the field with the id "Branches")... end of understanding.
    if ( sel  ) {
      if ( i in BranchOptions )
{  // is "in" a technical Javascript term?
        sel.options.length = 0  //  I think this just zeros out Branches option's numbering
        var BO = BranchOptions[ i ]
        for ( var j = 0; j < BO.length; j++ ) {
          sel.options[ j ] = new Option( BO[ j ] )
        }



      } else {  //give alert with the i from the Branches list? or Network list?
        alert( 'fill_Branches(): Invalid selection made: ' + i )
      }
    }
  } // end of function fill_Branches


0
 
HonorGodCommented:
If this is easier for you to understand, then use it, instead of the one I used.

[ 'Select Branch', 'N1, Branch 1', 'N1, Branch 2', 'N1, Branch 3' ]

I find it harder to type because of the ', ' sequence between each entry.
But it is your document, and you have to be comfortable with it.

> But I don't see where "i" is declared or defined as such.

Ah!  This is part of many programming languages. The fact that "i" is part of the function signature, i.e.,

function fill_Branches( i ) {

Means that it is defined!  And that for the scope of the function, i is a local variable, just as though you had used something like this:

function fill_Branches() {
  var i = arguments[ 0 ]
  ...
}

You may not know that "arguments" is also part of JavaScript, and can be used to access parameters used when the function was called, and for which parameters have not been included in the function signature.

>> Is this one of those "reserved" javascript conventions or would "z" work just as well?  

You can put whatever variable names that you want in the function signature.
It could just as easily have been:

function fill_Branches( z ) {
  ...
}

If you had though, you would have had to use z instead of i within the function body.

>> alert( 'fill_Branches( ' + i + ' )' )  // this is really a disposable alert

  Absolutely!

>> var sel = field( 'Branches' )  // variable called "sel" is the field* with the id 'Branches'

  Not quite.  field is a function that expects an id attribute to be passed.
It uses this id to perform a document.getElementById() to try and locate a document element that has this id attribute.  If, by chance, none is found, an alert dialog box will be displayed that tells you that no document element was found with the specified id.

  Since your document does contain an element that has the id "Branches", the result of this call is that the variable sel will be a reference to this document element.

>> /  *Is the use of the word "field" here the same field in the field function established earlier??

Yes!

>> I get confused between terms used by Javascript with
>>  strict definitions, and terms defined by you - the programmer.

I understand.  That is part of the challenge of learning a programming language. Trying to figure out what is part of the language itself, and what you, or some other programmer my write that, in essence, extends the language.  That's what user defined functions are all about. Designing, implementing, and testing things (like commands) that aren't part of the language already, that you find useful to do what you need to do.

----------------------------------------------------------------------
// This next section bounces around in my brain but doesn't settle anywhere
// the function fill_Branches will fire if sel  (the field with the id "Branches")...
// end of understanding.
----------------------------------------------------------------------

Understood.  That's why this (experts-exchange) is such a good place.
You can ask questions, and hopefully get answers that are easy for you
to understand.

The "if" statement (line 4, below) is used to check that the variable sel has a valid value.  If the specified document element isn't found, then the value of sel will be null.  So, the test performed by the "if" will fail, and any "else" clause would be executed.  Since no "else" clause exists for this "outer if", the "then" clause would be skipped.

But only if sel has a null value!

Now, if "sel" is valid (i.e., a document element exists), then the value in i may be a reasonable, and valid valid.  We don't know, at least not yet.  That is why we have the "inner if" (i.e., "if ( i in BranchOptions ) {").

This takes the value of i and checks to see if the variable BranchOptions has an index, or key, that corresponds to this value.  If we look back at http://#a24160720, on lines 7-12, we see that the only valid index, or key values for BranchOptions are 0, 1, 2, and 3.  If the value passed to this function happens to be anything else, the "else" clause for this "inner if" will be executed, and we will see the "Invalid selection made" alert.

If the value is 0, 1, 2, or 3, we start executing at line 6, below. i.e., the:

sel.options.length = 0

Since "sel" contains a reference to the "SELECT" statement, we can use it like this to set the number of options to 0 (thus emptying the DD list)
This statement lets us reference individual values within the particular BranchOptions value referenced by the specified value of i:

var BO = BranchOptions[ i ]

So, we can easily find the number of list elements using: BO.length, and access individual list elements using: BO[ j ].

ok, no we can get back to the question you asked a bit ago.  Why doesn't the Section DD get populated with any of the entries from 4 .. 9?

The answer should be easily understood if you take a look at how the fill_Section() function.  What values can get passed to it, and how?

The answer is that the number passed to the fill_Section() function is based upon the entry number from a given Branch value.  So, since each of your Branch() listings is only 4 entries long (i.e., values from 0..3), these are the only ones that can get passed to the fill_Section() function.  If you want to have values from 4..9 displayed, make one of the Branches lists (in the BranchOptions) longer!

Does this help?
  function fill_Branches( i ) {
    alert( 'fill_Branches( ' + i + ' )' )
    var sel = field( 'Branches' )
    if ( sel  ) {
      if ( i in BranchOptions ) {
        sel.options.length = 0
        var BO = BranchOptions[ i ]
        for ( var j = 0; j < BO.length; j++ ) {
          sel.options[ j ] = new Option( BO[ j ] )
        }
      } else {
        alert( 'fill_Branches(): Invalid selection made: ' + i )
      }
    }
  }

Open in new window

0
 
dzash2000Author Commented:
Boing!! (My eyes popping out)  

Your explanation is great and I've been pouring over it line by line to grasp each concept in turn.  
I SHOULD have read the whole thing to realize that we're NOT SOLVING THE SAME PROBLEM!

>> If you want to have values from 4...9 displayed, make one of the Branches lists
>>(in the BranchOptions) longer!

But that is not what I'm looking for!

I know why this happened.  The coding for the select lists are too symmetrical looking and their uniqueness is hidden.  I SHOULD have asked this with Countries, States and Cities instead of Networks, Branches and Sections because then the picture would have been clearer.  Visualize that the data builds a pyramid-type shape with Networks at the top and Sections at the bottom.

(for now I'm ignoring all "Sections.options[0]" to make adding up the Sections.options clearer.)

Network 1 has 3 Branches. Each of those 3 Branches has 3 unique Sections. (9 Sections total)
Network 2 has 3 different Branches and each of those has 3 unique sections.(add in 9 more Sections)
Network 3 and it's 3 Branches work the same way (...for a grand total of 27 unique Sections)

I don't need Network1Branch3, for example, to access cases 4...9.  I need to access Section cases 4...9 from Branches OTHER than N1B1, N1B2 & N1B3.  (Access is not the perfect word. I hope you get my point anyway.)

For example:
N2B2 should access case 5.
N3B1 should access case 7.

Have we been going down different roads?

Aside from that, your explanations have cleared up many of the confusions about fundamental programming and JS and I am truly appreciative.  I'm a big fan of forums in general.  And EE seems to run smoothly.  But people like you sir, are the reason I will join up and come back.






0
 
HonorGodCommented:
>> Visualize that the data builds a pyramid-type shape with Networks at the top and Sections at the bottom.

Sorry, no can do.  I don't visualize.  At all, ever.  I don't think in pictures.
Many people do, I don't.

However, as to the point you finally realized, I knew that, and was wondering when we were going to get to that... :-)

I know that the Sections should be unique.  Unfortunately, the way you had things coded, it was going to take some time to get your head around the difference in hard coding the DD option lists using case statements, and actually having, or using unique option lists.

So, have we been going down different roads?  Not really.  We traveled down some twisted back roads for a little bit, and now it would seem that we are actually going in the right direction. ;-)

So how do we go from here?

Describe actual data for your DD lists.  It doesn't have to be the whole thing, just enough to differentiate between the different tiers.  Then, given this data, we can discuss how best to represent, and populate the DD lists using this data.

Hopefully that helps, and makes sense.

By the way, thanks for the kind words.  That's why I like using EE.  I like to share knowledge.
0
 
dzash2000Author Commented:
Hi -
I do not have the actual data.  

I am building an html/css/javascript demo to show how a user will be able to "drill down" from the general location of a Network (a large area, square miles of land), down thru a Branch to the more specific location of a Section (an area of land of a few hundred square yards) by using DD lists.  My goal is to show the interface - not necessarily with any actual data.

If I cannot script this to work correctly - having the selected options from on DD populate the next - I will merely fake it for the demo.  From our exchanges I was getting confident that the real solution was possible and I was eager to learn something.

I purposely started this exchange stating that I did not want to use a database or XML.
I just wanted to hard code the entire demo with "dummy" data.  I thought it possible.  I actually thought it would be simple.

Do you believe there is no way to accomplish this within these guidelines?

j2
0
 
dzash2000Author Commented:
I'm trying to answer your request to describe the actual data.
All Networks, Branches and Section have names, IDs, locations and measurements.  To differentiate I can exaggerate by stating that Networks are measured in sq miles, Branches are measured in sq feet and Sections in sq inches.  The other catagories (names, IDs, location) are really somewhat similar.

I hope this is helpful.

j2
0
 
HonorGodCommented:
>> From our exchanges I was getting confident that the real solution was possible and I was eager to learn something.

Excellent.

>> Do you believe there is no way to accomplish this within these guidelines?

Not at all.  Let's use the scenario that you described earlier for which it is easy to "make up" data.

Instead of Networks, Branches, and Sections, let's use Countries, States and Cities.  We don't even have to use lots of data, just enough to show how things can work.

There are some important things to understand though.

1. What is the relationship between the data?
2. How do we use the data that we have to populate a drop down list?

We have been covering #2 quite thoroughly up to this point. The thing that will help tie this all together is some data structure that can be used to represent the data, and the relationship between the different parts.

Lets start with a diagram:

Countries
- Country #1
- Country #2
- Country #3
...

States
- State #1
- State #2
- State #3
...

Cities
- City #1
- City #2
- City #3
...

This is basically what you started with.  What's the problem with this?

The problem is that for each Country there are a collection of States, and for each State, there are a collection of Cities.  A slightly different, though familiar way to represent this is shown below:

Does this make sense?
+-- Country #1
|   |
|   +-- State #1
|   |   |
|   |   +-- City #11
|   |   |
|   |   +-- City #12
|   |   |
|   |   +-- City #13
|   |   |
|   |   +-- ...
|   |    
|   +-- State #2
|   |   |
|   |   +-- City #21
|   |   |
|   |   +-- City #22
|   |   |
|   |   +-- City #23
|   |   |
|   |   +-- ...
|   |    
|   +-- State #3
|   |   |
|   |   +-- City #31
|   |   |
|   |   +-- City #32
|   |   |
|   |   +-- City #33
|   |   |
|   |   +-- ...
|   |    

Open in new window

0
 
HonorGodCommented:
One way to deal with this is to use something like you have done with the fill_*() routines.  That is, to pass a value, and use that value in a switch statement to populate the DD list.

What are the pro's and con's of this approach?

Con:
- It's very verbose. Each DD option needs to have a line something like:
  form1.Sections.options[0] =new Option('case1 Select Section','Select Section');
- It takes a lot of typing...
- It's manually intensive. If you decide to add or remove entries, you have to remember to adjust the options index value yourself.
- Its' easy to make a mistake.  Remember what happened when you left off the "break" statement?

Pro:
- It's pretty straight forward, and relatively easy to understand.

What about the approach shown in http://#a24169409?

Con:
- The code requires more understanding
- If the data is messed up, the lists won't get displayed correctly
- Building the data structure(s) might be a bit more complex

Pro:
- Very little additional typing is required over the specification of the data

Which approach do you prefer?
0
 
dzash2000Author Commented:
Hi -
>>Which approach do you prefer?
I have been reviewing all of the "lessons"  - especially from 24169409 - and the concepts and relevance of them are not much clearer.  For that reason I think I would be better off using the method I started with...
>>That is, to pass a value, and use that value in a switch statement to populate the DD list.
I think, because of the repetitious nature of the code, I might be able to troubleshoot it myself better because it seems more elementary.  I may also be able to build on it's simplicity easier (there are a few other things I want to show in my demo with the data).

Using the other method is such that I would be "without a clue" for a longer time.

That's my take.  Lead on.

0
 
HonorGodCommented:
ok, Let's start with the 3rd tier, and work our way up.

When the user makes a selection on the Section DD list, what kind of value do you want it to be?  An integer, or the text of the DD entry, or something else?

Using the diagram in http://#a24179005 above, for example, it makes sense to either use the city number (e.g., 11, 12, 13, etc), or the city name (whatever it might be).

Given a trivial "select" statement like this:

<select id='here' onchange='picked(this)''>
  <option value='0'>Pick...</option>
  <option value='11'>City #11</option>
</select>

and the associated "picked()" function like this:

function picked( sel ) {
  var sI   = sel.selectedIndex
  var val = sel.options[ sel.selectedIndex ].value
  alert( 'Selected value: ' + val )
}

What do you think would be displayed when "City #11" is selected?
The displayed value would be 11, not the text associated with the option.
So, if you would prefer the text "City #11" to be returned then the easiest way would be to have to option value be the same as the option text.

So, how do we dynamically populate the DD list to contain exactly this kind of list?  Well, your earlier code shows that you know how to do this.  For example:

var sel = form1.Sections
sel.options.length = 0
sel.options[ 0 ] = new Option( 'Pick...' )
sel.options[ 1 ] = new Option( 'City #11' )

Using code like this to populate the DD, the output of the picked() function would be "City #11".  However, if we would prefer to have the numeric value of 11 returned, we would use something like:

var sel = form1.Sections
sel.options.length = 0
sel.options[ 0 ] = new Option( 'Pick...', 0 )
sel.options[ 1 ] = new Option( 'City #11', 11 )

Ok, so far, so good. this means that our code for the different cities (sections) for a specific state (branch) would look something like the code below.

Next, we'll talk about how to have the higher level DD populated so that the proper information passed to the fill_Sections() function.


  function fill_Sections( i ) {
    var form1 = document.getElementById( 'form1a' )
    form1.options.length = 0
    switch( i ) {
      case 0:
        form1.options[ 0 ] = new Option( 'case 0 Section')
        break
          
      case 11:
        form1.options[ 0 ] = new Option( 'case 11 Select Section')
        form1.options[ 1 ] = new Option( 'N1B1_Section1' )
        form1.options[ 2 ] = new Option( 'N1B1_Section2' )
        form1.options[ 3 ] = new Option( 'N1B1_Section3' )
        break
 
      case 12:
        form1.options[ 0 ] = new Option( 'case 12 Select Section' )
        form1.options[ 1 ] = new Option( 'N1B2_Section1' )
        form1.options[ 2 ] = new Option( 'N1B2_Section2' )
        form1.options[ 3 ] = new Option( 'N1B2_Section3' )
        break
 
      case 13:
        form1.options[ 0 ] = new Option( 'case 13 Select Section' )
        form1.options[ 1 ] = new Option( 'N1B3_Section1' )
        form1.options[ 2 ] = new Option( 'N1B3_Section2' )
        form1.options[ 3 ] = new Option( 'N1B3_Section3' )
        break
...       
      default:
        alert( 'fill_Section(): invalid/unexpected value specified: ' + i )
    }
  }

Open in new window

0
 
HonorGodCommented:
One thing that I just noticed, and thought about was the fact that the only part of the select object being used by the fill_Sections() function is the options attribute.

So, let's do a minor revision first...

How does this look to you?
  function fill_Sections( i ) {
    var form1 = document.getElementById( 'form1a' )
    if( form1 ) {
      var opts = form1.options
      opts.length = 0
      switch( i ) {
        case 0:
          opts[ 0 ] = new Option( 'case 0 Section')
          break
            
        case 11:
          opts[ 0 ] = new Option( 'case 11 Select Section')
          opts[ 1 ] = new Option( 'N1B1_Section1' )
          opts[ 2 ] = new Option( 'N1B1_Section2' )
          opts[ 3 ] = new Option( 'N1B1_Section3' )
          break
 
        case 12:
          opts[ 0 ] = new Option( 'case 12 Select Section' )
          opts[ 1 ] = new Option( 'N1B2_Section1' )
          opts[ 2 ] = new Option( 'N1B2_Section2' )
          opts[ 3 ] = new Option( 'N1B2_Section3' )
          break
 
        case 13:
          opts[ 0 ] = new Option( 'case 13 Select Section' )
          opts[ 1 ] = new Option( 'N1B3_Section1' )
          opts[ 2 ] = new Option( 'N1B3_Section2' )
          opts[ 3 ] = new Option( 'N1B3_Section3' )
          break
...         
        default:
          alert( 'fill_Section(): invalid/unexpected value specified: ' + i )
      }
    } else {
      alert( 'fill_Section(): Specified element not found. id="form1a".' )
    }
  }

Open in new window

0
 
HonorGodCommented:
In order for this to work, we need the Branches DD list to provide the proper/appropriate value for each Section.  So, to do this, we need to correlate the Section option number (e.g., 11, 12, 13, 21, 22, 23) with the corresponding Branch, and build the Branch option accordingly.

Given branches DD list population, how do we use it?

The answer is that the code called when the Branches DD selection list is changed needs to access the numeric value, and pass it to the fill_Section() routine()!

Do you want me to show that, or do you want to work on it yourself?


case 11:
  opts[ 0 ] = new Option( 'Branch 1 Pick...')
  opts[ 1 ] = new Option( 'N1B1_Section1', 11 )
  opts[ 2 ] = new Option( 'N1B1_Section2', 12 )
  opts[ 3 ] = new Option( 'N1B1_Section3', 13 )
  break

Open in new window

0
 
dzash2000Author Commented:
HonorGod-
I haven't abandoned this but I'm being reassigned for a few days... another website... new issues.  I hope we can pick this up next week.  Either way - I appreciate all you've done.
d2
0
 
HonorGodCommented:
Understood.  When you have some time, take a look at this, and see what you can learn.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>3 tier</title>
 
<script type='text/javascript'>
  function field( id ) {
    var ele = document.getElementById( id )
    if ( !ele ) {
      alert( 'Specified element not found. id="' + id + '"' )
    }
    return ele
  }
 
  function fill_Branches( i ) {
//  alert( 'fill_Branches( ' + i + ' )' )
    var branches = document.getElementById( 'Branches' )
    if ( branches ) {
      if ( branches.nodeName == 'SELECT' ) {
        var opts = branches.options
        opts.length = 0
        switch( i - 0 ) {
          case 0:
            opts[ 0 ] = new Option( 'case 0 Branch' )
            break
 
          case 11:
            opts[ 0 ] = new Option( 'case1 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'Section1', 11 )
            opts[ 2 ] = new Option( 'Section2', 12 )
            opts[ 3 ] = new Option( 'Section3', 13 )
            break
 
          case 12:
            opts[ 0 ] = new Option( 'case2 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'Section1', 21 )
            opts[ 2 ] = new Option( 'Section2', 22 )
            opts[ 3 ] = new Option( 'Section3', 23 )
            break
 
          case 13:
            opts[ 0 ] = new Option( 'case3 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'Section1', 31 )
            opts[ 2 ] = new Option( 'Section2', 32 )
            opts[ 3 ] = new Option( 'Section3', 33 )
            break
 
          default :
            alert( 'fill_Branches(): Unexpected value specified: ' + i )
        }
      } else {
        alert( 'fill_Branches(): error. Unexpecte element type: "' + branches.nodeName + '".' )
      }
    } else {
      alert( 'fill_Branches(): error. Branches select element not found. id="Branches".' )
    }
  }
 
  function fill_Sections( i ) {
//  alert( 'fill_Sections( ' + i + ' )' )
    var sections = document.getElementById( 'Sections' )
    if ( sections ) {
      if ( sections.nodeName == 'SELECT' ) {
        var opts = sections.options
        opts.length = 0
        switch( i - 0 ) {
          case 0:
            opts[ 0 ] = new Option( 'case 0 Section', 'Select Section' )
            break
 
          case 11:
            opts[ 0 ] = new Option( 'case1 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N1B1_Section1', '11a' )
            opts[ 2 ] = new Option( 'N1B1_Section2', '11b' )
            opts[ 3 ] = new Option( 'N1B1_Section3', '11c' )
            break
 
          case 12:
            opts[ 0 ] = new Option( 'case2 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N1B2_Section1', '12a' )
            opts[ 2 ] = new Option( 'N1B2_Section2', '12b' )
            opts[ 3 ] = new Option( 'N1B2_Section3', '12c' )
            break
 
          case 13:
            opts[ 0 ] = new Option( 'case3 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N1B3_Section1', '13a' )
            opts[ 2 ] = new Option( 'N1B3_Section2', '13b' )
            opts[ 3 ] = new Option( 'N1B3_Section3', '13c' )
            break
 
          case 21:
            opts[ 0 ] = new Option( 'case4 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N2B1_Section1', '21a' )
            opts[ 2 ] = new Option( 'N2B1_Section2', '21b' )
            opts[ 3 ] = new Option( 'N2B1_Section3', '21c' )
            break
 
          case 22:
            opts[ 0 ] = new Option( 'case5 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N2B2_Section1', '22a' )
            opts[ 2 ] = new Option( 'N2B2_Section2', '22b' )
            opts[ 3 ] = new Option( 'N2B2_Section3', '22c' )
            break
 
          case 23:
            opts[ 0 ] = new Option( 'case6 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N2B3_Section1', '23a' )
            opts[ 2 ] = new Option( 'N2B3_Section2', '23b' )
            opts[ 3 ] = new Option( 'N2B3_Section3', '23c' )
            break
 
          case 31:
            opts[ 0 ] = new Option( 'case7 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N3B1_Section1', '31a' )
            opts[ 2 ] = new Option( 'N3B1_Section2', '31b' )
            opts[ 3 ] = new Option( 'N3B1_Section3', '31c' )
            break
 
          case 32:
            opts[ 0 ] = new Option( 'case8 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N3B2_Section1', '32a' )
            opts[ 2 ] = new Option( 'N3B2_Section2', '32b' )
            opts[ 3 ] = new Option( 'N3B2_Section3', '32c' )
            break
 
          case 33:
            opts[ 0 ] = new Option( 'case9 Select Section', 'Select Section' )
            opts[ 1 ] = new Option( 'N3B3_Section1', '33a' )
            opts[ 2 ] = new Option( 'N3B3_Section2', '33b' )
            opts[ 3 ] = new Option( 'N3B3_Section3', '33c' )
            break
 
          default:
            alert( 'fill_Sections(): Unexpected value specified: ' + i )
        }
      } else {
        alert( 'fill_Sections(): error. Unexpecte element type: "' + sections.nodeName + '".' )
      }
    } else {
      alert( 'fill_Sections(): error. Sections select element not found. id="Sections".' )
    }
  }
 
  function pick( val ) {
    alert( 'Selected value: ' + val )
  }
</script>
 
</head>
<body>
 
<form name='form1aa' method='post' action='' id='form1a' >
<p>Network</p>
<select name='network' id='network' title='Select a Network'
onchange='fill_Branches(this.options[this.selectedIndex].value)' >
        <option value='0'>Select Network</option>
        <option value='11'>Network1</option>
        <option value='12'>Network2</option>
        <option value='13'>Network3</option>
</select>
 
<br />
<p>Branch</p>
<select name='Branches' id='Branches' title='Select a Branch'
onchange='fill_Sections(this.options[this.selectedIndex].value)' >
<option value='noBranch'>No Branches</option>
</select>
 
<br />
<p>Section</p>
<select name='Sections' id='Sections' title='Select a Section'
onchange='pick(this.options[this.selectedIndex].value)' >
<option value='noSection'>No Sections</option>
</select>
 
</form>
 
</body>
</html>

Open in new window

0
 
dzash2000Author Commented:
HonorGod - It's perfect!
I see you built a little "teaching machine" out of it with all the references and the alert.  I really appreciate how you sensed how much trouble I have understanding programming. (I'm better with pictures.)  Still - I'm fascinated by it.  Needless to say - I'll be staring at this for awhile and I'll be thinking of you when I do.  Thank you for all your time and attention.
d2

0
 
HonorGodCommented:
You are very welcome.  Thank you for the compliments, the patience, the grade & the points.

Good luck & have a great day.


0
 
dzash2000Author Commented:
HonorGod -
Something has come up.  

One of the things I thought I knew how to do was to link to an external JS file.  Since this 3tier DD appears on all of my demos pages I took everything between the <script> tags, put it into it's own .js file and put this link in the head of the demo page:
 <script type="text/javascript" src="_scripts/threeTierDD9.js"></script>
But the functions aren't working at all.  

Is there something else I should do?

thanks,
d2
0
 
HonorGodCommented:
Using something like this:

<script type="text/javascript" src="_scripts/threeTierDD9.js"></script>

does make the functions, and any global variables available on the page.

What do your "select" tags look like?

are they like this?

Or something else?



<select name='network' id='network' title='Select a Network'
onchange='fill_Branches(this.options[this.selectedIndex].value)' >

Open in new window

0
 
dzash2000Author Commented:
I am using the select lists as they were in your full code post...
<select name='network' id='network' title='Select a Network'
onchange='fill_Branches(this.options[this.selectedIndex].value)' >
        <option value='0'>Select Network</option>
        <option value='11'>Network1</option>
        <option value='12'>Network2</option>
        <option value='13'>Network3</option>
</select>
 
<br />
<p>Branch</p>
<select name='Branches' id='Branches' title='Select a Branch'
onchange='fill_Sections(this.options[this.selectedIndex].value)' >
<option value='noBranch'>No Branches</option>
</select>
 
<br />
<p>Section</p>
<select name='Sections' id='Sections' title='Select a Section'
onchange='pick(this.options[this.selectedIndex].value)' >
<option value='noSection'>No Sections</option>
</select>

Open in new window

0
 
HonorGodCommented:
One thing that can cause failures is if you have some javascript on the page that has a syntax error, which can cause all sorts of havoc.

What browser are you using?

What errors/symptoms are you seeing?


0
 
dzash2000Author Commented:
I'm using IE6...it's a requirement of the project.
I'm developing in MS Expression Web and the page is .aspx - not .html - also a requirement.
I'm not seeing any error messages, symptoms or even markings from Expression Web (which loves to put squigglies under anything it doesn't like).  

I just did the entire process again. I made a new .aspx with nothing else on it. I linked the DD's to the external script and it worked.

But when I integrate it on one of my demo pages, with all kinds of other stuff going on, it doesn't register.   If you don't see anything I'm doing wrong in the script tag and the select list code, there must be an error elsewhere.

I'm wondering if it's an Expression Web thing - like it doesn't see new scripts until it crashes and re-launches.

I'll keep crashing and digging and figure this out.   Thanks.
0
 
HonorGodCommented:
Good luck & have fun.
0

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

  • 19
  • 16
Tackle projects and never again get stuck behind a technical roadblock.
Join Now