Scripting element identity via ClientID

K

kw

TextBox t=new TextBox();
Controls.Add(t);
t.ID=t.ClientID;
//reads: "_MyControl1__ctl16"

And even in OnPreRender, I examine the Controls collection and verify that
the ID of the TextBox is "_MyControl1__ctl16".

But then, on the final HTML rendered, if you look at the page, the textbox
looks like this:
<input ID="MyControl1_MyControl1__ctl16" ...etc...>

So how on earth am I supposed to determine the ID of this control such that:

<script>
ctl=document.getElementById('_MyControl1__ctl16');
 
K

kw

BRUCE BARKER You are the greatest! Not only did it work in the simple
cases, but the most complex nexted dynamically loaded ones too.

I did try UniqueID, but I found it has to be in the OnPreRender phase.
Thus, the script generation has to be the last step.

string s=this.FindControl("X").UniqueID;//should be called from
OnPreRender()
private string GetScript(){
string s=this.FindControl("X").UniqueID;
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("<script>\n");
sb.Append("function DoSomethingReallyImportant(ctl)\n{\n");
sb.Append("document.getElementById(\"");
sb.Append(s);
sb.Append("\").value=\"test\";\n}\n");
sb.Append("</script>\n");
return sb.ToString();
}




bruce barker said:
control id and names are a mess because MS did not understand the W3C rules
when they wrote the code.

background.

html form controls have a name property that is used in a form post

<form><input name="myInput" type="button" value="foo"></form>

when posted the browser will send

myInput=foo

originally there were no rules for forming name. later version of html set
rules (use id rule - see below)

later version of html added the id attribute from xml. the id attribute has
many rules.

1) must be unique across the document
2) must start with a letter
3) can only contain letters, numbers and underscore

when ms wrote web controls they had the issue of naming nested controls. the
simple fix concat the names together with ":" between them. for example if
button1 was nested in control control1, the name would be
"control1:button1". this turned out to be a really bad decision. for several
reasons.

1) ":" are not allowed in the id attribute, so they are removed and replaced
with _
2) while non w3c compliant browser allowed the ":" in name, it lead to
scripting errors, because the name was not valid javascript name, so could
not be used in the common syntax:

document.forms[0].myFieldname

3) IE has a bug which causes an alert if a ":" is present in a url under
https. this caused problems with postback:
javascript:_doPostBack('control1:control2')
would cause an alert on an https page, so now __dopostback() replaces
the ":" with $.
javascript:_doPostBack('control1$control2')

4) the name attribute is the name the backend uses to match up the posted
data with the controls. the name still uses ":" even though some proxy
servers will strip it, and thus are not compatiable with .net


now:

ClientID is the name of the control on the server side, it does not have to
be unique. Two parent controls can controls of the same name, otherwise
writing composite controls would be hard.

UniqueID is the what the rendered html attribute id will be. this is what
your javascript should use and will contain the any parent container names.

in your web control you want to:

TextBox t=new TextBox;
t.ID = "X";

Control.Attributes["OnClick"] ="javascript:document.getElementById('"
+ this.FindControl("X").UniqueID + // get the unique id of my
child control X
+ "').value='test';";


assuming the webcontrol's id is TextBox1 (and is a div), when rendered it
looks like:

<div id="TextBox1"
OnClick="javascript:document.getElementById('TextBox1_X').value='test';" >
<input type=text id="TextBox1_X" name="TextBox1:X">
</div>

-- bruce (sqlwork.com)













kw said:
Guess what...it still doesn't work for me (I can see how this will work in
your example). And here's the funny thing: after the controls are added and
ClientID is known (even in OnPreRender)...the final HTML looks like this:

MyControl1_MyControl1__ctl16

instead of (from tb.ClientID)

_MyControl1__ctl16

I don't understand why ASP.NET is modifying the ID after OnPreRender.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top