views:

459

answers:

2

I have a UserControl that I want to include in a page multiple times programatically based on some business rules. Currently the control has a JavaScript function that must be called on the ASP.NET AJAX pageLoad event.

I'm using a pattern where the Master page has a pageLoad function that calls a contentPageLoad function on any ContentTemplate, if the function exists. The ContentTemplate that holds the UserControl in question would then be responsible for calling the appropriate function on the UserControl during this event.

Right now, the JavaScript is inline in the .ascx for the UserControl, but I have a feeling that I'll need to use the Page.ClientScript property to inject it via code behind. My question is: how do I make sure that my function names don't get clobbered, and make sure that the appropriate method gets called for each UserControl?

FYI: the code that needs to get executed for each UserControl is a block of jQuery that creates a Multi-Select control from a standard HTML <select>.

EDIT: RegisterStartupScript was suggested, but this runs before the DOM is finished loading. Wrapping the function in a jQuery Document.ready() doesn't seem to help. The user control is running inside of an UpdatePanel, so I don't really have a choice about how to call this script.

+1  A: 

One solution is to use the ClientID of the user control in the JS function definition:

function onLoadInitialize_<%=ClientID%>(){/*do things*/}

and then use Page.ClientScript.RegisterStartupScript to cause it to happen during client-onLoad. Be aware that page_load happens on every asynchronous postback; if you want things only to happen once per actual page load (excluding async postbacks), use the init event instead.

DDaviesBrackett
That was my first instinct, but `ClientId` doesn't exist in the context of the UserControl. Would I need to inherit from a certain class or interface?
technomalogical
Whoops, had a typo (ClientID should have a capital 'D') but I'm still not sure how to handle calling each of these functions on the AJAX page load (to my knowledge, client onLoad will only happen on the first page load.)
technomalogical
updated answer - page_load will actually happen on every async postback, which I think is what you want.
DDaviesBrackett
It sounds like your approach is on the right track, but RegisterStartupScript doesn't hook into page_load auto-magically, that I can see anyway. Any suggestions on how to do this?
technomalogical
it doesn't hook automagically, no. You'll want to look into Sys.WebForms.PageRequestManager's event hooks (MSDN has all the documentation).
DDaviesBrackett
+1  A: 

So I ended up taking a hybrid approach to what @DDaviesBrackett suggested. I am registering a function with Page.ClientScript, not as a startup script, but as a ClientScriptBlock. The function uses classes instead of IDs (and thus, ClientIDs) to attach to each control. The basic structure is:

if(!Page.ClientScript.IsClientScriptBlockRegistered(Page.GetType(),"scriptkey"))
{
    Page.ClientScript.RegisterClientScriptBlock(
        Page.GetType(),"scriptkey",script,true);
}

with the following script:

function bindMultiSelects() {
    $('.multiselectclass').multiSelect({
        oneOrMoreSelected: '*', 
        noneSelected: 'Select Item(s)'
    });
}

(using the awesome jQuery MultiSelect plugin)

Again, this works because my Master page creates a page_load method that then calls a method on the content, which then calls bindMultiSelects. Just for my own reference, the page_load and contentPageLoad functions both follow this "plugin" pattern I found here:

if(typeof functionname=='function') {
    functionname()
}
technomalogical