Damian Mehers' Blog Android, VR and Wearables from Geneva, Switzerland.

28Feb/070

Automatically attaching Extenders to Controls using Control Adapters – demo posted

I get a lot of hits on this article I posted last year, showing how you can use ASP.NET Control Adapters to automatically attach Control Extenders to a specific kind of ASP.NET control throughout an existing web site, without modifying any of the existing pages.

It uses a Control Adapter to create and attach extenders to the target controls, and also an HttpModule to ensure that all pages have a ScriptManager or ScriptManagerProxy.

Anyway, I finally got around to uploading a demo project showing this.  It is slightly different to the article, since it shows how to attach a DropShadow extender to all UpdatePanels on your site.  Not something you will necessarily want to do, but you get the point.

The demo project is here.  It consists of a class project containing the Control Adapter and Http Module, and then a sample web site with a .browsers file to cause the adapter to be used, and a modified web.config to let the Http Module do its stuff.

Filed under: AJAX No Comments
28Feb/0710

Calling AJAX Control Extenders from JavaScript code

I am a big fan of declarative programming.  It reduces the risk of errors, saves on mundane coding and lets me say what I want to do and someone else can figure out the how (although I like to understand the how too :-).

That said, when you find yourself doing strange and unnatural things simply to be able to use declarative programming then you know you've gone too far.

I found myself in this kind of situation recently.  I have a very large GridView and for one of the columns I wanted to display a ModalPopup whenever the user clicked on the corresponding item in each row, where they could select information related to that item.

What I could have done is to hook up an instance of the ModalPopup in the template, so that for each row a new ModalPopup would be created.

Instead what I did was to define a single ModalPopup outside of the GridView, targeted at a dummy hidden LinkButton (with no label):

<asp:LinkButton ID="DummyHiddenLinkButton" runat="server"></asp:LinkButton>

<cc1:ModalPopupExtender ID="SelectYxzModalPopupExtender"
                                                         
runat="server" 
                                                         
TargetControlID="DummyHiddenLinkButton"
                                                         
PopupControlID="SelectYxzPanel" 
                                                         
OkControlID="SelectYxzOKButton" >
</cc1:ModalPopupExtender>

Then in the template I hooked up the onclick method of the item to invoke a JavaScript function  passing as a parameter key information related to the item.

Inside my JavaScript function I first initialize the Panel with information related to the item (in my case by invoking a page method), and then I programatically cause the ModalPopup to show:

function OnItemLinkClicked(someId) {
    PageMethods.SomePageMethod(someId,
                               OnSomePageMethodSucceded,
                               OnSomePageMethodFailed);
}

function OnSomePageMethodSucceded(result) {
    var extender = $find('SelectYxzModalPopupExtender');
    var someList = $get('SomeListInTheModalPanel');
    if(!extender || !someList) { ...
    }
    someList.options.length = 0;
    for(var i = 0; i < result.length; i++) {
        var option = document.createElement('OPTION');
        option.text = result[i].Text;
        option.value = result[i].Value;
        someList.options.add(option);
    }
    extender.show();
}

I've shown my call to a backend page method for completeness. I'm invoking a page method to get an array of structs related to the item that the user clicked, and then using the resulting array to populate a SELECT that I display within the modal popup.

But the interesting stuff is in bold. Here I am programatically finding my ModalPopup extender (using the $find shortcut to the Sys.Application.findComponent method), and then invoking its show method to cause it to display. The hidden LinkButton that is its "official" target never actually gets used.

I discovered what methods were available on the ModalPopup extender by looking at its source, which is available for all the control extenders when you download the AJAX Control Toolkit. Methods that are prefixed with an underscore are internal methods and I'd never call those, but I'm pretty comfortable calling the other methods, such as the handy show method above.

Filed under: AJAX 10 Comments
25Feb/078

Screencast: Introduction to AJAX, ASP.NET AJAX and the AJAX Control Toolkit

Last Tuesday I gave a presentation in Geneva on ASP.NET AJAX and the AJAX Control toolkit, and this morning I created a one hour screencast of the presentation available here (25MB) zipped, or here (33MB) as a WMV.

I tried to make it useful for someone that has at least dabbled in ASP or ASP.NET, and wants a quick bootstrap into Microsoft's AJAX offerings.

 It includes introductions to:

  • AJAX
  • ASP.NET AJAX including coding demos of the UpdatePanel (including a look behind the scenes), Web Services, and the JavaScript extensions
  • The AJAX Control Toolkit including coding demos of using a couple of the control extenders
  • Creating AJAX Control Extenders including a coding demo of creating your own extenders

It is encoded at quite a high level of compression so the sound is a little distorted but perfectly understandable.

Note:I recorded this around 6am this morning, and around 55 minutes into it my three year old and five year old sons decided to make their own (very sweet) contributions to the screencast -- please forgive my momentary distraction, and when you hear me tell my three year old that he can take the money he found: he is  talking about two small coins I gave him yesterday.  This is not an attempt at bribary (honest!).

Many thanks to Atif Aziz and Dominique Kuster for organizing last week's presentation, and Dicomp Acadamy Suisse Romande for hosting it.

Filed under: AJAX, Screencast 8 Comments
22Feb/0717

Dealing with “Assembly x contains a Web resource with name x, but does not contain an embedded resource with name x. “

I got the go-ahead to move the ListSearchExtender from the prototype branch of the AJAX Control Toolkit to the development branch, and everything was going swimmingly until I got this error when running:
Assembly 'AjaxControlToolkit, Version=1.0.10201.0, Culture=neutral, PublicKeyToken=28f01b0e84b6d53e' contains a Web resource with name 'AjaxControlToolkit.ListSearchBehavior.js', but does not contain an embedded resource with name 'AjaxControlToolkit.ListSearchBehavior.js'.

I checked, and yes my ListSearchBehavior.js file did have its Build Action property set to Embedded Resource so the solution wasn't that easy.

Next I fired up the ildasm tool that comes with the .NET SDK and double-clicked on the manifest. Here I got a clue as to what was happening. It showed that the embedded resource was called AjaxControlToolkit.ListSearchBehavior.ListSearchBehavior.js whereas all the others were called things like AjaxControlToolkit.DropShadow.DropShadowBehavior.js

I went digging in my code and sure enough, I'd screwed up my assembly and ClientScriptResource attributes. This is the corrected version (the bold bits used to say ListSearchBehavior):

[assembly: WebResource("AjaxControlToolkit.ListSearch.ListSearchBehavior.js", "text/javascript")]
namespace AjaxControlToolkit
{
...
[ClientScriptResource("AjaxControlToolkit.ListSearchBehavior", "AjaxControlToolkit.ListSearch.ListSearchBehavior.js")]
...
public class ListSearchExtender : ExtenderControlBase

Hopefully this post will save others that are banging their heads against the wall with the same error.

Filed under: AJAX 17 Comments
21Feb/072

Initializing PopupBehavior in your AJAX Control Extender initialize method won’t work

In the ListSearchExtender which I am currently working to contribute to the AJAX Control Toolkit I use the PopupBehavior to display a DIV next to the ListBox (rendered as a SELECT) which initially has a message such as "Type to search...".  This is then replaced as the user types characters, with the characters they have typed.

If the user sets the ListBox to have the default focus (via the form's defaultFocus property) then I want to show the Prompt DIV immediately, which I initially tried doing in my control extender's initialize method.  This didn't work, and the reason is that there is a second initialization pass that takes place for the PopupBehavior, that is called by the framework, which hides the element (my DIV) associated with the PopupBehavior.  This second pass takes place after my extender's initialize method is called.

The workaround I used was to register a method to be called after all controls are initialized.  That would be the Sys.Application.load method:

this._applicationLoadDelegate = Function.createDelegate(this, this._onApplicationLoad);
Sys.Application.add_load(
this._applicationLoadDelegate);


My delegate gets called after all scripts have been loaded and the objects in the application have been created and initialized.

Filed under: AJAX 2 Comments
12Feb/073

Article: Cross-browser ASP.NET AJAX Control Extender support – trickier than I thought

I've just had an article on DotNetSlackers published on porting ASP.NET AJAX Control Extenders to multiple browsers.

Porting a control extender that I am working to contribute to the ASP.NET AJAX Control Toolkit turned out to far more involved than I initially thought it would be. If you are a hardcore JavaScript developer then a lot of this may be familiar. But if you are like me, and JavaScript is just one of many technologies you are using, read on to learn from my mistakes.

More at:

http://dotnetslackers.com/articles/ajax/CrossBrowserAjaxControlExtenderTips.aspx

Filed under: AJAX 3 Comments