Thursday, July 28, 2011

Clientside API for ASP.NET User Controls

Have you ever had an ASP.NET User Control that performed some simple function that you needed available via javascript on the containing page? Perhaps it's simply a combination of controls like an address/city/state/zip block, or maybe it's a custom control like a fancy combobox you pieced together. Whatever it is, it's generally risky and/or a pain to interact with it via javascript on the containing page.

The reason this is difficult is because all the element id's are generated dynamically, and you have no way of knowing what the User Control's element ids will be at runtime - therefore you don't know how to reference them back in your code on the containing Page. Now this is where many people will advise you to simply use the jQuery "ends-with" selector here and just hard-code the element ids you're looking for, but I have another option for you.

Although the jQuery "ends-with" approach does work, you are still hard-coding element ids on a page they don't belong on. I think a more appropriate solution is to expose the javascript methods and properties by extending the User Control itself client side. The problem though is that a User Control by itself doesn't actually render any DOM, so there's nothing to extend. Only a User Control's contents are actually rendered. This solution actually exploits that fact by adding a single wrapper div inside the User Control and giving it the same ID as the actual User Control like so:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UcDemo.ascx.cs" ...etc... %>



.... actual content....


Now we'll have a known element id we can reference on the containing Page, because it'll actually be the ID that we assign the User Control!

Now all we have to do is expose our methods and properties by using jQuery's extend method:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UcDemo.ascx.cs" ...etc... %>








So now we've just added 3 methods to our little container div that will be available once we select the element.
To do that, our containing page would look something like this:

 

<html>
<body>
...
Say Hello
Set "TESTING" to the Textbox Value
Alert the Textbox Value
...

...
</body>
</html>

Now the only hard-coded element id you have on the page is actually to the user control. Another added bonus is that all your javascript methods on the user control are all neatly scoped in the add_init function (or document ready or whatever you're using) so nothing is in the global namespace.

Full demo project available below:

3 comments:

  1. This is the cleanest solution to this I've seen. Slick idea about using the user control's id. Nice post.

    ReplyDelete
  2. thank you, very nice. i used it using the clientId property

    ReplyDelete
  3. very nice solution, thank you - I've been searching just for something like this

    ReplyDelete