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:
OnItemLinkClicked(someId) { PageMethods.SomePageMethod(someId, OnSomePageMethodSucceded, OnSomePageMethodFailed); }</code>
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.