An Atlas Client-Side Enhancement: Making the ASP.NET Controls easily accessible

[out of date post... this deals with MS Atlas CTP... which has been change drastically and is now MS Ajax Extensions.. this particular post may or may not work.. your mileage will vary]

[Small update… there were a couple issues with the code.  That’s what I get for not compiling it one last time after adding a simple parameter]

Lately, I have been playing with the client-side of Atlas.  I have a big post on the Behaviors coming up.  Well it’s similar in the vein of the browsing the source code, except I have been building examples as I work (so I guess it will be the big behaviors post and then a bunch of examples to follow).

Anyway, today I faced a challenge that I bet many people have faced.  That is using the Atlas client-side with ASP.NET server controls.  In case you don’t know the ID attribute of ASP.NET server controls is usually different client side.  It’s usually a combination of the control’s server-side ID plus all of its parents’ IDs with a underscore as a delimitter between all of them (it’s done probably to make sure that the ID is unique as well as to give you an object path… at least that’s my guess). 

So the problem is that Atlas let’s you connect an Atlas class to a real HTML element if you know it’s ID.  So you don’t always know what ASP.NET will assign the client side ID to (unless either you use ClientID property from the server side or your one of the ASP.NET team).  I haven’t seen anything in the docs to suggest that the Atlas team has built anything to make it easy to get around this.  If you are building an extender or a Atlas-aware server control then you always have the ClientID field available to you, but what if you are doing something a little more basic… Atlas makes a lot of things easy, but it would be nice to be able to easily make the translation client side.

Anyway, I decided to tackle the problem.  My solution produces a Javascript object called “ASPDotNetControls.”  This object has a method for every server side control (there’s also a switch to filter out any hidden controls that won’t be on the client); each method returns a DOM reference to that element (I chose this method so that I don’t end up with an object with references to a bunch of DOM elements).  By the way, my solution scans the entire control tree, so it will pick up all controls on the page even those buried deep inside the controls hierarchy.

So enough of the talk here’s the code:

protected void registerASPDotNetControlsForAtlas(bool OnlyVisibleControls)
{
  System.Text.
StringBuilder sb = new System.Text.StringBuilder();
 
sb.Append("function ASPDotNetControlsClass() {\n");
  sb.Append(LoopThroughControlsForAtlasRegistration(Controls, OnlyVisibleControls));
  sb.Append(
"}");
  sb.Append(
"\nvar ASPDotNetControls = new ASPDotNetControlsClass();");
 
this.ClientScript.RegisterClientScriptBlock(this.GetType(), "ASPNetControls", sb.ToString(), true);
}

protected string LoopThroughControlsForAtlasRegistration(ControlCollection Ctls, bool OnlyVisibleControls)
{
  System.Text.
StringBuilder sb = new System.Text.StringBuilder();
 
foreach (Control Ctl in Ctls)
  {
   
if (!OnlyVisibleControls || Ctl.Visible)
    {

     
if (Ctl.ID != null && Ctl.ID.Trim() != "")
        sb.Append(
" this." + Ctl.ID + " = function() { return $(\"" + Ctl.ClientID + "\")};\n");

     
if (Ctl.Controls != null && Ctl.Controls.Count > 0)
        sb.Append(LoopThroughControlsForAtlasRegistration(Ctl.Controls, OnlyVisibleControls ));
    }
  }
  return sb.ToString();
}

Now all you need to do is add a call to the first method registerASPDotNetControlsForAtlas in your codebehind (I usedthe PreRender event); if you are using the UpdatePanel you might want to set the parameter to false (but be aware that you will need to check any references that you get back from the class to see if they are null).

Here’s a quick scenario.  Let’s say I have an actual label on my form.  It might look like this:
<asp:Label runat="server" id="MyLabel" />

So you could turn this label into an atlas label (in javascript) like this:
var MyAtlasLabel = new Sys.UI.Control(ASPDotNetControls.MyLabel());
MyAtlasLabel.initialize();

Now from the script side I can use Atlas to its fullest… enjoy…

[A number of improvements I can think of… if I cached my script code for the complete list of controls, so that you’re not looping through the control tree on every hit… I’m too tired to come up with anymore]

[tags: Atlas, Ajax, ASP.NET]

Print | posted on Thursday, June 22, 2006 4:58 AM

Feedback

# re: An Atlas Client-Side Enhancement: Making the ASP.NET Controls easily accessible

left by at 6/22/2006 7:33 AM Gravatar

Hi Jay,

I've been doing quite a bit of Atlas work too - I posted a problem I was having around Client Side DataBinding and the ToggleButton Extender to the forum forums.asp.net/.../1307642.aspx - and was given the the reply:

"Attaching XML-Script to server controls directly is not supported"

I posted more about this scenario and a possible workaround here -

blogs.conchango.com/.../AtlasAttachingXmlScriptToServerControlsIsNotSupported.aspx

# re: An Atlas Client-Side Enhancement: Making the ASP.NET Controls easily accessible

left by at 7/8/2006 4:43 PM Gravatar

VERY nice! What a great idea to declare all Server Side controls upfront and not waste time declaring them manuelly.

Great Work!

Title  
Name
Email (never displayed)
Url
Comments   
Please add 7 and 6 and type the answer here: