views:

55

answers:

3

When you click Questions, Tags, Users etc. at the top of stackoverflow, the one you're looking at becomes highlighted orange. This is (usually) done by changing the css of one of them to be 'selected'.

If you have a single template that all your pages are built with, and that template includes these buttons across the top, how do you highlight one of them depending on which page you are viewing?

The problem is that you'd have one template, not one for each page... ideas?

(If it matters, I am using ASP.NET MVC 2 and setting up a Master page)

A: 

add a class dynamically by checking where you are. in rails, i usually add a "selected" class based on the controller, e.g. if im in the questions controller, i should add a selected class in the question tab. i'm not sure about asp.net (how you check your controller or where you are in the site) but that's the general idea.

corroded
Is that some kind of javascript thing though?
SLC
you can use jscript but you can use your language's variables also. is there a way in asp to know which controller you are in? something like controller.controller_name? maybe you can add asp.net as a tag so people who know about it can also help :)
corroded
+1  A: 

There are various ways of doing this, on a scale of how much of a change you can make to the HTML code.

In the best case scenario, but with the most HTML manipulation, you should be wrapping the link in a strong tag. Whether or not you wrap the anchor in a strong tag or replace it with a strong tag is up to you *, but the strong tag adds semantic meaning to the link that a class attribute does not, meaning the raw HTML still shows that the current link is highlighted. You would need a lot of IF statements or some such logic to achieve this effect programmatically though.

<li><a href="...">Home</a></li>
<li><strong>News</strong></li>
<li><a href="...">About</a></li>

In the worst case scenario, with the least HTML manipulation, adding a class to each LI and then altering a body class will allow you to control the appearance of a single navigation element. This is simple to do, but lacks any semantic structure in the HTML.

<style type="text/css">
.in-news .nav-news { font-weight: 600; }
</style>
<body class="in-news">
...
<ul>
<li class="nav-home"><a href="...">Home</a></li>
<li class="nav-news"><a href="...">News</a></li>
<li class="nav-about"><a href="...">About</a></li>
</ul>

[*] There are lots of opinions on whether a page should link to itself in the site navigation. There are lots of subjective reasons for either case. I'll leave that to you ...

beseku
A: 

This is a great question. I remember having to do this is ASP.NET but havent thought about it for ASP.NET MVC.

For ASP.NET MVC, you could create a user control, but I like the idea of an HTMLHelper extension method. Taking beseku's idea from above, that would be the ultimate output of your control. The method would accept a collection of elements, and from those elements you would then be able to determine the selected page.

  1. Create a MenuTab object that has properties of DisplayText, ActionName, and ControllerName.
  2. Create a System.Web.MVC.HtmlHelper extension that takes a collection of MenuTab as an argument, e.g. public static MvcHtmlString TabbedMenu(this HtmlHelper helper, IEnumerable<MenuTab> menuTabs). Note the return type of MvcHtmlString so it works both with response.write and html.encode.
  3. Inside the body of the above method, you would be able to see via the HtmlHelper if the pages current controller and action matches the controller and action names of any of the passed in MenuTab, and if so, build an ActionLink that has a html class attribute set to your css class for a selected item.

Example usage in you master page would be something like:

<%: Html.TabbedMenu(new List<MenuTab> { new MenuTab{Text="Home", ActionName="Index", ControllerName="Home"}, new MenuTab{Text="Other Page", ActionName="Index", ControllerName="Other Controller"}, new MenuTab{Text="What is this?", ActionName="About", ControllerName="Home"} }) %>

in one that I am using, I am additionally passing in an id parameter so I could have multiple menus on the same page (think side and top navigation).

Jonathan Bates