28 март 2009, събота
Last months I have worked on a very interesting project which uses latest .NET technologies as well as some other APIs like Microsoft Virtual Earth and Google Earth. My team and I had a lot of challenging problems to solve some of which I want share with you.
Imagine that we have a user control called UserControlWithInlineScripts with the following code in it:
Now let’s put the control in a sample page like the following:
The ButtonShowControl on the server side only sets the Visible property of our user control to true. From first sight nothing strange – we have just a control which is showed dynamically by a button. If you test this code it will work perfectly well.
But what is the actual problem? Just put a wrapping UpdatePanel…
As you can see the browser cannot find the function which the button’s click calls. You know that everything with the function and its call should be OK as we have just tested it without the UpdatePanel. Therefore problem obviously is in the panel, but where exactly?
Explanation of the problem
Why this happens? When you update the content inside an UpdatePanel the old content of the panel is replaced by the new content trough the innerHTML property. In general if you set the innerHTML of a DOM element with markup which contains a script block inside it, this doesn’t cause the script to be registered as script in the DOM tree. In other words the browser looks at this new content as pure markup (text). If you want to say to the browser that some string is script (in other words inject a script block into the DOM) you can do this with the method document.createElement(“script”). Another way to evaluate and execute script, which you have as string is to use the eval(string) function, which takes only one string argument – the script to be executed.
There are some interesting static methods into the ScriptManager class which gives you the ability to register startup script, script block, onsubmit statement, etc. They prevent us from this problem if we do not have our scripts as inline and register them trough this methods.
In general it is not a good practice to have your scripts as inline and is better to have them as an external .js files. But the problem with the inline one still exists. You can think of some workarounds of this problem and this is my challenge for you – just share your ideas!