Thursday, November 3, 2011

New Look

As you may have noticed, the site (finally) has a new theme applied. The blue-and-white circa 2007 theme is history!

I also took the opportunity to upgrade to the latest 3.x (hosted) version of Syntax Highlighter for code snippets. I went back through all the old posts and updated everything accordingly - hopefully I didn't miss/break anything.

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:

Sunday, July 24, 2011

ASP.NET Session Timeout Control with jQuery UI Dialog

As you may or may not be aware, back in 2009 I posted code where I had extended an ASP.NET session timeout control originally created by Travis Collins. That control then later evolved into a second version that included a countdown timer, and later still I made it .NET 4.0 compatible. All along the way I attempted to retain as much of the original code as possible, supporting the original shown/hidden div approach Travis created - as well as my jQuery UI dialog approach. While this seemed like a good idea at the time, it ultimately led to some ugly code as well as a bit of code bloat for no good reason - and I've finally gotten around to doing something about it.

I've rewritten most of the code now to such a degree that it looks nothing like the original control from Travis. The javascript class especially has been completely reworked, notably forgoing prototypes for simple closures. I did this largely for two reasons. The first is that there's no reason to have more than one Timeout class instantiated on a page. The second is that I hope the closure style is simpler for everyone to follow.

Please note that due to all these changes, I have renamed the project, namespace, etc. - dropping all references to the original TSC name - as well as reset the version number to 1.0.

This new version functionally is very similar to the last, but jQuery is now a requirement. Also partial postbacks are no longer optional - they will simply always reset the control just as a full postback would. The countdown timer is also no longer optional. It is simply required. If you don't want to show it, simply place a display hidden style on the span.

The demo project has been updated to use the latest version of jQuery and the jQuery UI (installed as NuGet packages).

There is one new bit of functionality to take note of. You can now reset the timeout from outside the control (something requested a few times over the years). Simply grab a reference and call the reset() method using $find like this:
$find('myTimeout1').reset();

Also to foster social development, I have moved the code to a github repository so fork away!