tags:

views:

1081

answers:

8

If I want to manipulate an HTML tag's properties on the server within an aspx page based on a master page i.e.

<a href="#" runat="server" ID="myLink">My Link</a>

For example to give the link a different class depending on the current page i.e.

if (Path.GetFileName(Request.PhysicalPath) == "MyPage")
{
myLink.Attributes.Add("class","active");
}

.NET changes the ID property of the link to something like

<a href="#" ID="ct100-foo-myLink">My Link</a>

Is there any way of stopping this from happening and keeping the original ID?

Thanks in advance

A: 

I don't think so.

However, you probably want to keep the original name so that you can manipulate the control with javascript.... if that's the case, you should look into ClientID; it will return the assigned ID at runtime.

EDIT:

It looks like there is a way to do it, but with some work... take a look at ASP.NET Controls - Improving automatic ID generation : Architectural Changes ( Part 3)

I didn't read the full post, but it looks like he created his own container and own naming provider. I think that if you wanted to leave your control's name untouched, you would just return the name back in

public abstract string SetControlID(string name, System.Web.UI.Control control);
Giovanni Galbo
A: 

I never figured out how to prevent .NET from doing this, but what I did start doing was placing asp:Literals and using c# to add a WebControl to them. If you write a WebControl you can set various properties without it getting .NET's unique ID. For instance:

<asp:Literal ID="myLink" />

...

WebControl a = new WebControl(HtmlTextWriterTag.A);
a.CssClass = "active";
a.Attributes["href"] = "#";
Literal text = new Literal();
text.Text = "click here";
a.Controls.Add(text);
myLink.Controls.Add(a);

Which will result in the following html:

<a href="#" class="active">click here</a>

Overall, a pretty dirty solution, but I didn't know what else to do at the time and I had a deadline to meet. ;)

Rahul
+2  A: 

AFAIK there is no way.

It shows the actual control tree, which is in this case masterpage-content-control.

However if you add an ID to the masterpage (this.ID = "whatever") then you will see "whatever" instead of ctl00 (which means control index 0).

Biri
just what i was looking for, thanks!
gnomixa
A: 

Yep exactly, we will need to persist the original ID for JavaScript and CSS reasons. I noticed the ClientId property but it's read only and can't be assigned, so i'm not sure how I would use it?

Nick Allen - Tungle139
A: 

This blog post could be helpful: Remove Name Mangling from ASP.Net Master Pages (get your ID back!)

The solution in the post overwrites the .getElementById method, allowing you to search for the element just using the normal ID. Maybe you can adapt it to your needings.

Disclaimer: That ASP.NET behaviour is by design and it is good that way, even for HTML Server Controls like the control in your example. Server-ID and Client-ID are two very different things, which should not be mixed. Using Master Pages or User Controls you could end with identical Client-IDs if there wasn't that mechanism.

splattne
+3  A: 

It's not possible directly. You could make a new control that inherits the link and override its ClientID to return directly the ID. But this seems to be overkill. You can simply use HTML markup and use <%# GetClass() %> to add the class when you need it.

Regarding the usage of ClientID for Javascript:

<a ID="myLink" runat="server">....


var ctrl = document.getElementById('<%# myLink.ClientID %>');

Of course you need a DataBind somewhere in the code.

rslite
+1. I've done it successfully this way before.
Raithlin
THanks i'll see if I can get this solution going. Trying to be as little "hacky" as possible
Nick Allen - Tungle139
This surely isn't "hacky" :) It is actually the purpose of the ClientID property.
rslite
this is the way to do it if you must make it a runat server control. but why do that, why not just use a regular a tag and just set the class to a method call using a render block instead
DevelopingChris
@ChanChan - of course that's also possible. It depends from case to case. In the general case it's still useful to know how to do it.
rslite
A: 

Why not just use a standard a tag, and use render blocks to modify it, and then you have its behavior locked in on client.

DevelopingChris
A: 

I just discovered an easy way to do it if you are using jQuery.

var mangled_name = $("[id$=original_name]").attr("id");

So if you have a server control like this:

<asp:TextBox ID="txtStartDate" runat="server" />

You can get the mangled name in your jQuery/Javascript with:

var start_date_id = $("[id$=txtStartDate]").attr("id");

Since it is a string, you can also use it "inline" instead of assigning it, e.g. concatenating it with other elements for selectors.

CMPalmer