Robert Pessagno

Navigation

Skip navigation.

Search

Site navigation

Email conversation

FromRobert Pessagno
ToMe
SubjectHelp with expanding menu script
Date9 February 2010 18:08
Hi Mark,

I would like to use your expanding menu script because it is simple and
works with correct markup for accessibility. But I am not very good with
JavaScript, so I was wondering if you could me help me out.

I see that the menu works with an ID placed on the <ul>, and that there can
be multiple IDs for each <ul> that is added. Is it possible to just have a
<div>, let's say "leftnav," and have the script call work for each <ul> that
is inside it? I am building a template that can be easily used by people who
use Dreamweaver, so I don't want them to have to go inside the scripts, or
have to add IDs on each <ul>. I would like the script to just work with
however many <ul>'s there are inside a single <div>. Is that possible? I
hope I am being clear. If not let me know I can try to rephrase.

Thank you for your time, and for the awesome script!

-- Robert
FromMe
ToRobert Pessagno
SubjectRe: Help with expanding menu script
Date12 February 2010 08:21
Robert,

> Is it possible to just have a
> <div>, let's say "leftnav," and have the script call work for each <ul>
> that is inside it?

The script itself does not provide this functionality, since it expects the
author to be in control of where they want to apply it. However, you could
fairly easily make it work with a little script of your own that searches
for all ULs directly inside that DIV, assigns them an ID, then calls my
script, passing it that new ID.

Something like this:

var oDiv = document.getElementById('leftnav'), ul;
for( var i = 0; i < oDiv.childNodes.length; i++ ) {
  ul = oDiv.childNodes[i];
  if( ul.tagName && ul.tagName.toLowerCase() == 'ul' ) {
    if( !ul.id ) {
      ul.id = 'leftnav_list'+i;
    }
    compactMenu(ul.id,true,'&plusmn; ');
  }
}

Of course, if the ULs are not direct children of the DIV, this would need a
more clever script that looks at all UL descendants of the DIV, and excludes
any that are children of an LI (since they will be part of a nested list).

var oDiv = document.getElementById('leftnav'), ul;
var oULs = oDiv.getElementsByTagName('ul');
for( var i = 0; i < oULs.length; i++ ) {
  ul = oULs[i];
  if( ul.parentNode.tagName.toLowerCase() != 'li' ) {
    if( !ul.id ) {
      ul.id = 'leftnav_list'+i;
    }
    compactMenu(ul.id,true,'&plusmn; ');
  }
}

Hope this helps.


Mark 'Tarquin' Wilton-Jones - author of http://www.howtocreate.co.uk/
FromRobert Pessagno
ToMe
SubjectRe: Help with expanding menu script
Date16 February 2010 22:42
Wow, you are a true master of JavaScript. I can't thank you enough for doing
this. I implemented it today and it works perfectly. I am not at all good at
writing JavaScript, so I really appreciate the help!
FromRobert Pessagno
ToMe
SubjectNeed help with integrating cookies
Date25 February 2010 19:34
Attachmentincluded below
Hi Mark,

I'm trying to integrate the cookie script into the collapsing menu function
so it remembers the state it was in, but I'm having some trouble. I saved a
document called cookie.js with the script you wrote, and then called it out
in the head. But you wrote some custom code for me a couple weeks ago, so I
don't if I'm integrating it correctly. I attached a text file with what's in
the head; could you take a look at it to see if there's something wrong? If
you need me to send more I code I'd be glad to do so.

Thank you!

-- Robert

<script type="text/javascript" src="../scripts/listCollapse.js"></script>
<script src="../scripts/cookie.js" type="text/javascript" language="javascript"></script>
<script type="text/javascript">
window.onload = function () {

<!-- Expanding / Collapsing Left Navigation -->
var oDiv = document.getElementById('leftnav'), ul;
  for( var i = 0; i < oDiv.childNodes.length; i++ ) {
    ul = oDiv.childNodes[i];
    if( ul.tagName && ul.tagName.toLowerCase() == 'ul' ) {
    if( !ul.id ) {
      ul.id = 'leftnav_list'+i;
      }
    compactMenu(ul.id,true,'<span class="collapse"></span>');
    stateToFromStr('leftnav',retrieveCookie('menuState'));

    }
    window.onunload = function () {
    setCookie('menuState',stateToFromStr('leftnav'));
    }
  }
}
</script>
FromMe
ToRobert Pessagno
SubjectRe: Need help with integrating cookies
Date13 March 2010 12:59
Robert,

> I'm trying to integrate the cookie script into the collapsing menu
> function so it remembers the state it was in

<!-- Expanding / Collapsing Left Navigation -->
This is a HTML comment, not a JavaScript comment. It does not belong in
JavaScript.

You have the wrong idea about how the loop works.

stateToFromStr('leftnav',retrieveCookie('menuState'));

This line cannot work. It expects the ID of the *list*, not the ID of the
div that the list is inside. In addition, it would need to have differently
named cookies for each list - you already have a unique ID for each list, so
that can be used to create a unique cookie name.

Something like this would probably work:
stateToFromStr(ul.id,retrieveCookie('menuState'+ul.id));

window.onload = function () {
  ...
  for( var i = 0; i < oDiv.childNodes.length; i++ ) {
    ...
    window.onunload = function () {
      setCookie('menuState',stateToFromStr('leftnav'));
    }
  }
}

This is a mess :)

1. You create the onunload event handler inside the onload event handler.
While this may work, it is pointless in this case. It is normal
to create the onunload event handler outside the onload handler, so it does
not have to wait for onload before it sets up the onunload handler.

2. You set up onunload inside a for loop. This means that every time it runs
through the loop (once for each list), it will recreate the exact same event
handler - only one is allowed per page so the subsequent ones just overwrite
it. The onunload event handler should not be put inside a for loop.

3. This line cannot work:
setCookie('menuState',stateToFromStr('leftnav'));
It is once again trying to get the state from a *div* instead of the
individual lists. As I said in my last email, the script only understands
lists, and only one at a time. What you need to do is to make a for loop
inside the onunload event handler that searches through all lists inside the
div, and sets a unique cookie for each of them (matching the cookie name
used when retrieving them). This is basically the same approach as you will
need to use for *every* command you want to run against all lists in your
div.

4. Minor cosmetic issue:
whatever = function () {...}
This is an assignment statement, and should end with a ; character.
whatever = function () {...};

This should work (untested):

window.onload = function () {
  //Expanding / Collapsing Left Navigation
  var oDiv = document.getElementById('leftnav'), ul;
  for( var i = 0; i < oDiv.childNodes.length; i++ ) {
    ul = oDiv.childNodes[i];
    if( ul.tagName && ul.tagName.toLowerCase() == 'ul' ) {
      if( !ul.id ) {
        ul.id = 'leftnav_list'+i;
      }
      compactMenu(ul.id,true,'<span class="collapse"></span>');
      stateToFromStr(ul.id,retrieveCookie('menuState'+ul.id));
    }
  }
};
window.onunload = function () {
  var oDiv = document.getElementById('leftnav'), ul;
  for( var i = 0; i < oDiv.childNodes.length; i++ ) {
    ul = oDiv.childNodes[i];
    if( ul.tagName && ul.tagName.toLowerCase() == 'ul' ) {
      setCookie('menuState'+ul.id,stateToFromStr(ul.id));
    }
  }
};

If you have any problems understanding any of these concepts, please work
through my JavaScript tutorial:
http://www.howtocreate.co.uk/tutorials/javascript/important

Tarquin
FromRobert Pessagno
ToMe
SubjectRe: Need help with integrating cookies
Date1 April 2010 21:49
It worked! Wow, thank you again for your help.
This site was created by Mark "Tarquin" Wilton-Jones.
Don't click this link unless you want to be banned from our site.