jQuery Vertical Menu - Active State

Hi,

I am trying to implement a jQuery expandable menu (see code).  I would like for the chosen link/page to remain active when you go to that page.  

I don't know if I should do this by placing the code on every page, or if I could do an include file.  There will be a lot of pages.  In either case though, I need an active state for the Sub Items (i.e. a different color, or background image) to remain active while on the active page, and the "Main Item" heading it's under to remain open.  The Main Items will be links to pages too.

If you have other coding I should start with besides this one, I'm open to that too.  This was just my starting point.

Any suggestions?
Thank you!

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

<style type="text/css">
#menu {padding:0; margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px;}
#menu a:hover {text-decoration:underline;}
#menu dt b, #menu dt a {display:block; font-weight:bold;  line-height:25px; cursor:pointer; width:200px;  background-color:#CCC; padding-left:5px;}
#menu dt b {background:url(arrow.gif) no-repeat left center; background-color:#CCC;}
#menu dt a {color:#000; text-decoration:none;}
#menu dd {padding:0; margin:0;}
#menu dd ul {padding:0; margin:0; list-style:none;}
#menu dd ul li {padding-left:20px;}
#menu dd ul li a {text-decoration:none; color:#000000;}
</style>

<script src="js/jquery-1.2.6.min.js" type="text/javascript"></script>

<script type="text/javascript">
$(document).ready(function(){
	if($("#menu")) {
		$("#menu dd").hide();
		$("#menu dt b").click(function() {
			if(this.className.indexOf("clicked") != -1) {
				$(this).parent().next().slideUp(200);
				$(this).removeClass("clicked");
			}
			else {
				$("#menu dt b").removeClass();
				$(this).addClass("clicked");
				$("#menu dd:visible").slideUp(200);
				$(this).parent().next().slideDown(500);
			}
			return false;
		});
	}
});
</script>
</head>

<body>
  <dl id="menu">
    <dt><b><a href="#url">Main Item 1</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 1</a></li>
        <li><a href="#url">Sub Item 2</a></li>
        <li><a href="#url">Sub Item 3</a></li>
        <li><a href="#url">Sub Item 4</a></li>
      </ul>
    </dd>
    <dt><b><a href="#url">Main Item 2</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 5</a></li>
        <li><a href="#url">Sub Item 6</a></li>
        <li><a href="#url">Sub Item 7</a></li>
        </ul>
      </dd>
    <dt><b><a href="#url">Main Item 3</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 8</a></li>
        <li><a href="#url">Sub Item 9</a></li>
        <li><a href="#url">Sub Item 10</a></li>
        </ul>
      </dd>
    <dt><b><a href="#url">Main Item 4</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 11</a></li>
        <li><a href="#url">Sub Item 12</a></li>
        <li><a href="#url">Sub Item 13</a></li>
        </ul>
      </dd>
    <dt><b><a href="#url">Main Item 5</a></b></dt>
    
    </dl>
</body>
</html>

Open in new window

smfmetro10Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

scrathcyboyCommented:
"I don't know if I should do this by placing the code on every page, or if I could do an include file."

If the script code happens to lie *inline* in the HTML, or you can put it there without adverse effects, then you can include this in an include file on every page -- but at the point where you want it included in the HTML flow.  If the script code MUST be in the head or the bottom (for page refresh or timing or looping reasons), then NO, you can't really use a #include, when it is outside the HTML body.

But of course, you could use PHP to compose the page to the browser, and there you can send ANYTHING you want -- the head code, the body, and you can do conditional IF THEN ELSE -- you can do anything.
0
smfmetro10Author Commented:
Hi scrathcyboy,

Thanks for your help, but the main problem I'm having is that I want to make the link stay active on the page that it is active on.  Like if you click to the "sub item 1" page, the sub item 1 page stays highlighted (in color red or whatever).

I don't know PHP, unfortunately.

Thanks!
Becki
0
Steve KrileCommented:
A few things.  First, I've attached a working copy, so this should give you the core idea.  Essentially I suggest you use the URL of the anchor tag to determine whether to show the menu section.  I've gone with a straight comparison, but if you anticipate querystring elements, you may need to switch the comparison to more of a regular expression approach.

Second, you MUST have this script on every page or this won't work.  But, since you are using code "if("#menu")"  before your wiring code, you should just put all of this logic in a central page like project.js, and include it in every header, just like you have done with the jquery library.

And last, you are using the <b> tag.  This tag is being deprecated in css3, so it's my opinion you shouldn't use it, or as you have done, not only use it, but style the hell out of it :)  Instead, consider using an H1 tag, or maybe even no tag at all and style your anchor tag directly.  Just a suggestion.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<style type="text/css">
#menu {padding:0; margin:0; font-family:Arial, Helvetica, sans-serif; font-size:14px;}
#menu a:hover {text-decoration:underline;}
#menu dt b, #menu dt a {display:block; font-weight:bold;  line-height:25px; cursor:pointer; width:200px;  background-color:#CCC; padding-left:5px;}
#menu dt b {background:url(arrow.gif) no-repeat left center; background-color:#CCC;}
#menu dt a {color:#000; text-decoration:none;}
#menu dd {padding:0; margin:0;}
#menu dd ul {padding:0; margin:0; list-style:none;}
#menu dd ul li {padding-left:20px;}
#menu dd ul li a {text-decoration:none; color:#000000;}
</style>

<script src="http://code.jquery.com/jquery-1.4.2.min.js" language="javascript"></script>

<script type="text/javascript">
$(document).ready(function(){
	if($("#menu")) {
		$("#menu dd").hide();

		//when the page first loads, loop through each dd list item
		$("dd > ul > li").each(function(){
			//get the href of the link in the menu item
			var thisRef = $(this).children("a").attr("href").toLowerCase();

			//compare the href to the current page - be careful about querystrings and such, you may
			//need to go to a regular expression rather than a straight comparison
			if(thisRef == currentPage()) {
				//if they match, do your
				$(this).parents("dt b").addClass("clicked");
				$(this).parents("dd").show();
			}
		});


		$("#menu dt b").click(function() {
			if(this.className.indexOf("clicked") != -1) {
				$(this).parent().next().slideUp(200);
				$(this).removeClass("clicked");
			}
			else {
				$("#menu dt b").removeClass();
				$(this).addClass("clicked");
				$("#menu dd:visible").slideUp(200);
				$(this).parent().next().slideDown(500);
			}
			return false;
		});
	}
});

function currentPage() {
	var sPath = window.location.pathname;
	//var sPage = sPath.substring(sPath.lastIndexOf('\\') + 1);
	var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);

	return sPage.toLowerCase();
}
</script>
</head>

<body>
  <dl id="menu">
    <dt><b><a href="#url">Main Item 1</a></b></dt>
    <dd>
      <ul>
        <li><a href="test1.html">Sub Item 1</a></li>
        <li><a href="test2.html">Sub Item 2</a></li>
        <li><a href="test3.html">Sub Item 3</a></li>
        <li><a href="test4.html">Sub Item 4</a></li>
      </ul>
    </dd>
    <dt><b><a href="#url">Main Item 2</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 5</a></li>
        <li><a href="test.html">Sub Item 6</a></li>
        <li><a href="#url">Sub Item 7</a></li>
        </ul>
      </dd>
    <dt><b><a href="#url">Main Item 3</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 8</a></li>
        <li><a href="#url">Sub Item 9</a></li>
        <li><a href="#url">Sub Item 10</a></li>
        </ul>
      </dd>
    <dt><b><a href="#url">Main Item 4</a></b></dt>
    <dd>
      <ul>
        <li><a href="#url">Sub Item 11</a></li>
        <li><a href="#url">Sub Item 12</a></li>
        <li><a href="#url">Sub Item 13</a></li>
        </ul>
      </dd>
    <dt><b><a href="#url">Main Item 5</a></b></dt>

    </dl>
</body>
</html>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
smfmetro10Author Commented:
Thank you, skrile!  I appreciate your time!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.