Ok, so it's easy enough to modify element CSS on the fly with getElementById. Problem is, you have to give a unique id to every single element on your page you want to be able to modify. I don't want to have to make over a 100 unique id's for the project I'm working on. I'd rather use DOM familial relationships to determine which element to act upon. I'm sure JS has a solution for me. Can you help me find it?

Here's my goal. It's a list of projects that my agency is working on. We have lots of projects happening, like maybe 20-30, so the list will need to be expandable/collapsible as seen in the image (this is a screenshot of static XHTML at the moment, no interactivity).

[img]http://www.hca.wa.gov/images/screen.gif[/img]

Here is the html code of the list. All the bullets and formatting are in a separate CSS.

<ul id="programlist">

  <li class="programlistitem" id="p1"><a href="#">Project 1</a>
    <ul>
      <li class="overview"><a href="#">Overview</a></li>
      <p>This is the purpose of the program.</p>
      <li class="news"><a href="#">Latest News</a></li>
      <p>This is what the program did last.</p>
      <li class="contact">Contact Person: John Smith</li>
      <li class="homepage"><a href="...">Project Homepage</a></li>
    </ul>
  </li>

  <li class="programlistitem" id="p2"><a href="#">Project 2</a>
    <ul>
      <li class="overview"><a href="#">Overview</a></li>
      <p>This is the purpose of the program.</p>
      <li class="news"><a href="#">Latest News</a></li>
      <p>This is what the program did last.</p>
      <li class="contact">Contact Person: John Smith</li>
      <li class="homepage"><a href="...">Project Homepage</a></li>
    </ul>
  </li>

</ul>

Now, if someone clicks on, say, the words "Project 1", it says "ok, I need to make my child <ul> visible now, which effectivly expands the contents of the first project, so you can see the 4 items under it. The Overview and Latest News would also function the same way making visible/hidden the <p> tags under themselves, with their content hidden at first, then appearing when you click their links.

I have created scripts like this before, using display: hidden and display: block to achieve the same effect, but I always had to use a unique ID for EVERY item. I want to take my JS to the next level. Can someone point me to a tutorial that will show me how to select elements more dynamically based upon familial relationships?

I hope this is clear. Please let me know if you need any more details about what I'm trying to do.

Thanks in advance for your help!

chigasakigaijin

Recommended Answers

All 2 Replies

There are DOM methods equivalent to getElementById, such as .getFirstChild, .getChildNodes() and so on. Those are what you need to use. Web search for those terms, you should find lots of tutorials

Thanks so much for getting me started in the right direction. I found that the items I was looking for were:

parentElement; and getElementsByTagName();

here is the final working script for the main project name links.

function toggle(source) 
{
	var theParent = source.parentElement;
	var children = theParent.getElementsByTagName('ul');
	var target = children[0];
	//check current visibility and set it to the opposite
	if ((target.style.display == "none") || (target.style.display == "null"))
	{
		target.style.display = "block";
		//change bullet to minus sign to indicate "collapsible"
		theParent.style.backgroundImage = "url(/images/projectspage/minus.gif)"; 

	} 
	else 
	{
		target.style.display = "none";
		//change bullet to plus sign to indicate "expandable"
		theParent.style.backgroundImage = "url(/images/projectspage/plus.gif)"; 
	}
}

I also made a toggleSub(); function to handle the two sub-list expandable items.

I call them with the following HTML:

<li class="projectlistitem"><a class="projectname" href="#" onClick="toggle(this);">Web Advisory Committee (WAC)</a>

The key for me was figuring out what "this" meant. Since it sends in the hierarchical location of where the script was called, I used that as my starting point. Since I use consistent patterns of HTML, I know that I can reliable go, for instance:
1. Out to the parent
2. In to the first UL

and that is what I want to toggle the visibility of. Doing it this way, I did not use a single ID in relation to the JS. Smooth, baby.

Whew, anyway it works, and I'm glad.

Thanks again!

Be a part of the DaniWeb community

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