I am writing a website with Visual Studio 2008 and ASP.NET 3.5. I have a masterpage set up to simplify the layout and to keep the content pages for content rather than content and layout.
The navigation is list, css’d so it looks like a bar. In order to highlight the page on the bar, the list item needs to look like this <li id="current">. I do not want to use <asp:ContentPlaceHolder> if I can avoid it. Is there some code I can add to each of my pages (or just to the masterpage?) to accomplish this or am I stuck using <asp:ContentPlaceHolder>‘s?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Have you considered using a Web.sitemap file? It makes it real easy. If your sitemap file looks like this…
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode>
<siteMapNode url="~/Default.aspx" title="Home" description="" />
<siteMapNode url="~/Blog.aspx" title="Blog" description="" />
<siteMapNode url="~/AboutUs.aspx" title="AboutUs" description="" />
</siteMapNode>
</siteMap>
…then you can do this in your master page to achieve the results you want:
<asp:SiteMapDataSource ID="sitemapdata" runat="server" ShowStartingNode="false" />
<ul id="navigation">
<asp:Repeater runat="server" ID="navrepeater" DataSourceID="sitemapdata">
<ItemTemplate>
<li class="<%# SiteMap.CurrentNode.Equals(Container.DataItem) ? "activenav" : "inactivenav" %>"><a href="<%# DataBinder.Eval(Container.DataItem, " rel="nofollow noreferrer noopener"url") %>"><%# DataBinder.Eval(Container.DataItem, "title") %></a></li>
</ItemTemplate>
</asp:Repeater>
</ul>
The current page’s LI will have a class of “activenav” (or whatever you decide to use), and the others will have a class of “inactivenav”. You can write your CSS accordingly. This is the technique I use on my site and it works great.
Method 2
Add a property to your master page called Page Section
public string PageSection { get; set; }
Add a MasterType page directive to the top of your content pages
<%@ MasterType VirtualPath="~/foo.master" %>
In your content page code behind, set the PageSection property of the master page
Master.PageSection = "home";
In your master page, make the body tag a server tag
<body ID="bodyTag" runat="server">
In the master page code behind, use that property to set a class on the body tag
bodyTag.Attributes.Add("class", this.PageSection);
Give each of your nav items a unique ID attribute.
In your css, change the display of the nav items based on the current page class
.home #homeNavItem,
.contact #contactNavItem
{
color: #f00;
}
Method 3
It’s a better semantic match and likely an easier variable to set to keep the navigation using the same classes or ids everywhere and only alter the body element’s id to match:
<li id="homeNav">home</li> <li id="blogNav">blog</li>
and then on each page…
<body id="home"> <body id="blog">
And in the css:
#home #homeNav {background-image:url(homeNav-on.jpg);}
#blog #blogNav {background-image:url(blogNav-on.jpg);}
Method 4
The use or non use of ContentPlaceHolder will not affect which element has the id=”current” set on it.
You will have to look at some method, either in your codebehind for the master page, a javascript function or something else when rendering the menu component to properly add the id=”current” to the list when it is created.
Method 5
How about creating a protected string property in your masterpage code class? Override the OnLoad:
protected string _bodyId;
protected override void OnLoad(EventArgs e)
{
_bodyId = "your css id name";
}
Then in your masterpage aspx:
<body id="<%= _bodyId %>">
Then you don’t have to mess with your CSS, especially useful if the CSS came from a design agency.
Method 6
Here’s how we’ve achieved it using JQuery by appending the css class to change the background.
$("ul.nav > li > a:contains('<%= SiteMap.CurrentNode.ParentNode.Title %>')").addClass("navselected");
The “.nav” in ul.nav (in Jquery) is the css class applied to the UL tag.
:contains helps checking the contents of all “a” tag/element within the ul->li->a with ParentNode Title that is printed in Menu…
If found, applies the css class named navselected to the specific ul->li->a tag/element.
Regards, Minesh Shah
Systems Plus Pvt. Ltd.
www.systems-plus.com
Method 7
I would use javascript to accomplish this. In css, change your #current to be a class (.current) and then have id’s on each of your ListItems that you create. Then using RegisterStartupScript, call a javascript method that gets the appropriate ListItem and assigns it a style of current. Using Prototype, this would look like $(‘MyPageLi’).className = ‘current’.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0