Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Changing the List bullet image on collapse/expand 1

Status
Not open for further replies.

Zoom1177

Programmer
Oct 25, 2006
44
US
Hi, I have a tree menu that expands and collapse with the default XHTML bullets

I would like to add couple of lines to the existing javascript functions that i have to change the those bullets to the Windows Standard Plus and Minus images, which i have them in files called: plus.gif and minus.gif

My tree-men is pulled dynamically from a database but to demonstrate i'll just put a static list to make it easy, i dont think it would make a difference once i know how to change the bullets to image on expand/collapse

I appreciate your help very much.

here is the simple code

<STYLE TYPE='text/css'>
li.Item {
color: #0000FF;
cursor: hand;
display: table-row;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 14px;
line-height: 20px;
} ;
li.Main {
color: #0000FF;
cursor: hand;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 14px;
line-height: 20px;
} ;
ul ul { display: none; } ;
</STYLE>

<SCRIPT LANGUAGE='Javascript'>
function checkParent( src, tagName ) {
while ( src != null ) {
if (src.tagName == tagName)
return src;
src = src.parentElement;
}
return null;
}
function checkContent( src, tagName ) {
var pos = src.sourceIndex ;
while ( src.contains( document.all[++pos] ) )
if ( document.all[pos].tagName == tagName )
return document.all[pos] ;
return null ;
}
// onClick event
function outlineAction() {
var src = event.srcElement ;
var item = checkParent( src, "LI" ) ;

if ( parent != null ) {
var content = checkContent( item, "UL" ) ;

if ( content != null )
if ( content.style.display == "" )
content.style.display = "block" ;
else
content.style.display = "" ;
}
event.cancelBubble = true;
}
</SCRIPT>

<body>
<DIV onClick="JavaScript: outlineAction();">
<UL>

<LI class='Main'>List1
<UL>
<LI class='Item'>Item1</LI>
<LI class='Item'>Item2</LI>
<LI class='Item'>Item3</LI>
</UL>
</LI>

<LI class='Main'> List2
<UL>

<LI class='Item'>Item1</LI>
<LI class='Item'>Item2</LI>
<LI class='Item'>Item3</LI>

</UL>
</LI>

<LI class='Main'> List3
<UL>

<LI class='Item'>Item1</LI>
<LI class='Item'>Item2</LI>
<LI class='Item'>Item3</LI>

</UL>
</LI>

</UL>

</DIV>
</body>

 
If I were you I'd scrap what you've already started with.

For starters, document.all is IE only syntax, which means that your code will likely break in all browsers other than IE. That's a bad foot to start out on.

Secondly, I can never stress how important proper indentation is when coding and ESPECIALLY debugging.

Third, your use of classes in your CSS is not really necessary - you can get around that by using parent tag specifiers to get down to the items you want to apply your styles to. Here's my stab at doing this (note that the javascript is down to only 3 lines in one function, instead of multiple lines across 3 functions - it's cross browser compliant as well).

And, as always when working with lists, it's a good idea to set all padding and margins to 0, as different browsers have different default padding and margins for lists. Starting initially at 0 and specifying what you want will allow you to make sure they look the same on each browser.

Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">[/URL]
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<script type="text/javascript">

function blah(obj) {
   var childList = obj.getElementsByTagName("ul")[0];
   childList.style.display = (childList.style.display == "block") ? "none" : "block";
   obj.className = (obj.className == "") ? "expanded" : "";
}

</script>

<style type="text/css">

* {
   padding:0px;
   margin:0px;
}

ul#theList {
   list-style-type:none;
}

ul#theList li {
   padding-left:20px;
   background:url(plus.gif) 4px 4px no-repeat;
}

ul#theList li.expanded {
   background:url(minus.gif) 4px 4px no-repeat;
}

ul#theList ul {
   display:none;
}

ul#theList ul li {
   background:none;
   margin-left:20px;
   padding-left:0px;
}

</style>
</head>
<body>

<ul id="theList">
   <li onclick="blah(this)">
      List 1
      <ul>
         <li>Item 1</li>
         <li>Item 2</li>
         <li>Item 3</li>
      </ul>
   </li>
   <li onclick="blah(this)">
      List 2
      <ul>
         <li>Item 1</li>
         <li>Item 2</li>
         <li>Item 3</li>
      </ul>
   </li>
   <li onclick="blah(this)">
      List 3
      <ul>
         <li>Item 1</li>
         <li>Item 2</li>
         <li>Item 3</li>
      </ul>
   </li>
</ul>

</body>
</html>

-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
Thanks kaht,

I'll try it and let you know how it works out

by the way: this application is for Intranet and we're sure of the browser being used will always be IE, but thanks anyway.

As for indentation, yes i do thanks :)

 
It worked great, THANKS

However, when i tried to add more ul under the li it collapse back up to the Main List instead of opening the more lists under

What i need actually is something like this:

List1
List2
List3
Item1
Item2
Item3

and each list could have item under neath it too.

But thanks anyway for your help
 
Sorry i forgot to mention something:

The code need to check and see if the current item is a List or an Item because if it's a List it should assign it the plus.gif again.

I think there is some code i read about assiging SRC"path" where path is the plus/minus path
 
I am really stuck here, if someone can help me that would be great

I am using a different function and style to toggle the driven-menu that i have and it's working Perfectly

the only problem is that at the node of collapsed items it shows the Plus character "+" and when it expands it shows the "-" character.

Nothing wrong with that except it's not what my boss wants

So if someone can hellp me how to ulter my code so instead of switching between those two characters(+/-) it would switch between two pictures (plus.gif/minus.gif)

I think it should be easy, i don't know much about javascript so any help would be greatly appreciated:

here is a sample code.

<style>
body,td,th {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 14px;
line-height: 20px;
color: #0000FF;
cursor: hand;
background-image: url(../images/bg.gif);
}
.element{
font-size:13px;
margin-left:25px;
}
.element_contents{
font-size:13px;
display:none;
}
.element_file{
font-size:13px;
margin-left:25px;
}
.toggle{
width:20px;
text-decoration:none;
text-align:center;
color:#aaaaaa;
cursor:hand;
}
</style>

<script language="JavaScript">
//first redirect all click events to the navClicked function
document.onclick = navClicked;

function switchPoint(aNavPoint){
var collapsed;

if(aNavPoint.innerHTML == "+"){
collapsed=false;
aNavPoint.innerHTML = "-";
}
else{
collapsed=true;
aNavPoint.innerHTML = "+";
}

return collapsed;
}

function navClicked(){
//assume the click was on a switchPoint and that it is collapsed
var isCollapsed = true;

//get a reference to the element that was clicked
e = window.event.srcElement;

//if the element that was clicked on was one of the toggles
if(e.className == "toggle"){
//call the switchpoint function to change it's state, ie "+" to "-" and "-" to "+"
isCollapsed = switchPoint(e);
//if the item is now collapsed after switching
if(isCollapsed)
//get it's parent element, get the parents third child (element_contents), hide it
e.parentElement.children(2).style.display = "none";
else
//otherwise open it's element_contents sibling
e.parentElement.children(2).style.display = "inline";
}
}
</script>

</head>

<body>
<!-- Parent 1 -->
<div class="element">
<span class="toggle">+</span>
<span class="element_name">Parent 1</span>
<div class="element_contents">

<!-- Begin Child 1 -->
<div class="element">
<span class="toggle">+</span>
<span class="element_name">Child 1</span>
<div class="element_contents">

<!-- Begin Child 2 -->
<div class="element">
<span class="toggle">+</span>
<span class="element_name">Child 1.1</span>
<div class="element_contents">

<!-- Beging the Last List -->
<div class="element"><span class="element_file"> Child 1.1.1</span></div>

<!-- End Child 2 -->
</div>
</div>

<!-- End Child 1 -->
</div>
</div>

<!-- End Parent1 -->
</div>
</div>

THANK YOU for your help!
 
Why did you go to using divs and spans? That's a step backward. You were using <ul> and <li> tags to display a list - that's what those tags are for. To change them to divs and spans is symantically incorrect. I changed a few things up and redid my example from above. It had 3 images, plus.gif, minus.gif, and bullet.gif (bullet because you have to set the list-style-type to none if you're using your own custom images for plus and minus. That will trickle down thru the whole list if it can be multi-tiered, so no one <ul> tag can be assured of having list-style-type of disc, so instead we make an image to fake it [smile]

Addtionally, I added anchor tags so that only clicking on the plus or minus image expands/contracts the list. That way the list doesn't contract itself when you click a + button on a child list (because it still triggers the onclick event from the parent <li>).

Anyway, the example:


-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
Well, the first example completely bombed in Firefox (which was probably irrelevant since you said you're on an IE only platform), but I was incorrectly using parentElement instead of parentNode. Additionally, FF requires you to have some content in the anchor to be able to click on it, so I threw in some non-breaking spaces. A little sloppy, I know. But it works.

-kaht

[small](All puppies have now found loving homes, thanks for all who showed interest)[/small]
 
It sounds great kaht,

thank you again, i'll try it and let you know how it worked out.
 
kaht,

It worked just fine.

Great job!

Thank you very much
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top