DeveloperBarn Forums

DeveloperBarn

Programming & IT forum

How do I check the tag of a child?

This is a discussion on How do I check the tag of a child? within the JavaScript Programming forums, part of the Programming & Scripting category; I'm trying to teach myself more complex javascript by making a cascading menu. What I've run into is trying to ...

Go Back   DeveloperBarn Forums > Programming & Scripting > JavaScript Programming

  #1  
Old February 17th, 2009, 02:33 PM
bryceowen's Avatar
Barn Regular
 
Join Date: Sep 2008
Location: Jacksonville, FL
Posts: 92
Rep Power: 2
bryceowen is on a distinguished road
Default How do I check the tag of a child?

I'm trying to teach myself more complex javascript by making a cascading menu. What I've run into is trying to determine what the first child tag is. For example:
HTML Code:
<ul id="menu">
  <li>Item 1
    <ul>
      <li>A</li>
      <li>B</li>
    </ul>
  </li>
</ul> 
The tidbit of code I have at the beginning reads:
HTML Code:
function hideLists(){
  var ulArray=menu.getElementsByTagName('ul');
  for(var i=0;i<ulArray.length;i++){ulArray[i].style.display='none';}
}
And there's an onload in the body tag which quite nicely hides the nested ul. What I need to know is how to check each li tag in the list to see if it's first child is a ul tag, so I can then start on writing how I want it to display that ul.

I know the solution I'm looking for will use .childNodes, but I'm not terribly clear on how to make it happen.
HTML Code:
function hideLists(){
  var ulArray=menu.getElementsByTagName('ul');
  for(var i=0;i<ulArray.length;i++){ulArray[i].style.display='none';}
  var liArray=menu.getElementsByTagName('li');
  for(var i=0;i<liArray.length;i++){if(liArray[i].childNodes[0].nodeName='ul') liArray[i].style.cursor='pointer'; //Just to see if it recognizes the li's that have ul's as children.}
}
Can anyone offer a suggestion?
Reply With Quote
  #2  
Old February 17th, 2009, 02:47 PM
jmurrayhead's Avatar
The Barnfather
 
Join Date: Mar 2008
Real name: Jason
Location: Washington, D.C.
Posts: 1,962
Blog Entries: 8
Rep Power: 15
jmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud of
Default

This will return a list of direct descendants:
Code:
var children = document.getElementById('menu').childNodes;
This will return a list of all decsendants:
Code:
var children = document.getElementById('menu').getElementsByTagName('*');
__________________
jmurrayhead
If you agree with me... click the icon!
If my post solved your problem, click the button in the lower right-hand corner of the post.

If you like it here...throw us a few bones to help
support us.

Join our Folding team: DeveloperBarn Folding

Reply With Quote
  #3  
Old February 18th, 2009, 04:50 PM
bryceowen's Avatar
Barn Regular
 
Join Date: Sep 2008
Location: Jacksonville, FL
Posts: 92
Rep Power: 2
bryceowen is on a distinguished road
Default

Using what you mentioned, Murray, I was able to get it to KINDA work...

Here's my updated code:
HTML Code:
<html>
<head>
<style>
#menu{margin:0;padding:0;z-index:2;}
#menu ul{margin:0;padding:0;}
#menu li{list-style:none;}
#menu .menubar{margin:0;padding:0;float:left;font-family:sans;font-size:80%;}
#menu .menubar a{display:block;margin:0;padding:2px 20px;width:80px;background:#5970B2;color:#FFF;text-align:center;text-decoration:none;cursor:pointer;}
#menu .menubar a:hover{background:#49A3FF;}
#menu .mainmenu{float:left;position:absolute;width:120;font-size:80%;z-index:4;}
#menu .mainmenu a{position:relative;display:block;margin:0;padding:2px 10px;width:auto;text-align:center;text-decoration:none;background:lightblue;color:#2875DE;}
#menu .submenu{position:absolute;left:60px;margin:0;padding:0;width:100px;z-index:5;}
#menu .submenu a{background:lime;padding:2px 0;width:120px;}
</style>
<script language="JavaScript" type="text/javascript">
function initLists(){
	tagArray=menu.getElementsByTagName('*');
	for(i=0;i<tagArray.length;i++){
		if(tagArray[i].tagName=='LI'){
			tagArray[i].setAttribute('class','menubar');
		}
		if((tagArray[i].tagName=='DIV')&&(tagArray[i].parentNode.tagName=='LI')){
			tagArray[i].setAttribute('class','mainmenu');
			tagArray[i].id="menu"+i;
			tagArray[i-1].onclick=function(){togglemenu("menu"+i);};
		}
		if((tagArray[i].tagName=='DIV')&&(tagArray[i].parentNode.tagName=='DIV')){
			tagArray[i].setAttribute('class','submenu');
			tagArray[i].id="submenu"+i;
		}
	}
}
function togglemenu(m){
	alert(m);
//	if(document.getElementById(m).style.display=='none'){
//		document.getElementById(m).style.display='block';
//	}
//	else{
//		document.getElementById(m).style.display='none';
//	}
}
///////////////////////////////Show all lists
function showLists(){
	ulArray=menu.getElementsByTagName('div');
	for(i=0;i<ulArray.length;i++){
		if(ulArray[i].style.display=='none'){
			ulArray[i].style.display='block';
		}
		else{
			ulArray[i].style.display='none';
		}
	}
}
///////////////////////////////
</script>
</head>
<body onload="initLists();">
<ul id="menu">
	<li>
		<a>Service</a>
		<div>
			<a>Panel Guides</a>

			<div>
				<a>Ademco</a>
				<a>Caddx</a>
			</div>
			<a>Service Sheets</a>
		</div>
	</li>

	<li>
		<a>Sales</a>
		<div>
			<a>Lead Tracking</a>
		</div>
	</li>
	<li>
		<a>Administration</a>

	</li>
</ul>
<div style="position:absolute;top:0;right:0;"><input type="button" value="Show/Hide" onclick="showLists();" /></div>
</body>
</html> 
I have it set an onclick event to the <A> tags that immediately proceed the <DIV> tags that, in theory, would throw up an alert box with the ID supposedly assigned to the <DIV>. For some reason, it throws the tagArray.length value... (Load the page and click on 'Service' and 'Sales' to see what I mean.)
What gets me is I have something STRONGLY similar to this working the way I envision it, but I'm not able to use it because I can't get the boxes to position correctly...
I guess my question is, why isn't the code above assigning IDs the way it looks like it should?

Also, something weird to mention, if you click on the show/hide button then try clicking 'Service' or 'sales' it shows menu3, not menu14 like it's been doing...

Double Edit!
Also, it would seem getElementsByTagName('*') doesn't hit on <A> tags. Weird...

Last edited by bryceowen; February 18th, 2009 at 04:53 PM.
Reply With Quote
  #4  
Old February 18th, 2009, 07:39 PM
jmurrayhead's Avatar
The Barnfather
 
Join Date: Mar 2008
Real name: Jason
Location: Washington, D.C.
Posts: 1,962
Blog Entries: 8
Rep Power: 15
jmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud ofjmurrayhead has much to be proud of
Default

I modified your initLists() function and also placed alerts in there so you can see it working (be sure to backup your function before replacing it with this):
Code:
function initLists(){
var menu = document.getElementById("menu"); 
var items = menu.getElementsByTagName("*"); 
for (var i = 0; i < items.length; i++) { 
    if(items[i].tagName=='LI'){
        items[i].id = "menu" + i; 
        items[i].setAttribute('class','menubar');
        alert("ID: " + items[i].id + " Tag Name: " + items[i].tagName);
    }
    if((items[i].tagName=='DIV')&&(items[i].parentNode.tagName=='LI')){
        items[i].id = "menu" + i; 
        items[i].setAttribute('class','mainmenu');
        items[i-1].onclick = function(){togglemenu("menu"+i);};
        alert("ID: " + items[i].id + " Tag Name: " + items[i].tagName);
    }
    if((items[i].tagName=='DIV')&&(items[i].parentNode.tagName=='DIV')){
        items[i].setAttribute('class','submenu');
    items[i].id="submenu"+i;
        alert("ID: " + items[i].id + " Tag Name: " + items[i].tagName);
    }
}
So what I guess I'm asking is, what are you expecting to happen?
Reply With Quote
  #5  
Old February 19th, 2009, 02:01 PM
bryceowen's Avatar
Barn Regular
 
Join Date: Sep 2008
Location: Jacksonville, FL
Posts: 92
Rep Power: 2
bryceowen is on a distinguished road
Default

I managed to get the code to work correctly insofar as labeling each sub-menu with its own unique ID. (Turns out the problem was with the line "tagArray[i-1].onclick=function(){togglemenu("menu"+i);};". You can't reference 'i' because once the loop completes, 'i' will equal whatever its last value was. You can see below where I assigned 'i' as an ID to the tag I wanted to be the trigger.)

Here's my revised code.
HTML Code:
<html>
<head>
<style>
#menu{margin:0;padding:0;z-index:2;}
#menu ul{margin:0;padding:0;}
#menu li{list-style:none;}
#menu #menubar{margin:0;padding:0;float:left;font-family:sans;font-size:80%;}
#menu .menubar a{display:block;margin:0;padding:2px 20px;width:80px;background:#5970B2;color:#FFF;text-align:center;text-decoration:none;cursor:pointer;}
#menu .menubar a:hover{background:#49A3FF;}
#menu .mainmenu{float:left;position:absolute;width:120;font-size:80%;display:none;z-index:4;}
#menu .mainmenu a{position:relative;display:block;margin:0;padding:2px 10px;width:auto;text-align:center;text-decoration:none;background:lightblue;color:#2875DE;}
#menu .subMenu{position:absolute;left:90px;margin:0;padding:0;width:100px;border:solid 1px #5970B2;display:none;z-index:5;}
#menu .subMenu a{background:#EAEBD8;padding:2px 0;width:100px;}
</style>
<script language="JavaScript" type="text/javascript">
function initLists(){
	tagArray=menu.getElementsByTagName('*');
	for(i=0;i<tagArray.length;i++){
		if(tagArray[i].tagName=='LI'){
			tagArray[i].setAttribute('class','menubar');
		}
		if((tagArray[i].tagName=='DIV')&&(tagArray[i].parentNode.tagName=='LI')){
			tagArray[i].setAttribute('class','mainmenu');
			tagArray[i].style.display='none';
			tagArray[i].id="menu"+i;
			tagArray[i].onmouseover=function(){keepOpen();};
			tagArray[i].onmouseout=function(){delayClose();};
			tagArray[i-1].id=i;
			tagArray[i-1].onmouseover=function(){openMenu("menu"+this.id);};
			tagArray[i-1].onmouseout=function(){delayClose("menu"+this.id);};
		}
		if((tagArray[i].tagName=='DIV')&&(tagArray[i].parentNode.tagName=='DIV')){
			tagArray[i].setAttribute('class','subMenu');
			tagArray[i].style.display='none';
			tagArray[i].id="subMenu"+i;
			tagArray[i-1].id=i;
			tagArray[i-1].onclick=function(){openSubMenu("subMenu"+this.id);};
			tagArray[i-1].onmouseout=function(){delaySubClose("subMenu"+this.id);};
		}
	}
}

delaySub=0;
function openSubMenu(tSM){
	tSM=document.getElementById(tSM);
	tSM.style.display='block';
}
function delaySubClose(dSC){
	delaySub=window.setTimeout(subClose(dSC),1000);
}
function subClose(sC){
	sC=document.getElementById(sC);
	sC.style.display='none';
}

//This part works the way it should.
var delay=0;var showing=0;var subMenu=0;
function openMenu(m){keepOpen();if(showing) showing.style.display='none';showing=document.getElementById(m);showing.style.display='block';}
function closeMenu(){if(showing) showing.style.display='none';}
function delayClose(){delay=window.setTimeout(closeMenu,1000);}
function keepOpen(){if(delay){window.clearTimeout(delay);delay=null;}}
//End working part
</script>
</head>
<body onload="initLists();">
<ul id="menu">
	<li>
		<a>Service</a>
		<div>
			<a>Panel Guides</a>

			<div>
				<a>Ademco</a>
				<div>
					<a>Vista 10</a>
				</div>
				<a>Caddx</a>
			</div>

			<a>Service Sheets</a>
			<div>
				<a>Invoice Sample</a>
			</div>
		</div>
	</li>
	<li>
		<a>Sales</a>

		<div>
			<a>Lead Tracking</a>
		</div>
	</li>
	<li>
		<a>Administration</a>
	</li>
</ul>

</body>
</html> 
The problem I'm having now is with the delaySubClose function. When I mouseout of the link that triggers the menu (eg, click on 'Panel Guides') it immediately closes the sub menu rather than waiting 1000ms like it's supposed to.
I realize that resolving THIS problem won't prevent the sub menu from closing after it does open and I mouse into it, but I'll address that as soon as the freakin' delay is working the way it should.
Also, could you give me a little help with the placement of the sub menus? I'd prefer they open directly adjacent to their parent link... I can shift its location left and right just fine, but if I try to set the top or bottom style, it puts it (and all other sub menus) onto the same location. I just want it to move up about 5px...
Reply With Quote
Reply

  DeveloperBarn Forums > Programming & Scripting > JavaScript Programming

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads

Thread Thread Starter Forum Replies Last Post
Check if integer or float! micky .Net Development 23 January 14th, 2009 05:20 AM
Check for existing data in field using SP micky SQL Development 17 November 4th, 2008 09:09 AM
[ASP.Net - VB.Net] Select all checkboxes in child repeater Shem .Net Development 29 November 4th, 2008 08:28 AM
Access 03 Adding updating data from child table to Parent nboscaino Microsoft Access 8 July 15th, 2008 08:12 AM
[Database] Check if result set is empty noFriends PHP Development 6 June 27th, 2008 08:00 PM


All times are GMT -4. The time now is 06:19 PM.


Copyright ©2008-2010, DeveloperBarn

Content Relevant URLs by vBSEO 3.3.2