views:

42

answers:

3

Hi everyone

I'm currently working on an ASP.NET 3.5 project, and I wanted to know your opinion regarding the following situation, which I happen to run into sometimes:

Let's say I've defined the following control of an imaginary component framework somewhere in my code:

<Window runat="server" ID="windowTest" />

Let's assume that with the above mentioned imaginary component framework it's possible to get a reference to my Window control from the client-side using its ID (for example to change its appearance):

function MyFunc(){
    var win = GetWindow("windowTest");
}

Let's also assume that both code snippets are placed in different files, e.g. the JavaScript code in MasterPage.Master and the control in AnotherPage.aspx.

As you might already have noticed, the passing of the control's ID as a hard-coded string to the GetWindow function is a bit problematic here, since changing the control's ID is going to break the JavaScript function.

This situation surely smells like it needs a good ol' Replace Magic Number with Symbolic Constant refactoring. I can achieve this by dynamically creating the Window control and using a constant for the value of the control's ID:

AnotherPage.aspx:

Window windowTest = new Window();
windowTest.ID = Consts.ID_WINDOW_TEST;
form1.Controls.Add(windowTest);

MasterPage.Master:

function MyFunc(){
    var win = GetWindow("<%= My.Namespace.Consts.ID_WINDOW_TEST %>")
}

My question now is: How do you handle such situations? Do you create all your controls dynamically (like shown in the example above) when running into this situation, and are there any drawbacks using this approach, e.g. Designer doesn't display the control anymore? Or do you say "Screw it, nobody's going to change that control's ID" and leave it hard-coded in your code? Or do you have other approaches to this situation?

I personally am a fan of the of the first option (refactoring), since a) it makes sure that a change to the ID is not going to break my code and b) I almost never work with the Designer, but I thought I'd ask this question on SO to get some valuable opinions on this.

Thanks in advance for all the responses.

Greetings,

Giu

Update / Clarification:

I made a small error in the first version of this question by stating that the code snippets are placed in the same file. Since both the control and the JavaScript method are located in the same file, there is no need to create the control dynamically and defining the control's ID using a constant; by defining the control directly in the .aspx file I could use its ID in the JavaScript method as follows: GetWindow("<%= windowTest.ID %>");

But, my problem is another one; the control and the JavaScript method are each placed in different files, in which case the mentioned approach of using the control's ID doesn't work anymore. Therefore I introduced the solution mentioned in my question with the constant and the dynamic creation of the control. I now corrected both the filenames in my question so that the correct scenario is described to which my question is related.

A: 

In my opionion there a two suitable solutions:

1) Use the JQuery framework to get ahold of the html element you want to adress via JavaScript. JQuery is designed to be able to work with autogenerated hierarchically created control IDs
2) Use .net Framework 4.0 and don't use autogeneration of the Control ID. (I've heard that this is a new feature in 4.0. I think in your situation it might be worth trying out)

citronas
Thanks for your response. Actually, I'm using a component framework, which comes with a client-side API, so jQuery is not an option unfortunately. I'll have a look at the ASP.NET 4.0 feature, though the project's using ASP.NET 3.5, so I don't know if a transition will happen any time soon.
Giu
A: 

Check out Rick Strahl's blog post entitled "A generic way to find ASP.NET ClientIDs with jQuery"... it seems to have some good ideas that could be of some help to you.

He uses jQuery, as the first responder suggested, but does it in a way that you are using ASP.NET's built-in ClientID property to get the actual id ASP.NET generates and uses a client-side friendly mechanism that enables you to write script code referencing controls that won't break with ID changes.

G-Mac
Thanks for the link. As I mentioned in the response to citronsas' answer, I'm working with a component framework, which itself comes with an own client-side API. This means that I'll have to use the `GetWindow` method mentioned in my question to change the window's appearance from the client-side, e.g. `GetWindow('myObject').SetSize(400,400)`.
Giu
A: 

In 4.0 you can control the client ID that's generated in master/content page situations quite well. but i believe if someone changes the ID manually in the page at one place and not in the javascript code it will still be a problem. If you are the only one who'll be working on this code then you can always be mindful and refactor properly. Otherwise you can go in for the constants option or store the IDs in a separate resource file.

Ritik Khatwani
Thanks for your opinion. I had a look at the `ClientIDMode` property that comes with ASP.NET 4.0. There's the `Static` mode that looks like a solution to my <em>problem</em>, since the `ClientID` will be the same es the `ID`. I then could write `GetWindow("<%= windowTest.ClientID %>")` and everything would work fine. If somebody's going to change the ID, sure, it'll crash at run-time. But then again, using `ClientIDMode="Static"` surely is the better approach than hard-coding strings.
Giu
Yes i guess its better than hard-coding the strings.
Ritik Khatwani