tags:

views:

42

answers:

2

I have page that has some javascript that needs to run at page load. Said javascript needs to locate the client-side component of a ServerControl, which it does with $find().

Of course, if I emit my code directly onto the page, it executes as the page is being read, and fails because nothing it depends on is yet initialized.

If I put my code inside a pageLoad() function, it runs just fine, because asp.net automatically wires up an onload handler for any function named pageLoad(). The problem is I really don't like the pageLoad() solution - mainly because it's a single global name. If I commit some code using pageLoad(), I just know that some other programmer is going to copy the approach, somewhere inappropriate, and we're going to end up with a page that includes two or more different pageLoad() functions, and the result will be a bunch of mysterious errors that will take forever to track down.

So, I put my code inside an anonymous function passed to jquery's $(document).ready(). This fails, because it runs before the ServerControl's client-side component exists.

So, I put my code inside an anonymous function passed to by Sys.Application.add_load(). This also fails, because Sys is undefined.

So I finally settle on putting my code inside Sys.Application.add_load(), and then put that inside a function called by $(document).ready(). This works, but it gives nearly as much heartburn as pageLoad().

<script type="text/javascript">
    $(document).ready(function(){
        Sys.Application.add_load(function(){
            var component = $find(<clientid>);
            if (component) { <do something> }
        });
    });
</script>

There has to be a better way of handling this.

Any ideas?

+1  A: 

I believe if you add (or move) a ScriptManager control above your script block, you wouldn't need to wrap it in jQuery's $(document).ready() function. By doing this apparently Sys will be available as the ScriptManager:

injects the bulk of that JavaScript in the exact location that the ScriptManager control is positioned at in the page. [http://encosia.com/2007/08/16/updated-your-webconfig-but-sys-is-still-undefined/]

However, this solution may still give you heartburn as it would certainly not be obvious to any unsuspecting developer what the ScriptManager is actually providing here.

Another method where script references are added inside the ScriptManager (see "Better Way" discussed in the linked article above) doesn't sit that well with me either as I'm not a huge fan of the whole ScriptManager approach.

Bermo
+1  A: 

If you have control over the code-behind, you can register the JavaScript to run at startup via something like:

this.Page.ClientScript.RegisterStartupScript(
    this.GetType(), 
    "StartupScript", 
    "Sys.Application.add_load(function() { functioncall(); });", 
    true);

As long as your component has been loaded via Sys.Application.add_init() you sould be fine...

Mike McCaughan
That seems to work for us.
Jeff Dege

related questions