18

My master page contains a list as shown here. What I'd like to do though, is add the "class=active" attribute to the list li thats currently active but I have no idea how to do this. I know that the code goes in the aspx page's page_load event, but no idea how to access the li I need to add the attribute. Please enlighten me. Many thanks.

<div id="menu">
  <ul id="nav">
    <li class="forcePadding"><img src="css/site-style-images/menu_corner_right.jpg" /></li>               
    <li id="screenshots"><a href="screenshots.aspx" title="Screenshots">Screenshots</a></li>
    <li id="future"><a href="future.aspx" title="Future">Future</a></li>
    <li id="news"><a href="news.aspx" title="News">News</a></li>
    <li id="download"><a href="download.aspx" title="Download">Download</a></li>
    <li id="home"><a href="index.aspx" title="Home">Home</a></li>
    <li class="forcePadding"><img src="css/site-style-images/menu_corner_left.jpg" /></li>
  </ul>
</div>

12 Answers 12

28

In order to access these controls from the server-side, you need to make them runat="server"

<ul id="nav" runat="server">
  <li class="forcePadding"><img src="css/site-style-images/menu_corner_right.jpg" /></li>               
  <li id="screenshots"><a href="screenshots.aspx" title="Screenshots">Screenshots</a></li>
  <li id="future"><a href="future.aspx" title="Future">Future</a></li>
  <li id="news"><a href="news.aspx" title="News">News</a></li>
  <li id="download"><a href="download.aspx" title="Download">Download</a></li>
  <li id="home"><a href="index.aspx" title="Home">Home</a></li>
  <li class="forcePadding"><img src="css/site-style-images/menu_corner_left.jpg" /></li>
</ul>

in the code-behind:

foreach(Control ctrl in nav.controls)
{
   if(!ctrl is HtmlAnchor)
   {
      string url = ((HtmlAnchor)ctrl).Href;
      if(url == GetCurrentPage())  // <-- you'd need to write that
         ctrl.Parent.Attributes.Add("class", "active");
   }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Does the code behind means the master page or the content page?
4

The code below can be used to find a named control anywhere within the control hierarchy:

public static Control FindControlRecursive(Control rootControl, string id)
{
    if (rootControl != null)
    {
        if (rootControl.ID == id)
        {
            return rootControl;
        }

        for (int i = 0; i < rootControl.Controls.Count; i++)
        {
            Control child;

            if ((child = FindControlRecursive(rootControl.Controls[i], id)) != null)
            {
                return child;
            }
        }
    }

    return null;
}

So you could do something like:

Control foundControl= FindControlRecursive(Page.Master, "theIdOfTheControlYouWantToFind");
((HtmlControl)foundControl).Attributes.Add("class", "active");

Forgot to mention previously, that you do need runat="server" on any control you want to be able to find in this way =)

Comments

2

Add runat="server" on the li tags in the masterpage then add this to the appropriate page_load event to add the 'active' class to the li in the masterpage

HtmlGenericControl li = HtmlGenericControl)Page.Master.FindControl("screenshots"); li.Attributes.Add("class", "active");

Comments

1

You could register a client script like this:

(set id to the id of the li that you want to set to active)

ClientScript.RegisterStartupScript(this.GetType(), "setActiveLI", "document.getElementById(\""+id+"\").setAttribute(\"class\", \"active\");", true);

This generates a JavaScript call on the page near the bottom after elements have already been rendered.

Comments

1

All the parts have already been provided in previous answers, but to put the whole thing together, you'll need to:

  • add the runat="server" attribute to the <ul> and <li> elements
  • add a public method to do the work on the master page that can be called from the pages using the master page
  • call the method from the Page_Load of the pages

    Alternatively you could also add the code to the OnLoad(...) method of the master page, so you don't have to add the method call to the Page_Load on every page.

  • Comments

    0

    If they were runat=server you could use the attributes property.

    Comments

    0

    In order to find that particular control it will need to be defined as public (in the generated designer)

    Or will need to be wrapped by a public get in the codebehind.

    Comments

    0

    You can expose the li's on the master page to any content pages by wrapping them in properties on the master page:

    public GenericHtmlControl Li1
    {
        get
        {
            return this.LiWhatever;
        }
    }
    

    Then on the content page:

    MasterPage2 asd = ((MasterPage2)Page.Master).Li1.Attributes.Add("class", "bla");
    

    If i've got that right!

    Comments

    0

    I found a link that works using CSS and involves only changing the body tag's class attribute. This means there's no Javascript and there's no for loops or anything.

    #navbar a:hover,
      .articles #navbar #articles a,
      .topics #navbar #topics a,
      .about #navbar #about a,
      .contact #navbar #contact a,
      .contribute #navbar #contribute a,
      .feed #navbar #feed a {
     background: url(/pix/navbarlinkbg.gif) top left repeat-x; color: #555;
    }
    
    ....
    
    <body class="articles" onload="">
    
    <ul id="navbar">
      <li id="articles"><a href="/articles/" title="Articles">Articles</a></li>
      <li id="topics"><a href="/topics/" title="Topics">Topics</a></li>
      <li id="about"><a href="/about/" title="About">About</a></li>
      <li id="contact"><a href="/contact/" title="Contact">Contact</a></li>
      <li id="contribute"><a href="/contribute/" title="Contribute">Contribute</a></li>
      <li id="feed"><a href="/feed/" title="Feed">Feed</a></li>
    </ul>
    

    Read more here http://www.websiteoptimization.com/speed/tweak/current/

    Comments

    0

    Try this the great example for future use. i know this thread is old, but for future queries...

    http://community.discountasp.net/showthread.php?p=33271

    Comments

    0

    Thanks For the solution.

    Mininized code.

    Master page control can also find in the child page..

    i mean master page contains html contol

    and chilld page can find the master page html conrol like this

    ((HtmlControl)this.Master.FindControl("dpohome1")).Attributes.Add("class", "on");
    

    Comments

    0

    Simple logic and minimal code, I usually use the following code, especially in dynamic menu. Hope this helps.

    Create this method code in the code behind master page

    CODE BEHIND (C#)

    protected string SetCssClass(string page) { return Request.Url.AbsolutePath.ToLower().EndsWith(page.ToLower()) ? "active" : ""; }

    In the menu list items you have created call this method passing the page name like this

    HTML PAGE (ASPX inline code)

    <li id="screenshots" class = "<%= SetCssClass("screenshots.aspx") %>"> <a href="screenshots.aspx" title="Screenshots">Screenshots</a></li>

    <li id="future" class = "<%= SetCssClass("future.aspx") %>"> <a href="future.aspx" title="Future">Future</a></li>

    and so on.

    By this method, every time you add a page and link, you don't have to write code in every page. Just when you add the link in the master page, with every <li> invoke the SetCssClass(pagename) method call for setting class and it's done. (you can rename the method as per your ease.

    You can use longer codes if you are being paid per lines of code bcoz then this is just one line of code. (lol). Just kidding. Hope it helps.

    Note: I am ignoring other parts of the html code, you can include them also, that would work fine.

    Comments

    Your Answer

    By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.