views:

14882

answers:

12

Hi,

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>
A: 

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

Adam Naylor
A: 

I tried doing that from the aspx page but it didn't find the control.

I did this

MasterPage2 asd = (MasterPage2)Page.Master;

    asd.idOfControl

But it could not find it.

Sir Psycho
You should add a comment to the answer that you are referring to, not add an answer (unless you solve it and want to answer you own question). The reason is that the answers get reordered by votes.
Lou Franco
+1  A: 

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.

Lou Franco
A: 

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.

Adam Naylor
A: 

Hey Lou,

Its a great solution that works but I was wondering if there's a non javascript way to do this. Not all visitors have JS running.

THanks anyway though :)

Sir Psycho
I'm not sure how well your .ASPX site is going to work without javascript -- look at the source of the generated page. ASPX uses plenty of JavaScript already.
Lou Franco
Also, you should add a comment directly to the answer -- in addition to keeping them related to each other, it also shows up on my responses list so I know that you have added a comment.
Lou Franco
A: 

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!

Adam Naylor
A: 

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 =)

Rob
+5  A: 

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");
   }
}
Ben Scheirman
this is a great answer, helped me, thanks so much!
iamserious
vote up for simplicity ;)
iamserious
A: 
csgero
A: 

Hi,

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/

Sir Psycho
+1  A: 

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");

beverage
A: 

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

sus2bhai