Skip navigation
ryry0909
Currently Being Moderated

How to highlight current page on a Spry Menu Bar?

Mar 26, 2010 11:56 AM

Hi,

 

I am a Final Year Student in university, and I have created a website using a Spry Menu Bar (CS4).

 

I would like to have the navigation bar stay highlighted for the current page.

 

So if i click 'home' and it goes to the index page, then the 'Home' should stay highlighted and likewise if I go to services, it should keep services hightlighted when I am on the services page.

 

Can anyone help?

 

Thanks,

 

Ryan

 
Replies
  • Currently Being Moderated
    Mar 26, 2010 4:37 PM   in reply to ryry0909

    Hi Ryan,

     

    Place the following code in the <HEAD>-section of your document.

     

    <script src="SpryAssets/SpryDOMUtils.js"  type="text/javascript"></script> // dont' forget to add to your document

    <script  type="text/javascript" language="javascript">
    function InitPage() {
    Spry.$$('#MenuBar1  li').forEach(function(node){
        var  a=node.getElementsByTagName("a")[0]; // finds all a elements inside the li, but we only want the first  so [0]
        if(a.href == window.location){
             Spry.Utils.addClassName(node,"activeMenuItem");
        }
    });
    }
    Spry.Utils.addLoadListener(InitPage);
    </script>

    <style  type="text/css"> // styling the activeMenuItem
    .activeMenuItem {
        font-weight: bold;
    }
    </style>

     

     

    I hope this helps.

    Ben

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 29, 2010 4:54 AM   in reply to ryry0909

    Hi Ryan,

     

    ryry0909 wrote:

     

    Hi Ben,


    Can I maybe upload my code for you to look at?

     

    Cheers

    Yes, please do.

    Ben

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 29, 2010 5:53 PM   in reply to ryry0909

    Hi,

     

    All I did when I received your code was to

    1. add SpryDOMUtils.js into the SpryAssets folder
    2. add the JavaScript and Style-rule to the document

    and it worked fine albeit for the first page (index.html) only.

     

    The reason for this  is because the JavaScript through if(a.href == window.location) checks to see if the link reference is the same as the URL reference. Par example, if we look at the following menu item <li><a href="index.html">Home</a></li> and we land on index.html an  activeMenuItem class name will be added to the code through Spry.Utils.addClassName(node,"activeMenuItem"). Our style rule then tells the markup to highlite the font.

     

    If the link reference does not equal the page URL as in <li><a href="#">Home</a></li> then the class will not be added and no highlighting takes place.

     

    Having said the above, parent items will not be affected, thus only the menu item itself will be highlighted.

     

    I hope the above helps.

    Ben

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 30, 2010 12:15 PM   in reply to ryry0909

    Hello,

     

    If Bens solution doesn't work out. Take a look at my patch. It doesn't require SpryDOMUtils.js to be loaded in advance and uses SpryMenuBar methods and elements where possible.

     

    Installation:

     

    Place the following piece of code, directly under the constructor ( var MenuBar1 = new Spry.Widget... ):

     

    (function( menubar, className, anchorsonly ){
         // get all <a> elments that are inside your menubar
         var a = menubar.element.getElementsByTagName( "a" ),
              i = a.length,
              location = window.location,
              widget = Spry.Widget.MenuBar.prototype,
              updateLI = function( element ){
                   parent = element.parentNode;
                   
                   while( parent && parent !== menubar.element ){
                        if( parent.nodeName.toLowerCase() == 'li' ){
                             widget.addClassName.apply( 
                                  widget, 
                                  [ 
                                       !anchorsonly ? parent : parent.getElementsByTagName("a")[0], 
                                       className 
                                  ]
                             );
                        }
                        
                        parent = parent.parentNode;
                   }
              };
         
         // loop over all a elements and check if we have one that matches
         while( i-- ){
              if( a[i].href == location ){
                   widget.addClassName.apply( 
                        widget, 
                        [ 
                             !anchorsonly ? a[i].parentNode : a[i], 
                             className 
                        ]
                   );
                   
                   updateLI( a[i] );
                   break; // we found what we are looking for, stop the loop
              }
         }
    }( MenuBar1, "MenuBarItemActive", true ))
    

     

    You can ignore the complete contents of the patch / script. There only 2 options you can and might want to configure. The options are added at the bottom of the script

     

    ( MenuBar1, "MenuBarItemActive", true ))
    

     

    MenuBar1 is the JavaScript variable that is created for the SpryMenuBar for example, if this is your widget constructor:

     

    var MenuBar22 = new Spry.Widget.MenuBar("MenuBar22", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"});
    

     

    You should replace the MenuBar1 with MenuBar22. The second option, is the name of the classname that will be added to the element. By default this will be MenuBarActive. But you can change it to anything you wish. And the last one tells allows you to specify where the to put the className. To the a element or its parent.

     

     

    Complete Example code

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Untitled Document</title>
    <script src="SpryAssets/SpryMenuBar.js" type="text/javascript"></script>
    <link href="SpryAssets/SpryMenuBarHorizontal.css" rel="stylesheet" type="text/css" />
    <style type="text/css">
         #MenuBar1 li.MenuBarItemActive a{ background:pink}
    </style>
    </head>
    
    <body>
    <ul id="MenuBar1" class="MenuBarHorizontal">
         <li><a class="MenuBarItemSubmenu" href="poke.html">Item 1</a>
              <ul>
                   <li><a href="ping.html">Item 1.1</a></li>
                   <li><a href="pong.html">Item 1.2</a></li>
                   <li><a href="cows-moo.html">Item 1.3</a></li>
              </ul>
         </li>
         <li><a href="tweep.html">Item 2</a></li>
         <li><a class="MenuBarItemSubmenu" href="fake.html">Item 3</a>
              <ul>
                   <li><a class="MenuBarItemSubmenu" href="url.html">Item 3.1</a>
                        <ul>
                             <li><a href="pink.html">Pink</a></li>
                             <li><a href="purple.html">Item 3.1.2</a></li>
                        </ul>
                   </li>
                   <li><a href="zoom.html">Item 3.2</a></li>
                   <li><a href="random.html">Item 3.3</a></li>
              </ul>
         </li>
         <li><a href="tweep.php">Item 4</a></li>
    </ul>
    <script type="text/javascript">
    var MenuBar1 = new Spry.Widget.MenuBar("MenuBar1", {imgDown:"SpryAssets/SpryMenuBarDownHover.gif", imgRight:"SpryAssets/SpryMenuBarRightHover.gif"});
    
    (function( menubar, className, anchorsonly ){
         // get all <a> elments that are inside your menubar
         var a = menubar.element.getElementsByTagName( "a" ),
              i = a.length,
              location = window.location,
              widget = Spry.Widget.MenuBar.prototype,
              updateLI = function( element ){
                   parent = element.parentNode;
                   
                   while( parent && parent !== menubar.element ){
                        if( parent.nodeName.toLowerCase() == 'li' ){
                             widget.addClassName.apply( 
                                  widget, 
                                  [ 
                                       !anchorsonly ? parent : parent.getElementsByTagName("a")[0], 
                                       className 
                                  ]
                             );
                        }
                        
                        parent = parent.parentNode;
                   }
              };
         
         // loop over all a elements and check if we have one that matches
         while( i-- ){
              if( a[i].href == location ){
                   widget.addClassName.apply( 
                        widget, 
                        [ 
                             !anchorsonly ? a[i].parentNode : a[i], 
                             className 
                        ]
                   );
                   
                   updateLI( a[i] );
                   break; // we found what we are looking for, stop the loop
              }
         }
    }( MenuBar1, "MenuBarItemActive", true ))
    </script>
    </body>
    </html>

     

    Copy paste example and save a pink.html As you will now notice. Item 3, Item 3.1 and Pink are now colored pink .

     

    Happy hacking !

     
    |
    Mark as:
  • Currently Being Moderated
    Mar 30, 2010 12:56 PM   in reply to ryry0909

    I have done this on another site before. To do this, in the css for the spry menu i put

     

    #here {
         background-color: #7A8FBC;
         color:#FFF;
    }

     

     

     

    You can change the background color and such. Once you create the style apply it to the button that you want to stay highlighted.

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 6, 2010 2:23 PM   in reply to ryry0909

    I have a simliar situation but with a few levels of complexity that makes me unsure if this is possible or how to do this.

     

    1) The top level navigation items that have submenus are NOT hyperlinks, just category titles to give access to the second and third level navigation items.

     

    2) I have the header (logo, tagline and spry navigation band) as in include since there are 30+ pages in the site and the client wants to be able to easily modify the navigation links text.

     

    3) The "Contact" top level navigtion item does not have a submenu. I'd like this to also be in the hover state (cream background/gray text) when on the Contact page.

     

    With these issues in mind, is there any way to have the top level navigation item be in the hover state (cream background/gray text) when a user is on a second or third level page?

     

    Here is a link to my beta site.

     

    ** M

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 6, 2010 7:40 PM   in reply to alovell15

    Note first that this all refers to Spry Menu Bars, that come with extensive and specific CSS files.

     

    I periodically answer this question.

     

    Because your menu is "persistent", at least it looks like the same menu page to page, it is easy to think that you are looking at a way to make the menu item show "persistently." This is an incorrect assessment.

     

    You are actually looking at menus that are contextual to the page they are sitting on. This is easy to do by giving each page body (or menu-enclosing div) a unique id AND each menu item a unique id. I code them so they are similar:

     

    body#contactuspage

    ...

    li#contactus

     

    Then, in the CSS for the menubar, find the hover state (if that is the state you want to mimic) and ADD code (additional selectors to that rule) so that you have a selector like this:

     

    body#contactuspage li#contactus that "pinpoints" or focuses on the specific menu item on its own specific page.

     

     

    /* Menu items that are open with submenus are set to MenuBarItemHover
    with a blue background and white text */
    ul.MenuBarHorizontal a.MenuBarItemHover, 
    ul.MenuBarHorizontal a.MenuBarItemSubmenuHover, 
    ul.MenuBarHorizontal a.MenuBarSubmenuVisible,
    body#contactuspage ul.MenuBarHorizontal li#contactus a
    {
         background-color: #33C;
         color: #FFF;
    }
    
    

     

    Be sure to add commas between selectors (except after the last one before the rules). You will be styling the link (the a); because previous rules have set it to display:block; your entire list item should style.

     

    This method requires that every menu item that you want to affect get its own unique ID and that every page or enclosing container have an editable attribute, so you can put that different id on every page.

     

    Happy styling!

     

    Beth

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 7, 2010 9:58 AM   in reply to Zabeth69

    I think I'm really close! It must be a syntax issue that I'm not understanding.

     

    -- Your instructions work beautifully for the Contact page - which has no submenu from the top level navigation.

     

    I've tried implementing the same thing for the 2nd level pages (mission, about, ca disclosure) under "Transformative Living."

    -- The good news is that "Transformative Living" on the top nav stays focused when on a sub-page

    -- The bad news is that if you go back into the "Transformative Living" menu, all the sub-menu items are also in the focus state

     

    Here's the code I have:

    On the 3 sub-menu pages (mission, about, ca disclosure) I have:

        <body id="tlpage">

     

    In the header.html include I have:

          <li id="tl"><a class="MenuBarItemSubmenu">Transformative Living</a>

     

    In the SpryMenuBarHorizontal.css file I have:

    ul.MenuBarHorizontal a.MenuBarItemHover,
    ul.MenuBarHorizontal a.MenuBarItemSubmenuHover,
    ul.MenuBarHorizontal a.MenuBarSubmenuVisible,
    body#contactuspage ul.MenuBarHorizontal li#contactus a,
    body#tlpage ul.MenuBarHorizontal li#tl a
    {
        background-color: #f0e7d9;
        color: #333;
    }

     

    I'm guessing the issue is that the SubmenuHover is in the block of code in the SpryMenuBarHoiritontal.css but I'm too new at this to know if I'm even looking in the right place or  what to change so that only the top level nav item is in the Hover state, not all the section navigation items, when on a sub-subpage.

     

    I haven't attempted this to any of the 3rd level items yet!

     

    ** M

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 7, 2010 10:51 AM   in reply to burgertime23

    One thing to realize is that, as you have discovered, when you style an a link by 'focusing' on it in CSS, it will style ALL "a" links in that descendancy, top level and submenus alike.

     

    You need to go in and "turn off" the styling on the submenus, if you do not want it. Be sure to put the new "turning-off" rules BELOW the "turning-on" rules in the style sheet!

     

    So if you style

    body#tlpage ul.MenuBarHorizontal li#tl a
    

    you are also styling

    body#tlpage ul.MenuBarHorizontal li#tl ul a
    and
    body#tlpage ul.MenuBarHorizontal li#tl ul ul a
    

     

    in other words, all the "a"s that appear (no matter how deep) inside an li#tl

     

    This should make it clear what to "unstyle"

    li#tl ul a, 
    li#tl ul ul a,
    ...[etc]
    {background-color: transparent; /*or whatever the original color-style was*/
         color: #000; /*or whatever the original color-style was*/
         }
    

    You might need to monkey with the positioning of this rule. Just drag it up and down in the style sheet until you get the reactions you want.

     

    Beth

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 9, 2010 12:37 AM   in reply to Zabeth69

    I have a different issue again with highlighting the current page. Firstly I am using Spry Collapsible Panels for my horizontal menu, but I am also forced for complicated reasons to use a separate _frame_ for my menu. Obviously the method of styling menu items on each separate page won't work for me.

     

    I'm wondering whether either of the other methods (SpryDOMUtils.js or the patch from Arnout Kazemier) described in this thread would work on my menu frame.

     

    (I could go ahead and try desperately to see if I could manage to implement one or the other, but since I'm a Spry and Javascript ignoramus, I probably won't be able to figure out why it doesn't work.)

     

    Can anyone advise me please?

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 12, 2010 3:20 PM   in reply to jhp_melbourne

    Please please please start a new thread. Your question is not the same as the original poster's question.

     

    Beth

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 12, 2010 4:34 PM   in reply to Zabeth69

    Thank you for all your help. The navigation was becoming more complicated than I think the client would be comfortable working with. She wants to be able to make updates on her own so with that in mind I suggested adding a standard breadcrumbing method to the lower level pages instead of having the top cateogry "tab" highlighted.

     

    This forum has been fantastic and I really appreciate the time and effort you have spent to help me. And the client loves the way the navigation turned out.

     

    Thank you very, very much!

    --M

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 12, 2010 4:48 PM   in reply to burgertime23

    I'm so happy to hear that!

     

    Come again!

     

    Beth

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 28, 2011 12:06 PM   in reply to Ben Pleysier

    Ben and others,

    I am trying to find an easy way to highlight current page on a Spry Menu Bar and found your post. Very frustrating

    I cannot find SpryAssets/SpryDOMUtils.js and I have just updated my Spry to the latest (1.6.1)  for CS4. I ran the updater then looked in all folders and it's not there. Huh?

    By the way I use templates throughout..and this seems to be a limiting factor for some solutions

    Any idea?

    Thanks,

    Rick

     
    |
    Mark as:
  • Currently Being Moderated
    Apr 28, 2011 2:35 PM   in reply to RickRoo
     
    |
    Mark as:
  • Currently Being Moderated
    Apr 28, 2011 6:05 PM   in reply to Ben Pleysier

    Thanks Gramps !!!!!

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points