PDA

View Full Version : Expandable/Collapsible Text not working in Firefox 1.04



wishiwasageek
05-26-2005, 04:22 AM
:o Ok. I totally ripped some javascript off Microsoft.
I don't program very well in javascript (more of a highlevel understanding... ;) )
There are heaps easier scripts I'm sure, some even on this site.
I've found script for everything but changing the images (should this be in style?? not javascript bit?)
Also I don't like having the expanded paragraph text in the javascript, as sometimes the expanded bits are really big.

Aim:
When you click on text(a link) with a small right arrow next to it, the hidden div expands.
BUT the arrow changes to a small down arrow
when you click again on the link, the div collapses (is hidden again) and the arrow returns to a small right arrow.


Happy for you to point me to the right code (especially if it's simpler!)
thanks as always,
WIWAG

Attached/included is the javascript and also the html code.
This works in IE6.0 but not Firefox 1.04


function Outline2(){

window.event.returnValue=0

//Expand or collapse if a list item is clicked.
var open = event.srcElement;

//Verify that the tag which was clicked was either the
//trigger tag or nested within a trigger tag.
var el = checkParent(open,"A");
if(null != el)
{
var incr=0;
var elmPos = 0;
var parentSpan;
var fBreak

//Get the position of the element which was clicked
elemPos = window.event.srcElement.sourceIndex;

//Search for a SPAN tag
for (parentSpan = window.event.srcElement.parentElement;
parentSpan!=null;
parentSpan = parentSpan.parentElement)
{
//test if already at a span tag
if (parentSpan.tagName=="DIV")
{
//alert("Parent Element is a SPAN");
incr=1;
break;
}

//Test if the tag clicked was in a body tag or in any of the possible kinds of lists
//we perform this test because nested lists require special handling
if (parentSpan.tagName=="BODY" || parentSpan.tagName=="UL" || parentSpan.tagName=="OL"|| parentSpan.tagName=="P")
{
//Determine where the span to be expanded is.
for (incr=1; (elemPos+incr) < document.all.length; incr++)
{
//verify we are at an expandable Div tag
if(document.all(elemPos+incr).tagName=="DIV" &&
(document.all(elemPos+incr).className=="expanded" ||
document.all(elemPos+incr).className=="collapsed"))
{
fBreak=1;
break;
}
//If the next tag following the list item (li) is another
//list item(li) return in order to prevent accidentally opening
//the next span in the list
else if(document.all(elemPos+incr).tagName=="LI")
{
return;
}
}
}
//determine if we need to break out of the while loop (kind of a kludge since theres no goto in javascript)
if(fBreak==1)
{
break;
}
}

}
else
{
//Alert("Return!");
return;
}

//Now that we've identified the span, expand or collapse it
if(document.all(elemPos+incr).className=="collapsed")
{

document.all(elemPos+incr).className="expanded"
document.all(elemPos+1).src="../images/bluedrop.gif";
if(open.tagName=="IMG"){open.src="../images/bluedrop.gif";}
if(open.tagName=="B")
{
if(open.parentElement.all.tags("IMG").length != 0)
{open.parentElement.all.tags("IMG").item(0).src="../images/bluedrop.gif";}
}
}
else if(document.all(elemPos+incr).className=="expanded")
{
document.all(elemPos+incr).className="collapsed"
document.all(elemPos+1).src="../images/blueup.gif";
if(open.tagName=="IMG"){open.src="../images/blueup.gif";}
if(open.tagName=="B")
{
if(open.parentElement.all.tags("IMG").length != 0)
{open.parentElement.all.tags("IMG").item(0).src="../images/blueup.gif";}
}
}
else
{
return;
}
event.cancelBubble = true;
// open.scrollIntoView(true);
}

function checkParent(src,dest)
{
//Search for a specific parent of the current element.
while(src !=null)
{
if(src.tagName == dest)
{
return src;
}
src = src.parentElement;
}
return null;
}



<head>
<title>Untitled</title>
<script LANGUAGE="JavaScript" src="../scripts/ExpCollapse.js"></SCRIPT>

</head>
<body>

<a href="#" class="DropDown" onclick="Outline2()" id="ddlink">
<img border=0 src="../images/blueup.gif">NAME OF DROPDOWN
</A><BR>
<DIV id="ExpCol" class="collapsed" border="0"><BR>
<p> text for dropdown goes here. <BR>
</div>
</body>

mwinter
05-29-2005, 04:44 PM
I've posted an example (http://mwinter.webhop.info/dd/collapsible-section/) online. Using the script is fairly simple.

When the script in collapsible-section.js (http://mwinter.webhop.info/dd/collapsible-section/collapsible-section.js) is run, it searches for label elements that contain the word 'collapsible' somewhere in their class attributes. These labels will be used as controls for expanding and collapsing the element identified by the for attribute. If you want, you can use several labels to control the same section: they'll all have the same for attribute value.

The label elements can contain anything - images, text, buttons. If the script runs successfully, it will append an image to the labels to indicate the collapsed or expanded state. These images (and their alternative text) will be updated whenever this state changes. Currently, the names of the images are specified in the collapsible-section.js (http://mwinter.webhop.info/dd/collapsible-section/collapsible-section.js) script as contract.png (http://mwinter.webhop.info/dd/collapsible-section/contract.png) and expand.png (http://mwinter.webhop.info/dd/collapsible-section/expand.png). The final component of the system is dom.js (http://mwinter.webhop.info/dd/collapsible-section/dom.js) which must be loaded before collapsible-section.js (http://mwinter.webhop.info/dd/collapsible-section/collapsible-section.js).

If a section should start collapsed, simply ensure that the class attribute for that element contains the word, 'collapsed'. There is no need to use CSS to do this (in fact, you shouldn't use CSS to do it) - the script will do it for you.

Finally, the script will only run successfully if it can implement all of these features. This is mainly a usability feature. If, for example, the state image cannot be added, then the document may become difficult to use.

The script has been tested on IE 4.01 to 6 SP2, Opera 6.06 to 8.00, NN 4.77 (to make sure it doesn't crash :D), Mozilla 1.3 to 1.7, and Firefox 1.0.4. IE 4.01, Opera 6.06, and NN 4.77 don't support all of the necessary features so all sections will remain exposed. IE 5.01 and Opera 7.03 will run the script as expected.

If you have suggestions, I'll see if I can incorporate them.

Mike

mwinter
05-30-2005, 05:15 PM
I've now tested the script in Konqueror 3.1.4 and it works fine. That means it should also work in Safari.

I would have added this as another edit, but logging out (or perhaps time) won't let me do that. At least this thread will be bumped properly now.

Mike

wishiwasageek
06-01-2005, 12:22 AM
oh mike - this schweet!
thank-you.
I don't suppose I will ever understand javascript but wow - it looks good.
I will compare the two and work out what's different and try to educate myself somewhat.

btw I've only ever seen labels with forms - do you have any links to something intelligent about labels in html? (I've tried googling and thought you may just know of something.)

and not too technically - but what does the dom.js bit do for the other js?

again - you're the bestest everest. thanks!

It's moments like these I need minties and really do wish I was a geek!
WIWAG ;)

wishiwasageek
06-01-2005, 03:05 AM
Post script:
Everything OK in IE 6.0 but images don't show at all in Firefox 1.04 (collapsing works fine)

My HTML file is in D:MAINFOLDER/folder1/folder2/expand.html (but have changed name)
My JS files are in D:MAINFOLDER/scripts/
My Images are in D:MAINFOLDER/images/(blueup.png and bluedown.png)

I edited the contractible-sections.js file as follows:

(function() {
var controls = dom.html.getElementsByClassName(document, 'collapsible', 'label'),
contract = '/images/blueup.png',
expand = '/images/bluedrop.png',
content, current, image;

1. does it matter if expand has been renamed and has an extension .htm as opposed to .html?
2. how do I specify the images to make Firefox happy?

thanx
WIWAG :o

mwinter
06-01-2005, 01:26 PM
I don't suppose I will ever understand javascript but wow - it looks good.Despite its reputation, Javascript (or more formally, ECMAScript) is a very powerful, expressive language. Far more so than most compiled languages (they have their own benefits, though).


I will compare the two and work out what's different and try to educate myself somewhat.That might be difficult as little similarity between my code, and what you took from Microsoft. Though it may look complicated, it's really quite simplistic as it relies on a well-defined relationship between the control element (the labels) and its target (specified in the for attribute). Microsoft's code needs to try and find that relationship.


btw I've only ever seen labels with forms - do you have any links to something intelligent about labels in html?I've always maintained that the HTML specification (http://www.w3.org/TR/html4/) is very readable, but you may not be able to just jump into it until you're at least somewhat familiar with how it's presented.

The label element is predominantly for form controls. The intent is that controls without their own labels (for example, checkboxes) can be given them through the label element. For controls like buttons, the text within the button face acts as the label.

You can use label elements in two ways: implicit association, and explicit. When the for attribute is used, this is considered explicit as the value of that attribute directly references the id of another control:


<label for="myCheckbox">Squares:</label>
<input id="myCheckbox" name="shape" type="checkbox" value="squares">This is particularly useful when controls have to be separate from their labels, such as when you structure a form with a table.

If the for attribute isn't used, the user agent should look for a form control within the label element itself. This is implicit association. You can combine both approaches as long as the label refers to the same form control.

When a label element is given focus - by an access key, or pointing device, for example - that focus is passed on to the associated control. This can make it easier to access that control.

Unfortunately, label support isn't complete in some user agents. NN4 (thankfully now obsolete) doesn't support them at all, and IE (even recent versions) only supports them if the for attribute is used.

That said, there's nothing to say that label elements can't be used for other purposes, as long as you maintain the idea of labelling something.




and not too technically - but what does the dom.js bit do for the other js?The file contains a set of objects and methods that are based around the modules of the Document Object Model (DOM) defined by the W3C. Most of the modules are represented by their own object:


dom
core
html
events
styleThe methods in each object are of one of two types: wrappers or helpers.

As you no doubt know, user agents don't always provide the same features, particularly older ones. The API determines support for certain methods, and produces a consistent interface that I know will always be available.

For instance, there's three possible representations of the document.getElementById method, wrapped by dom.core.getElementById. The first is that the host natively supports getElementById. The wrapper simply needs to call this and return the result. The second is that getElementById isn't directly supported, but it can be emulated (using Microsoft's proprietary all collection, for example). The last is that there's no way to emulate it, so the wrapper creates a function that always returns null.

Clearly the third result doesn't provide a reference like you would hope, but it does mean I can call the wrapper function whenever I want without fear of getting an error because it doesn't exist. I just need to check the return value to see if the call was successful (something that you should always do, anyway).

Helper methods don't provide services that are directly specified by the DOM specifications, but do useful, complex tasks. An example is the dom.html.getElementsByClassName method. This works like the standardised getElementsByTagName method, but allows you to search the document based on both the tag name, and the class attribute.

I've written several versions of that API now, with this being the latest. There are other helper functions that have been included in the past, but as I didn't really need them for the collapsible section code, I left them out.




My Images are in D:MAINFOLDER/images/(blueup.png and bluedown.png)

[...]

contract = '/images/blueup.png',
expand = '/images/bluedrop.png',The URLs you're using for the images are absolute paths (they begin with a single slash). When you use absolute paths on a Web server, the URL is resolved against the host name. That is, if the URL:

&#160;&#160;/images/logo.png

is used in a HTML document, then no matter where on a server that HTML document was found, the URL would always point to:

&#160;&#160;http://www.example.com/images/logo.png

A similar thing should happen on a file system, too. On Windows systems, the slash represents the root directory on the current drive. So, given the path:

&#160;&#160;D:\MainFolder\

the URL points to

&#160;&#160;D:\images\logo.png

This can be the problem with developing on the file system: useful URLs don't really work in a useful way. If you intend to eventually upload files to a Web server, you should develop using a Web server. I have Apache installed on this machine. When I just fiddle around, I just open files off of the file system. With more complex work, I route requests through the local Web server. No time wasted uploading, but all the benefits.


1. does it matter if expand has been renamed and has an extension .htm as opposed to .html?If all of your links point to expand.htm, then no. However, .html is the correct extension - .htm only existed for Windows 3.1 (and the like) which couldn't support long filenames.


2. how do I specify the images to make Firefox happy?You can change the URLs to relative ones:

&#160;&#160;../images/blueup.png

Mike

mr_evans2u
03-06-2007, 08:04 PM
mwinter,

I've noticed that after several minutes the code seems to not be able to find the images. After refreshing it seems to not be able to find any of the code. I have to clear cache to be able to see the page correctly. Have you or anyone else run into this issue?

Thanks