Nested Accordion Menu

I

ibizara

Please could someone help with an issue I have with creating my
accordion menu nested..

Below is an example, the menu itself works fine just not when I try to
nest.

Thanks

---CODE---

<script type="text/javascript" charset="utf-8">
function toggleMe(a,b){
var e = document.getElementById(a);
for (var i = 0, divs = document.getElementById
("container_"+b).getElementsByTagName("div"); i < divs.length; ++i)
divs.style.display = "none";
if (!e)
return true;
if (e.style.display == "none"){
e.style.display = "block";
}else{
e.style.display = "none";
}
return true;
}
</script>

<div id="container_1">
<a href="javascript:;" onclick="return toggleMe('sub_1',1)">Title 1</
a><br />
<div id="sub_1" style="display:none">
Link 1-1<br />
Link 1-2<br />
Link 1-3
</div>
<a href="javascript:;" onclick="return toggleMe('sub_2',1)">Title 2</
a><br />
<div id="sub_2" style="display:none">
Link 2-1<br />
Link 2-2<br />
Link 2-3
</div>
<a href="javascript:;" onclick="return toggleMe('sub_3',1)">Title 3</
a><br />
<div id="sub_3" style="display:none">

<!-- NESTED START -->
<div id="container_2">
<a href="javascript:;" onclick="return toggleMe('sub_3-1',2)">Link
3-1</a><br />
<div id="sub_3-1" style="display:none">
Link 3-1-1<br />
Link 3-1-2<br />
Link 3-1-3
</div>
<a href="javascript:;" onclick="return toggleMe('sub_3-2',2)">Link
3-2</a><br />
<div id="sub_3-2" style="display:none">
Link 3-2-1<br />
Link 3-2-2<br />
Link 3-2-3
</div>
</div>
<!-- NESTED END -->

</div>
</div>
 
I

ibizara

I have got the menu nested now although I am sure there is more than
likely a better way to achieve the same goal.

---CODE---

<script type="text/javascript" charset="utf-8">
function toggleMe(a,b){
var e = document.getElementById(a);
for (var i = 0, divs = document.getElementById
("container_"+b).getElementsByTagName("container_"+b); i <
divs.length; ++i){
divs.style.display = "none";
}
if (!e)
return true;
if (e.style.display == "none"){
e.style.display = "block";
}else{
e.style.display = "none";
}
return true;
}
</script>

<style type="text/css">
.subs{
margin-left: 5px;
}
</style>

<div id="container_1">
<a href="javascript:;" onclick="return toggleMe('sub_1',1)">Title 1</
a><br />
<container_1 id="sub_1" style="display:none" class="subs">
Link 1-1<br />
Link 1-2<br />
Link 1-3
</container_1>
<a href="javascript:;" onclick="return toggleMe('sub_2',1)">Title 2</
a><br />
<container_1 id="sub_2" style="display:none" class="subs">
Link 2-1<br />
Link 2-2<br />
Link 2-3
</container_1>
<a href="javascript:;" onclick="return toggleMe('sub_3',1)">Title 3</
a><br />
<container_1 id="sub_3" style="display:none" class="subs">
<div id="container_2">
<a href="javascript:;" onclick="return toggleMe('sub_3-1',
2)">Link3-1</a><br />
<container_2 id="sub_3-1" style="display:none" class="subs">
Link 3-1-1<br />
Link 3-1-2<br />
Link 3-1-3
</container_2>
<a href="javascript:;" onclick="return toggleMe('sub_3-2',
2)">Link3-2</a><br />
<container_2 id="sub_3-2" style="display:none" class="subs">
<div id="container_3">
<a href="javascript:;" onclick="return toggleMe('sub_3-2-1',
3)">Link3-2-1</a><br />
<container_3 id="sub_3-2-1" style="display:none" class="subs">
Link 3-2-1-1<br />
Link 3-2-1-2<br />
Link 3-2-1-3
</container_3>
<a href="javascript:;" onclick="return toggleMe('sub_3-2-2',
3)">Link3-2-2</a><br />
<container_3 id="sub_3-2-2" style="display:none" class="subs">
Link 3-2-2-1<br />
Link 3-2-2-2<br />
Link 3-2-2-2
</container_3>
</div>
</container_2>
</div>
</container_1>
</div>
 
I

ibizara

I have got the menu nested now although I am sure there is more than
likely a better way to achieve the same goal.

---CODE---

<script type="text/javascript" charset="utf-8">
function toggleMe(a,b){
        var e = document.getElementById(a);
        for (var i = 0, divs = document.getElementById
("container_"+b).getElementsByTagName("container_"+b); i <
divs.length; ++i){
                divs.style.display = "none";
        }
        if (!e)
        return true;
        if (e.style.display == "none"){
                e.style.display = "block";
        }else{
                e.style.display = "none";
        }
        return true;}

</script>

<style type="text/css">
        .subs{
                margin-left: 5px;
        }
</style>

<div id="container_1">
        <a href="javascript:;" onclick="return toggleMe('sub_1',1)">Title 1</
a><br />
        <container_1 id="sub_1" style="display:none" class="subs">
                Link 1-1<br />
                Link 1-2<br />
                Link 1-3
        </container_1>
        <a href="javascript:;" onclick="return toggleMe('sub_2',1)">Title 2</
a><br />
        <container_1 id="sub_2" style="display:none" class="subs">
                Link 2-1<br />
                Link 2-2<br />
                Link 2-3
        </container_1>
        <a href="javascript:;" onclick="return toggleMe('sub_3',1)">Title 3</
a><br />
        <container_1 id="sub_3" style="display:none" class="subs">
                <div id="container_2">
                        <a href="javascript:;" onclick="return toggleMe('sub_3-1',
2)">Link3-1</a><br />
                        <container_2 id="sub_3-1" style="display:none" class="subs">
                                Link 3-1-1<br />
                                Link 3-1-2<br />
                                Link 3-1-3
                        </container_2>
                        <a href="javascript:;" onclick="return toggleMe('sub_3-2',
2)">Link3-2</a><br />
                        <container_2 id="sub_3-2" style="display:none" class="subs">
                                <div id="container_3">
                                        <a href="javascript:;" onclick="return toggleMe('sub_3-2-1',
3)">Link3-2-1</a><br />
                                        <container_3 id="sub_3-2-1" style="display:none" class="subs">
                                                Link 3-2-1-1<br />
                                                Link 3-2-1-2<br />
                                                Link 3-2-1-3
                                        </container_3>
                                        <a href="javascript:;" onclick="return toggleMe('sub_3-2-2',
3)">Link3-2-2</a><br />
                                        <container_3 id="sub_3-2-2" style="display:none" class="subs">
                                                Link 3-2-2-1<br />
                                                Link 3-2-2-2<br />
                                                Link 3-2-2-2
                                        </container_3>
                                </div>
                        </container_2>
                </div>
        </container_1>
</div>


---

Ahh slight problem the made up tag names only works with FF and not
IE :( so still need a little help please.

Thanks
 
T

Thomas 'PointedEars' Lahn

Jeremy said:
I find it very hard to believe this code works reliably.

Though slightly off-topic, I strongly recommend AGAINST nested menus for
accessibility reasons. In fact, I am slowly removing them from the web
site I am responsible for.


You cannot simply make up your own tags.

To be fair, the OP is not making up anything *here*. However, it depends
very much on the DOM (thus, on the UA), on the document type and layout mode
which element objects will be found with the getElementsByTagName() method.
[...]
</script>

<style type="text/css">
.subs{
margin-left: 5px;
}
</style>

Let's hope that all this is just invalid HTML and not cluelessly written
XHTML, for otherwise the script element would not be well-formed because of
the unescaped `<', and </head> and <body> would be missing here, too.

In any case, I would recommend not to omit those two tags. In particular,
the `script' element is allowed both within the `head' element and the
`body' element; it may not be obvious where the `head' element ends and the
`body' element begins, even though it could be deduced by the parser from
the `style' element, which only belongs within the `head' element.
Invalid href. Best to have the href point to a valid target. If you
*must*, use href="#" as the target.

Certainly not invalid, but very unwise. Syntactically, `javascript:;' is a
valid absolute URI as per RFC 3986; however, there will be a hyperlink that
is not really a hyperlink (doesn't navigate), and it will not work without
support for the `javascript:' URI scheme (and may generate errors when
clicked), but it will be displayed anyway. See also the FAQ.
Wrong, wrong, wrong, wrong, wrong.
Simply overbrimming in wrongability.

Well, to be fair, it depends. Since the OP uses XHTML tag style and we have
not seen the DOCTYPE declaration yet, there is the remote possibility that
the DTD or the internal subset declares this element. The only thing left
to be found would be a user agent that renders it properly. But then, it
might be server-side code which is transformed before being served, or it
may be transformed client-side with XSLT. (I'm only talking about
possibilities here; the rest of the code rather shows signs of cluelessness
at work.)


PointedEars
 
T

Thomas 'PointedEars' Lahn

Jeremy said:
Though slightly off-topic, I strongly recommend AGAINST nested menus for
accessibility reasons. In fact, I am slowly removing them from the web
site I am responsible for.

Hm, wouldn't that mean that several common GUIs, including those of
Microsoft Windows, and several window managers like KDE and GNOME,
are not accessible? I find that hard to believe.

Maybe it is more a matter of how these nested menus are implemented.


PointedEars
 
J

Jeremy J Starcher

Hm, wouldn't that mean that several common GUIs, including those of
Microsoft Windows, and several window managers like KDE and GNOME, are
not accessible? I find that hard to believe.

Maybe it is more a matter of how these nested menus are implemented.

As a challenge from a blind friend, I did try using a screen-reader on a
number of websites as well as on the OS itself.

Within well-written applications that used one of the standard widget
sets, the screen-reader could tell the menu bar and only read off the
entries when requested.

I was not able to find a site with a screen-reader friendly drop-down
menu. The best ones used a nested-list structure and one could "skip-to-
next-element." I'll admit that my experience wasn't the world's most
intense, but it did open my eyes to things.
 
J

Jeremy J Starcher

To be fair, the OP is not making up anything *here*. However, it
depends very much on the DOM (thus, on the UA), on the document type and
layout mode which element objects will be found with the
getElementsByTagName() method.

True, though I did assume the OP intended HTML due to a lack of any other
context.
[...]
</script>

<style type="text/css">
.subs{
margin-left: 5px;
}
</style>

Let's hope that all this is just invalid HTML and not cluelessly written
XHTML, for otherwise the script element would not be well-formed because
of the unescaped `<', and </head> and <body> would be missing here, too.

In any case, I would recommend not to omit those two tags. In
particular, the `script' element is allowed both within the `head'
element and the `body' element; it may not be obvious where the `head'
element ends and the `body' element begins, even though it could be
deduced by the parser from the `style' element, which only belongs
within the `head' element.
Invalid href. Best to have the href point to a valid target. If you
*must*, use href="#" as the target.

Certainly not invalid, but very unwise. Syntactically, `javascript:;'
is a valid absolute URI as per RFC 3986; however, there will be a
hyperlink that is not really a hyperlink (doesn't navigate), and it will
not work without support for the `javascript:' URI scheme (and may
generate errors when clicked), but it will be displayed anyway. See
also the FAQ.

I was looking for a better word than invalid.
Well, to be fair, it depends. Since the OP uses XHTML tag style and we
have not seen the DOCTYPE declaration yet, there is the remote
possibility that the DTD or the internal subset declares this element.
The only thing left to be found would be a user agent that renders it
properly. But then, it might be server-side code which is transformed
before being served, or it may be transformed client-side with XSLT.
(I'm only talking about possibilities here; the rest of the code rather
shows signs of cluelessness at work.)

Again, under the lack of any other direction, I could only assume this
code was being fed directly into the UA. The reference to working in one
UA and not another re-enforced that.

In a fair world. UAs would reject invalid markup and enforce compliance.
 
I

ibizara

Thank you everyone for showing me the errors of my way :)
I got it all working in the end and I have provided the code below..
if anyone can pick holes in it please do to help me learn.

Thanks again

---CODE---

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Menu Demo</title>
<script type="text/javascript" charset="utf-8">
function toggleMe(a,b){
var e = document.getElementById(a);
for (var i = 0, containers = document.getElementById
('container'+b).getElementsByTagName('span'); i < containers.length; +
+i){
containers.style.display = "none";
}
if (!e){
return true;
}else{
e.style.display = "block";
return true;
}
}
</script>

<style type="text/css">
..subs{
margin-left: 5px;
}
</style>

</head>
<body>
<div id="container1">
<a href="javascript:;" onclick="return toggleMe('a',1);">Title 1</
a><br>
<span id="a" style="display:none" class="subs">
Link 1-1<br>
Link 1-2<br>
Link 1-3
</span>
<a href="javascript:;" onclick="return toggleMe('b',1);">Title 2</
a><br>
<span id="b" style="display:none" class="subs">
Link 2-1<br>
Link 2-2<br>
Link 2-3
</span>
<a href="javascript:;" onclick="return toggleMe('c',1);">Title 3</
a><br>
<span id="c" style="display:none" class="subs">
<div id="container2">
<a href="javascript:;" onclick="return toggleMe('d',2);">Link 3-1</
a><br>
<span id="d" style="display:none" class="subs">
Link 3-1-1<br>
Link 3-1-2<br>
Link 3-1-3
</span>
<a href="javascript:;" onclick="return toggleMe('e',2);">Link 3-2</
a><br>
<span id="e" style="display:none" class="subs">
<div id="container3">
<a href="javascript:;" onclick="return toggleMe('f',3);">Link
3-2-1</a><br>
<span id="f" style="display:none" class="subs">
Link 3-2-1-1<br>
Link 3-2-1-2<br>
Link 3-2-1-3
</span>
<a href="javascript:;" onclick="return toggleMe('g',3);">Link
3-2-2</a><br>
<span id="g" style="display:none" class="subs">
Link 3-2-2-1<br>
Link 3-2-2-2<br>
Link 3-2-2-3
</span>
</div>
</span>
</div>
</span>
</div>
</body>
</html>
 
J

Jeremy J Starcher

Thank you everyone for showing me the errors of my way :) I got it all
working in the end and I have provided the code below.. if anyone can
pick holes in it please do to help me learn.

[ Code Snipped ]

Turn off Javascript and try your menu.

An estimated 10% of web users do not enable Javascript, either by choice
or by corporate decree.

I recommend the following rule of thumb:
Make it work WITHOUT Javascript, then add Javascript if you wish.

I have already recommended using CSS menus. I will simply provide a
couple of links to show you what I mean, further discussion on them is
off-topic for this group. (I don't actually use any of these myself,
they are provided as examples only to show what is possible.)

http://www.howtocreate.co.uk/tutorials/testMenu.html

http://www.smashingmagazine.com/2007/03/14/css-based-navigation-menus-
modern-solutions/
 
T

Thomas 'PointedEars' Lahn

ibizara said:
Thank you everyone for showing me the errors of my way :)
I got it all working in the end and I have provided the code below..
if anyone can pick holes in it please do to help me learn.

Thanks again

---CODE---

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

Declare HTML 4.01 Transitional and also use the system identifier, the DTD URL.
<html>
<head>
<title>Menu Demo</title>
<script type="text/javascript" charset="utf-8">

Instead of declaring the encoding of the script ressource, which is
pointless because it is not linked here, you should declare the encoding of
the document. Use the HTTP `Content-Type' header and, as a fallback,

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<http://www.w3.org/TR/html401/struct/links.html#adef-charset>
function toggleMe(a,b){
var e = document.getElementById(a);
for (var i = 0, containers = document.getElementById
('container'+b).getElementsByTagName('span'); i < containers.length; +
+i){
containers.style.display = "none";


Several feature tests are missing above.
}
if (!e){
return true;
}else{

You don't need `else' here.
e.style.display = "block";

Better yet, reset the `display' property to its initial value:

e.style.display = "";
return true;
}
}
</script>

<style type="text/css">
..subs{

There is one extra dot.

margin-left: 5px;
}
</style>

</head>
<body>
<div id="container1">
<a href="javascript:;" onclick="return toggleMe('a',1);">Title 1</
a><br>

Still nothing works without client-side script support.
[...]
<span id="c" style="display:none" class="subs">
<div id="container2">

A `span' element MUST NOT contain a `div' element.

<http://validator.w3.org/>


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top