jQuery Selectors and ASP.Net Controls
As I’ve already mentioned, this is the bane of jQuery within an ASP.Net application. Selecting the control based on its ID becomes difficult with ASP.net Controls and even worse with naming containers. There have been a few methods I’ve used to find the ASP.Net control in the dom.
Injecting the ClientID
$(“#<%= fooTextBox.ClientID %>”)
This is my least favorite, but the most precise. There are no additional elements or attributes to add and you’re guaranteed to get the exact control you’re after. Another bad side effect is the javascript has to be inside the ASPX page. That’s not ideal either, although you could argue that having a small script that just has variables for the control names isn’t that bad.
var fooTextBoxClientID = “<%= fooTextBox.ClientID %>”;
Still icky.
Add Custom Attribute
You could add a custom ID in the markup of the control.
<asp:TextBox runat=”server” id=”fooTextBox” myID=”foo” />
Then select on that custom ID.
$(“input[myID=’foo’]”)
This seems to make the code less DRY, but it works well.
Find With Ending
Since the name you give you .Net control is only prepended with its naming garbage, you can still find your names using the ends with selector.
$(“input[ID$=’fooTextBox’]")
This works well when the controls are assured to appear only once of the form; however, when inside a repeating control such as a ListView or a reusable control, this method falls apart.
Find With Class
I probably use this method more than any other since most of the time I have a parent frame of reference which limits the scope enough that makes my class name unique. That scope limiter also helps with the other methods, but using class names has worked the best for me.
$(“.inputTextBox")
Be careful not to use the CSS class like you would ID and create a CSS class for every element.
Wrap in HTML Elements
Also, you can wrap the control in an HTML element that will provide you full control over its ID.
<span id=”fooText”><asp:TextBox runat=”server” ID=”FooTextBox” /> </span>
Then select it using the child / ancestor selector.
$(“#fooText > input”)
You’re adding unneeded markup here, but you might already have it and just need to add the ID attribute, or select it using the class name.
I hope this helps with some headaches surrounding ASP.Net and jQuery.
Update: Since then, I’ve been using the following method more and more. The only change I’ve made is I’ve started to prefix my control name with the “_” to make sure I’m not picking up any control names that might carry similar ending names.
Like…
$(“input[ID$=’_PhoneTextBox’]")
and…
$(“input[ID$=’_CellPhoneTextBox’]")
Without the “_” both would match the following.
$(“input[ID$=’PhoneTextBox’]")
19 Comments »
RSS feed for comments on this post. TrackBack URL
Thank you very much for these useful information
I covered a couple techniques on my blog as well: http://john-sheehan.com/blog/custom-jquery-selector-for-aspnet-webforms/
I’m glad it was useful.
@John Sorry it took so long for your comment to show up. I didn’t realize it was waiting for me to approve it.
[...] http://fooberry.com/2009/01/07/jquery-selectors-and-aspnet-controls/ [...]
You rock! I would like to know more about the pro’s and con’s of each method but, hey, that’s what research is for (awesome whymeriner!)
@brant I’m glad you find it useful. I can tell you it works out that I end up using a selector like ‘.myClass > input[id$="myTextBox"]‘ I usually have some containing element that limit the scope enough I’m not worried about a name collision with my input control.
@brant Actually check out the post on event delegation. I think you’ll find that method really handy.
[...] http://www.fooberry.com » jQuery Selectors and ASP.Net Controls Here are some approaches to finding an asp.net webform control with JQuery, along with the easiest…Find With Ending – Since the name you give you .Net control is only prepended with its naming garbage, you can still find your names using the ends with selector. (tags: dev dotnet web javascript jquery) [...]
So, here we are in Sept. ‘09. I still can’t get a reference to ASP.NET controls in javascript with jQuery.
My control:
This is a test.
=====
All the js function SetLabel() does is change the div to the value in the text box.
This is the *ONLY* method that works:
function SetLabel() {
//var sourceID = $(“#lblTest”);
//var targetID = $(“#txtTest”);
var a = “breakpoint”;
var myDiv = $get(“divTest”).text;
var myTextbox = $get(“”);
myDiv.innerHTML = myTextbox.value;
}
===========
C’mon, people; with the above stuff, I get NO access to the jQuery features for these objects.
Your method of using the underscore and then using the EndsWith (having changed the ID of my textbox control to “_txtTest”) would be:
$(“input[ID$='_txtTest']);
==> Where is the ending double-quote?
All I get is “unterminated string constant” in VS2008 javascript.
——
At this juncture, I have not been able to successfully employ jQuery after nearly 2 weeks of research, reading, trying this, trying that. All I freakin’ wanna do is take a stupid textbox and use it’s value to change the value of a div area.
Y’know, start small, then onto larger concepts.
BTW: WinXPPro_SP3, VS2008_SP1, ASP.Net 3.5, jQuery 1.3.2 w/ the vsdoc file, no master page, no fancy extra plugins, just a basic website with Default.aspx.
====
I gotta admit that I guess I’m *totally clueless” in any of this.
My controls didn’t post cuz they have greater-than and less-than; here’s another go; replace brackets with greater- & less-thans:
My control:
[div id="divTest"]
This is a test.
[/div]
[asp:TextBox ID="txtTest" runat="server" Text="Changed to this new value #2." /]
[asp:Button ID="btnTest" runat="server" Text="Update Label" CausesValidation="false" OnClientClick="return SetLabel();" /]
@gnoter Sorry about that. There was a typo in the example code. The jQuery selector would look like this:
$(“input[ID$='_txtTest']“);
This would find every HTML Input element that has an ID that ends with “_txtTest”. Hopefully there is only one, but if there are more, it will find all of them. You’ll either need to be more specific or give it a reference point.
corrected function (sorry ’bout that, I was trying various renditions and copy/pasted a wrong version):
function SetLabel() {
//var sourceID = $(”#lblTest”);
//var targetID = $(”#txtTest”);
var a = “breakpoint”;
var myDiv = $get(”divTest”);
var myTextbox = $get(””);
myDiv.innerHTML = myTextbox.value;
}
@gnoter Also, keep in mind that it doesn’t return the Input DOM object, but rather a jQuery set. You’ll need to operate on it using the jQuery API or get a single object from the set.
For example, you won’t be able to do myTextBox.value, you’ll need to do myTextbox.Val(). See http://docs.jquery.com/Attributes/val
2 items:
1) Wow, you reply fast, thx, truly.
2) all I get is “object expected” with either of these js:
FYI ~ Since I give all my controls a unique ID (and I don’t use js yet on gridview controls, I’m gonna avoid using the underscore (for the time being).
$(“input[ID$='txtTest']“);
$(“input[ID$='txtTest']“).text;
One would assume I need to do something other than merely referencing it. So, tried all these and they fail with “object expected”:
$(“divTest”).text = $(“input[ID$='txtTest']“).text;
$(“#divTest”).text = $(“input[ID$='txtTest']“).text;
$(“.divTest”).text = $(“input[ID$='txtTest']“).text;
$(“input[ID$='divTest']“).text = $(“input[ID$='txtTest']“).text;
As already noted: I’m clueless in the northwest. One would think it would (and should) ‘just work’ .. ?!
@gnoter Instead of doing .text, you need to call the jQuery API method .text(“foo”) See http://docs.jquery.com/Attributes/text#val
Too keep it straight in my head, I usually prefix my variable names with $ so I know it is a jQuery object and _not_ a DOM object.
var $myDiv = $(“#divTest”);
var $myTextbox = $(“input[id$='txtTest']“);
It is more obvious to me that I need to call methods on the jQuery API.
$myDiv.text($myTextbox.val());
All the calls off the jQuery objects are all from the API. http://docs.jquery.com/ is your best friend.
So, got it working.
I had a site master page referencing jquery, then a sub-master, then a default.aspx. didn’t work; “Object expected” errors.
Added referenc jquery in the sub-master; everything works.
two things learned:
1) got a major clue on jQuery API (thk U mark!)
2) the a web form’s master page needs to have a reference to jQuery, not the master’s master (if such is the case in your website).
Instead of starting your conrols with _ , and having “_myTextBox”, you may try “txtMy” and in that situation txt prefix will be the same as undescore _.
nice article by the way.
@zika I don’t start my controls with “_”. The naming container is throwing that in for me. I used to prefix with control names, but found suffixing with the entire control name is more readable for me. The problem I had was trying to prefix a slider control, or any other custom control? sldDegreesOfRotation? I like DegreesOfRotationSlider. Also, I like that MyTextbox, MyLabel, MyRequiredFieldValidator all show up next to each other in the intellisense.
Even in your example, “_txtMy” would still work, but you’re right. You’re less likely to run into “txtFirsttxtName” this way.