John Sheehan : Blog

Custom jQuery Selector for ASP.NET WebForms

I’ve built a ton of ASP.NET web sites using WebForms. Unfortunately I don’t have the luxury of rewriting them all using ASP.NET MVC so I’m stuck dealing with INamingContainer and the resulting auto-generated HTML element IDs.

Here are all the ways I know of that people use to get around this.

Output the ClientID using <%= %>
I don’t like this because it can make my markup messy, requires server-side interaction and doesn’t work in external script files.

Output a JavaScript Object
I first saw this method on Rick Strahl’s blog. I don’t like this method because it generates even more script to send down the wire and it requires you to specify the IDs in multiple places (codebehind to include them in the object and again in the jQuery selector).

Select by Class Instead of ID
The purist in me doesn’t like using classes as IDs and in some situations, this will conflict with well-structured CSS. Also, selecting by class is slower than by ID (although this is improving in newer browsers).

Select using jQuery’s Attribute Selectors
I came across this method on StackOverflow (don’t recall which question though). It’s the best of the bunch as it is the most concise and doesn’t require any server-side preparation. Here’s an example:

$("*[id$='TextBox1']").show();

This looks for all elements (*) that have an ID that ends with the specified text. Since INamingContainer-generated IDs always end in the ID you specify in your ASPX markup, it works. It’s also a valid CSS3 selector so it’s consistent with the way jQuery works. Still feels like a kludge to me.

I decided to see if I could try to find a more readable selection method. This was my goal:

$("#TextBox1:asp").show();

After looking into jQuery’s custom selectors and stepping through a crap ton of the jQuery core code in Firebug, I don’t believe this is possible. After tweaking and playing, I got this working:

$(":asp('TextBox1')").show();

Here’s how it works. It’s actually pretty simple. Add jQuery to your page. Then add the following script, either inline or in an external file.

String.prototype.endsWith = function(str) {
    return (this.match(str + '$') == str)
}

jQuery.extend(
    jQuery.expr[":"],
    {
        asp: "jQuery(a).attr('id').endsWith(m[3]);"
    }
);

I’m not going to go into the details of how this all works. The first section adds an ‘endsWith’ method to strings for brevity’s sake. The second section extends the jQuery object with the custom selector. For more info on how that works, I would suggest reading the jQuery docs and this tutorial.

Whether or not this is better than an attribute selector is up to your readability preferences, but it’s another option you can use. If anyone knows how to access the part of a selector before the colon, I’d love to hear about it.

September 29th, 10:20 PM .NET, Tips, jQuery Read more Comments