How to write a loop logic to replace this hard coded script?

I have been trying this for a while without success. Please help out.
The following code is a working code but the javascript is hard coded. I want to use a for loop to replace it.  But  I have tried many tricks without success.  Your help is deeply appreciated.

The complete Code:
================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>

<head>
<title>Dropdowns</title>

<style type="text/css">


table.navBar
{
border-top: 1px;
solid #FFF;
font-size:100%;
position:absolute;
visibility:hidden;
}

table.menu
{
font-size:100%;
position:absolute;
visibility:hidden;
}

#navigation { position: static; top: 150; left: 150; width:763px}
#posRight {position: relative; left: 360px; }
#posLeft  {position: relative; left: 0px; }



      .navbar td      { border-right: 1px solid #FFF; padding: 4px 9px; background-color: #001B6A; color: #FFF; font-family: Arial,sans-serif; font-size: 11px; font-weight: bold; text-align: center }
      #nbclass        { border: 1px solid #000; padding: 2px 0px; background-color: #5A84FF; font-size: 14px }
      #nbrule { border-top: 1px solid #FFF; padding: 0px; background-color: #000 }
      #nbsel  { background-color: #5F87FF }

      div.child            { width: 403px; border-width: 0px 1px 1px 0px; border-style: solid; border-color: #ADADAD }
      .child table      { border: 1px solid #000; border-top: 0px; background-color: #FFF }
      .child td      { padding: 0px 1px 1px 0px; background-color: #ADB5AD; font-size: 11px; font-family: Arial,sans-serif }
      .child td div            { margin: 0px }
      td .col            { border: 1px solid #00186B }
      .cat, .itm      { border-bottom: 1px solid #ADADAD; padding: 2px 3px; background-color: #FFF }
      .cat            { font-weight: bold }
      .cat img      { margin-right: 5px }
      .cat .new      { color: #FF0000 }
      .itm a, .cat a      { text-decoration: none }
      .itm a, .itm a:hover, .itm a:visited, .itm a:active      { color: #42425D }
      .cat a, .cat a:hover, .cat a:visited, .cat a:active      { color: #383843 }
      .csel            { background-color: #D3D4ED }


</style>

<script type="text/javascript"><!--//--><![CDATA[//><!--

var TIMER;

startList = function() {

            
            navBar = document.getElementById("nav").rows[0].cells;
            navBar[0].onmouseover=function() {
               document.getElementById("tutorials").style.visibility="visible"
            }
            
            navBar[0].onmouseout=function() {
                   TIMER=setTimeout('document.getElementById("tutorials").style.visibility="hidden"', 500);
            }
            
            document.getElementById("tutorials").onmouseover=function(){
                clearTimeout(TIMER);
                     document.getElementById("tutorials").style.visibility="visible";
         }
            
            document.getElementById("tutorials").onmouseout=function(){
                     TIMER=setTimeout('document.getElementById("tutorials").style.visibility="hidden"', 500);
         }
        
        
        
            navBar[1].onmouseover=function() {
               document.getElementById("scripting").style.visibility="visible"
            }
            navBar[1].onmouseout=function() {
                   TIMER=setTimeout('document.getElementById("scripting").style.visibility="hidden"', 500);
            }
            
            document.getElementById("scripting").onmouseover=function(){
                  clearTimeout(TIMER);
                  document.getElementById("scripting").style.visibility="visible";
            }
            
            document.getElementById("scripting").onmouseout=function(){
                  TIMER=setTimeout('document.getElementById("scripting").style.visibility="hidden"', 500);
            }
            
      
            navBar[2].onmouseover=function() {
               document.getElementById("validation").style.visibility="visible"
            }
            navBar[2].onmouseout=function() {
                TIMER=setTimeout('document.getElementById("validation").style.visibility="hidden"', 500);
            }
            
            document.getElementById("validation").onmouseover=function(){
                  clearTimeout(TIMER);
                  document.getElementById("validation").style.visibility="visible";
            }
            
            document.getElementById("validation").onmouseout=function(){
                  TIMER=setTimeout('document.getElementById("validation").style.visibility="hidden"', 500);
            }
}

window.onload=startList;

//--><!]]></script>

</head>

<body>

<div id="navigation">


<table id="nav" "width="763" cellpadding="0" cellspacing="0" border="0" class="navbar">
 <tr>
    <td >Tutorials</a><br /></td>
      <td>Scripting</a><br /></td>
        <td>Validation</a><br /></td>
 </tr>
</table>
</div>

<div id="posLeft">
<table class="menu" id="tutorials" width="120">
   <tr><td><a href="/html/default.asp">HTML</a></td></tr>
   <tr><td><a href="/xhtml/default.asp">XHTML</a></td></tr>
   <tr><td><a href="/css/default.asp">CSS</a></td></tr>
   <tr><td><a href="/xml/default.asp">XML</a></td></tr>
   <tr><td><a href="/xsl/default.asp">XSL</a></td></tr>
   </table>

   <table class="menu"  id="scripting" width="120">
   <tr><td class="menu"><a href="/js/default.asp">JavaScript</a></td></tr>
   <tr><td class="menu"><a href="/vbscript/default.asp">VBScript</a></td></tr>
   <tr><td class="menu"><a href="default.asp">DHTML</a></td></tr>
   <tr><td class="menu"><a href="/asp/default.asp">ASP</a></td></tr>
   <tr><td class="menu"><a href="/ado/default.asp">ADO</a></td></tr>
   </table>

   <table class="menu"  id="validation"  width="120">
   <tr><td><a href="/site/site_validate.asp">Validate HTML</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate XHTML</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate CSS</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate XML</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate WML</a></td></tr>
   </table>
</div>
</body>
</html>

================================================
rdongAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Michel PlungjanIT ExpertCommented:
list = "tutorials,scripting,validation".split(',')

startList = function() {
          navBar = document.getElementById("nav").rows[0].cells;
          for (i=0;i<list.length;i++)
          navBar[i].onmouseover=function() {
             document.getElementById(list[i]).style.visibility="visible"
          }
         
          navBar[i].onmouseout=function() {
                TIMER=setTimeout('document.getElementById("'+list[i]+'").style.visibility="hidden"', 500);
          }
         
          document.getElementById(list[i]).onmouseover=function(){
              clearTimeout(TIMER);
                  document.getElementById(list[i]).style.visibility="visible";
        }
         
          document.getElementById(list[i]).onmouseout=function(){
                  TIMER=setTimeout('document.getElementById("'+list[i]+'").style.visibility="hidden"', 500);
        }

}
DanielSchafferCommented:
var elementId = new Array();
elementId[0] = 'tutorials';
elementId[1] = ...etc

navBar = document.getElementById("nav").rows[0].cells;

for(index = 0;index < [number of elements you need do -1];index++)
{
document.getElementById(elementId[index]).onmouseout = ......
//set your other properties...
}

You get the idea.
Michel PlungjanIT ExpertCommented:
index < [number of elements you need do -1]
Huh???

Your Guide to Achieving IT Business Success

The IT Service Excellence Tool Kit has best practices to keep your clients happy and business booming. Inside, you’ll find everything you need to increase client satisfaction and retention, become more competitive, and increase your overall success.

DanielSchafferCommented:
sorry... just use 2.
Michel PlungjanIT ExpertCommented:
I think you mean
just use  
index < [number of elements you need to do ]
and not -1
DanielSchafferCommented:
Well yeah...  but it isn't the number of elements that need to be done, its that number -1, since its a 0-based index.
rdongAuthor Commented:
tested  mplungjan 's solution, not working...
rdongAuthor Commented:
DanielSchaffer's solution will not work either and you can not simply just pass elementId[index] to getElementById.  That will not work.   It is a challenge.
rdongAuthor Commented:
I wish you guys can test your solution first before you post here. I have tried many tricks without success. Looks like this is a difficult one.
DanielSchafferCommented:
You're going to need to clarify "will not work". What error are you getting and where?
DanielSchafferCommented:
document.getElementById(elementId[index]) should work fine...  elementId[index] will return a string, which will be used as the parameter in getElementById.
rdongAuthor Commented:
Thanks, DanielSchaffer, I have already tried similar solution as yours many times before.
The error would be document.getElementById(..) has no properties....
DanielSchafferCommented:
try testing to see what elementId[index] is returning. comment out the document.getElementById() line and put in alert(elementId[index)
rdongAuthor Commented:
Thanks, again, I think the issue here is how can I make this line of code work or work around:
I alwasy get "no properties" error...
============================================
........
var catNames = new Array("tutorials", "scripting", "validation");

document.getElementById(catNames[x]).onmouseover=function(){
          clearTimeout(TIMER);
      document.getElementById(catNames[x]).visibility="visible";
}
...........
=============================================
rdongAuthor Commented:
Also, I was trying to  get the element from dom.  So instead of using caNames array, I tried to extract them form dom. But I do not have much success either.
DanielSchafferCommented:
Wow, I can't believe I didn't notice this before.....  you're going to need to set the ID properties of the elements you're trying to reference in your html code. getElementById() is useless if you don't assign IDs to your elements.
rdongAuthor Commented:
Well, if you see my code above carefully, you should notice they all have ids.... I do not know why you say I did not assign IDs to elements...
DanielSchafferCommented:
Oh............. I feel dumb... was looking at the table above with the table cells....
rdongAuthor Commented:
No problems,  we all have times like that...

Ideally, I wish I could get something like the following work. Of course the code is not working but you get idea....

============================================
navBar = document.getElementById("nav").rows[0].cells;
node = document.getElementById("posLeft");  
       
        for(x=0; x<navBar; x++){
       navBar[x].onmouseover=function() {
        document.getElementById(x).style.visibility="visible"
      }
                  
    navBar[x].onmouseout=function() {
          TIMER=setTimeout('document.getElementById(x).style.visibility="hidden"', 500)
   }                  

  node.childNodes[x].onmouseover=function(){
       clearTimeout(TIMER);
      node.childNodes[x].style.visibility="visible";                        
}
                  
node.childNodes[x].onmouseout=function(){
   TIMER=setTimeout('node.childNodes[x].style.visibility="hidden"', 500)            
}
}      
=============================================
DanielSchafferCommented:
Just a few things I'm noticing....

1. There are several lines that don't end with a ; I've found that since JavaScript is intermittantly picky about this, it's always best to error on the side of safety and add a ; at the end of each line (except for closing brackets)

2. document.getElementById(x) will not work because x is an integer and you can't have IDs that are just integers.
rdongAuthor Commented:
I know,  it is not a working code, I just want to throw out some ideas.    Looks like a finding a solution is too difficult.
rdongAuthor Commented:
Increase the point to 150
Michel PlungjanIT ExpertCommented:
DS: semicolons are not the issue here
rdong: I was not testing since I just converted your code (assuming your code worked) to an array.
Michel PlungjanIT ExpertCommented:
Here:

 list = "tutorials,scripting,validation".split(',')

startList = function() {
          navBar = document.getElementById("nav").rows[0].cells;
          for (i=0;i<list.length;i++) {
          navBar[i].cnt=document.getElementById(list[i]).cnt;
          navBar[i].onmouseover=function() {
             document.getElementById(list[this.cnt]).style.visibility="visible"
          }
         
          navBar[i].onmouseout=function() {
                TIMER=setTimeout('document.getElementById("'+list[this.cnt]+'").style.visibility="hidden"', 500);
          }
         
          document.getElementById(list[i]).onmouseover=function(){
              clearTimeout(TIMER);
                  document.getElementById(list[this.cnt]).style.visibility="visible";
          }
          document.getElementById(list[i]).onmouseout=function(){
                  TIMER=setTimeout('document.getElementById("'+list[this.cnt]+'").style.visibility="hidden"', 500);
        }
  }
}


and I added cnt to each table:

<table class="menu" id="tutorials" cnt=0 width="120">
rdongAuthor Commented:
mplungjan, Thanks a lot for your efforts. However, I just tested on Firefox and got error:

document.getElementById(list[this.cnt]))has no properties....

I am thinking is there a way that we could use DOM to get the node and travse the children elements:

node = document.getElementById("posLeft");  use a for loop to get the table elements. I can not make it work.  Maybe you can share some input here.

 
rdongAuthor Commented:
I found the solution myself!!  Thank you very much!
Michel PlungjanIT ExpertCommented:
Yeah. Firefox does not read the attributes directly from the tag (expando).
use
this.getAttribute('....')  or similar
e.g.  document.getElementById(list[this.getAttribute("cnt")]).style.visibility="visible";
rdongAuthor Commented:

Tried:
document.getElementById(list[this.getAttribute("cnt")]).style.visibility="visible";
Got the same "no properties" error on Firefox.
Michel PlungjanIT ExpertCommented:
This works for me



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>

<head>
<title>Dropdowns</title>

<style type="text/css">


table.navBar
{
border-top: 1px;
solid #FFF;
font-size:100%;
position:absolute;
visibility:hidden;
}

table.menu
{
font-size:100%;
position:absolute;
visibility:hidden;
}

#navigation { position: static; top: 150; left: 150; width:763px}
#posRight {position: relative; left: 360px; }
#posLeft  {position: relative; left: 0px; }



     .navbar td      { border-right: 1px solid #FFF; padding: 4px 9px; background-color: #001B6A; color: #FFF; font-family: Arial,sans-serif; font-size: 11px; font-weight: bold; text-align: center }
     #nbclass        { border: 1px solid #000; padding: 2px 0px; background-color: #5A84FF; font-size: 14px }
     #nbrule { border-top: 1px solid #FFF; padding: 0px; background-color: #000 }
     #nbsel  { background-color: #5F87FF }

     div.child          { width: 403px; border-width: 0px 1px 1px 0px; border-style: solid; border-color: #ADADAD }
     .child table     { border: 1px solid #000; border-top: 0px; background-color: #FFF }
     .child td     { padding: 0px 1px 1px 0px; background-color: #ADB5AD; font-size: 11px; font-family: Arial,sans-serif }
     .child td div          { margin: 0px }
     td .col          { border: 1px solid #00186B }
     .cat, .itm     { border-bottom: 1px solid #ADADAD; padding: 2px 3px; background-color: #FFF }
     .cat          { font-weight: bold }
     .cat img     { margin-right: 5px }
     .cat .new     { color: #FF0000 }
     .itm a, .cat a     { text-decoration: none }
     .itm a, .itm a:hover, .itm a:visited, .itm a:active     { color: #42425D }
     .cat a, .cat a:hover, .cat a:visited, .cat a:active     { color: #383843 }
     .csel          { background-color: #D3D4ED }


</style>

<script type="text/javascript"><!--//--><![CDATA[//><!--

var TIMER;


 list = "tutorials,scripting,validation".split(',')

startList = function() {
          navBar = document.getElementById("nav").rows[0].cells;
          for (i=0;i<list.length;i++) {
          navBar[i].cnt=document.getElementById(list[i]).getAttribute('cnt'); // <<<<<< NB!!!
          navBar[i].onmouseover=function() {
             document.getElementById(list[this.cnt]).style.visibility="visible"
          }
         
          navBar[i].onmouseout=function() {
                TIMER=setTimeout('document.getElementById("'+list[this.cnt]+'").style.visibility="hidden"', 500);
          }
         
          document.getElementById(list[i]).onmouseover=function(){
              clearTimeout(TIMER);
                  document.getElementById(list[this.cnt]).style.visibility="visible";
          }
          document.getElementById(list[i]).onmouseout=function(){
                  TIMER=setTimeout('document.getElementById("'+list[this.cnt]+'").style.visibility="hidden"', 500);
     }
  }
}

window.onload=startList;

//--><!]]></script>

</head>

<body>

<div id="navigation">


<table id="nav" "width="763" cellpadding="0" cellspacing="0" border="0" class="navbar">
 <tr>
    <td >Tutorials</a><br /></td>
     <td>Scripting</a><br /></td>
       <td>Validation</a><br /></td>
 </tr>
</table>
</div>

<div id="posLeft">
<table class="menu" cnt="0" id="tutorials" width="120">
   <tr><td><a href="/html/default.asp">HTML</a></td></tr>
   <tr><td><a href="/xhtml/default.asp">XHTML</a></td></tr>
   <tr><td><a href="/css/default.asp">CSS</a></td></tr>
   <tr><td><a href="/xml/default.asp">XML</a></td></tr>
   <tr><td><a href="/xsl/default.asp">XSL</a></td></tr>
   </table>

   <table class="menu"  cnt="1"  id="scripting" width="120">
   <tr><td class="menu"><a href="/js/default.asp">JavaScript</a></td></tr>
   <tr><td class="menu"><a href="/vbscript/default.asp">VBScript</a></td></tr>
   <tr><td class="menu"><a href="default.asp">DHTML</a></td></tr>
   <tr><td class="menu"><a href="/asp/default.asp">ASP</a></td></tr>
   <tr><td class="menu"><a href="/ado/default.asp">ADO</a></td></tr>
   </table>

   <table class="menu"  cnt="2"  id="validation"  width="120">
   <tr><td><a href="/site/site_validate.asp">Validate HTML</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate XHTML</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate CSS</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate XML</a></td></tr>
   <tr><td><a href="/site/site_validate.asp">Validate WML</a></td></tr>
   </table>
</div>
</body>
</html>
Michel PlungjanIT ExpertCommented:
But I have a weird feeling it can be done simpler
rdongAuthor Commented:
Wow, that is quick!  As a matter of fact I just tested above code on Firefox and got the same no properties error: document.getElementById(list[this.cnt]) has no properties.

Did you test it on Firefox?

You know what: I want to try a different approach. Something like the this:

======================================
startList = function() {
      
      var top=document.getElementById("nav");
      var tKids=top.getElementsByTagName("td");

      var sub=document.getElementById("pos");
      var sKids=sub.getElementsByTagName("table");

      var sk="";            
      for (x=0; x<3; x++){
            sk=sKids[x].id;
            tKids[x].onmouseover=function(){
             document.getElementById(sk).style.visibility="visible";
             
            }            
            tKids[x].onmouseout=function(){
              TIMER=setTimeout('document.getElementById(sk).style.visibility="hidden"', 500);
             
            }
            sKids[x].onmouseover=function(){
                clearTimeout(TIMER);
                  document.getElementById(this.id).style.visibility="visible";
            }
            
            sKids[x].onmouseout=function(){
            TIMER=setTimeout('document.getElementById(this.id).style.visibility="hidden"', 500);
            }
            
      }            
}            
      
window.onload=startList;
======================================

I do not want to use array because all the information need is already available in the page. But I have a hard time get  this portion of the code work:

============================================
sk=sKids[x].id;
tKids[x].onmouseout=function(){
        TIMER=setTimeout('document.getElementById(sk).style.visibility="hidden"', 500);
==============================================
Since tKids[x] and document.getElementById(sk).... are in different scope so it is hard to try "this" trick and it only shows the last submenu.  See the complete code:

http://www.wiu.edu/users/murbhd/dropdown1.html

I think if something can be figured along that line, it will be the simplest solution.

Thanks again


Michel PlungjanIT ExpertCommented:
Yes I tested in firefox 1.0.4 with the code I pasted

you will HAVE to do something like
sk=sKids[x].id;
tKids[x].onmouseout=function(){
       TIMER=setTimeout('document.getElementById("'+sk+'").style.visibility="hidden"', 500);

Michel
rdongAuthor Commented:
Hi, Michel,

That's strange because I tested on firefox 1.0.4 too and it is not working.  I uploaded to the server:
http://www.wiu.edu/users/murbhd/michel.html

Is't that the code you pasted?


>you will HAVE to do something like
>sk=sKids[x].id;
>tKids[x].onmouseout=function(){
>       TIMER=setTimeout('document.getElementById("'+sk+'").style.visibility="hidden"', >500);

Sorry, I actually tested with that already. The real problem is that it only shows the last submenu no matter what category title the mouse is over

See here:
http://www.wiu.edu/users/murbhd/download2.html

I believe what I am trying to over come is so called "late evaluation" issue. But I could not find a work around.

Thanks a lot Michel.






Michel PlungjanIT ExpertCommented:
You are right. I get a message in the js console, but the code does do the mouseovers... Hence I thought it worked
CetusMODCommented:
PAQed with no points refunded (of 150)

CetusMOD
Community Support Moderator

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.