What's hot ? (and I mean really ...) - scroll down for more
1).  Code Templating - advanced usage of delegates & generics: my slides & demos are available for download! CodeProject article is also available.

2).  My series "TDD in the eyes of a simpleminded" is in progress(including code!): preface, part1, part2, Q&A 1, Manual Stub .vs. Mock Stub

3).  TDD Workshop: SeeCompass v0.1 and v0.2 are out.
# Wednesday, April 18, 2007

I'll start my post with a question:
What's the difference between ScriptManager.RegisterClientScriptBlock and ScriptManager.RegisterStartupScript methods?

Well, the only way to find out is not by looking at the method names but rather to look in MSDN. According to MSDN the former registers your script after the <form> element while the latter is registering your script just before the </form>. Now, let me ask you this - how the word "Startup" can be interpreted as "end of page"?

So OK, the naming is really bad but what's even worse are the arguments of these methods:

public static void RegisterClientScriptBlock(Control\Page control\page, Type type, string key, string script, bool addScriptTags);
public static void RegisterStartupScript(Control\Page control\page, Type type, string key, string script, bool addScriptTags);

Now, most of us write this code 95%(+) of the times:

ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "some stupid key", "the script here, finally...", true); //like someone is stupid enough to give false - if you have a full script, why not putting it inside myFile.js and add it to the header?

I don't understand the real need behind creating a "unique" key from the type+key given to this method. Why not creating a unique key each and every time? You need to create a simple API for the common (90%) tasks. I almost never actually asked about IsClientScriptBlockRegistered. But enough complaining, time to write a few bits & bytes.

I tried to play with the API a little and here is what I came up with (it's merly the beginning, I'll update on my progress during the week):

PageClientSideExtender clientSide = new PageClientSideExtender(Page);

// A better approach, IMHO, to ScriptManager API
clientSide
  .RegisterScript("alert('run at the beginning of the page');")
  .AddScriptTags()
  .RunAtTheBeginningOfThePage();

clientSide
  .RegisterScript("<script>alert('run at the end of the page');</script>")
  .RunAtTheEndOfThePage();

//let's register something like:
// var width = 300;
clientSide.RegisterLocalVariable<int>("width").SetValue("someValue");

//let's register something like:
// var data = 'width:300;height:500';
clientSide.RegisterLocalVariable<string>("data").SetValueFormatted("width:{0};height:{1}", 300, 500);

// Let's register to the onload of the <body> and trigger a nice alert
clientSide.Body.Load += ClientSideScriptHelper.CreateHandler("alert('run on body onload! cool ah??');");


//Or:

clientSide.Body.Load += delegate { return "alert('another message shown after the page onload event was raised. sweet!');"; };


The Fluent interface gives it a nice "read-the-code-like-a-story" look&feel which makes things really easy to understand. There is no thinking here, the code says it all.

Another rant I have is that all of the API examples I've demonstrated so far are implemented although not fully tested as using Microsoft classes requires a lot of work in order to abstract. The funny thing is that they(Microsoft) have decoupled things in the new Microsoft ASP.NET Ajax library(System.Web.Extension.dll) but they made everything internal!  You have IPage, which is really useful abstraction to the Page class, sitting there as an internal member. I had to come up with some heavy abstraction to make things play nice together.

To sum up, I would really appreciate YOUR feedback about the API and any kind of suggestion or things that you would like to see in future API. I'll release the code later this week with a short demo to get you going.

Thursday, April 19, 2007 5:06:05 PM (Jerusalem Standard Time, UTC+02:00)
Hey dude!

There is something in your saying, the key value to enter is quite annoying and seems to be unnecessary (could be handled by the system).
About your API, I didn't think that I understand the sytax, fix me if I am wrong: Are you concating method to each other? If does, why are you doing it?

Generally, I liked your explicit method names and the usage of the generics feature that simplifies the code.
Thursday, April 19, 2007 5:21:20 PM (Jerusalem Standard Time, UTC+02:00)
Hi, it's me again...

I am going back on me regarding the methods concating, it undarstood... :)

In the RegisterScript methods I whould rather to use the classic way of sending params to the method - it looks quite unnatural, because you are adding properties this way, right?

Do you need to be driven by the methods order? If you want to give up of one of the methods do you must insert it?

Eran
Saturday, April 21, 2007 11:37:05 PM (Jerusalem Standard Time, UTC+02:00)
These are terrific questions.
I decided to talk a little more about fluent interface, why to use them and pros&cons here:
http://www.lnbogen.com/FluentInterfacesLetTheAPITellTheStory.aspx

I would love to get your feedback. Thanks.
Thursday, May 03, 2007 4:26:40 PM (Jerusalem Standard Time, UTC+02:00)
"I don't understand the real need behind creating a "unique" key from the type+key given to this method. Why not creating a unique key each and every time?"

Because if for example you write a usercontrol or webcontrol that uses clientside javascript, and you use more then one instance of that control in your page, you want might want to include the javascript only once, hence you would use the same key to make sure of that. Ofcourse you can include the javascript in the hosting page, but that's a bad solution.
codemonkey
Tuesday, June 12, 2007 9:42:24 AM (Jerusalem Standard Time, UTC+02:00)
Why not try Script#:
http://www.nikhilk.net/ScriptSharpIntro.aspx

It simplyfies development and deployment of complex client-side javascripts.
DKL
Comments are closed.