I've finally had some time to update the West Wind Ajax Toolkit to version 1.90. A number of these changes I've written about and have updated previously, but this update finalizes a number of these updates into a full release. There are a number of enhancements to the existing functionality as well as a few new helper components that I'm finding very useful these days.

The toolkit consists of a number of controls to provide JSON callbacks and JSON service, popup hover windows, modal dialogs and a few other Ajax based controls. In addition the Toolkit includes a host of utility classes that provide services to ASP.NET AJAX pages including a generic JSON service, a Json Serializer, a ClientScriptProxy that can automatically route to either ClientScript or the ASP.NET ScriptManager, a ScriptVariables class that lets you embed data into client pages easily for client code access, a ScriptContainer for adding scripts to a page consistently in markup and through code, a script minifier and a JavaScript GZIP compression tool and much more.

Following are a few of the highlights of the release's new and changed components.

Improved JsonSerializer

Thanks to the help from Joe McLain there have been a number of improvements in the serialization code of the parser. It now deals much better with array/list de-serialization which previously was a bit shaky. Arrays/Lists are now supported as root objects or as embedded properties in objects. The latter worked before but there were problems with root arrays. A number of string formatting issues in deserialization are also fixed and the date parsing logic can now deal with ASP.NET AJAX/WCF style JSON dates, as well as the proposed ISO date literal and plain old new Date() syntax. Internally the serializer uses the ASP.NET AJAX date format now, but there's a switch which allows generating the new Date() 'code' syntax instead so you can use the serializer for creating fully runnable JavaScript.

ScriptVariables class

I talked about this class some time ago - it provides the ability to easily embed server variables into client side code by way of a client side object that contains these variables. So you get ServerVars.MyVariable with a server set value applied. Values can be applied literally via Add methods or be applied dynamically which reads values out of any object reference or control property.

Values are properly JSON encoded and can then easily be accessed on the client. The object also supports the ability to read these object values - optionally - back on the server side in a Postback if they are changed on the client. This is a great way to persist values without explicitly having to assign them to hidden variables or a field on the form.

You can create multiple server script variable objects as long as they each output a unique name (with the default being ServerVars) and control builders can also use this tool from within control code without interference with application level code by using a unique name.

Optionally this control can also optionally generate properties for each of the controls on a form and provide non-NamingContainer Ids. So even if txtName is inside of a user control you can access ServerVars.txtNameId to get the control name.

I've found this component to be extremely useful as it provides an easy way to embed:

Variable names that are mangled by ASP.NET naming containers - no more <%= txtName.ClientID %>either explicitly added or automatically generated through AddClientIds()

I've found this class extremely useful in Ajax applications, especially for pushing down sensible control names and avoiding the <%= ClientID %>mess on the client.

ScriptContainer Class

I've mentioned this class in several posts - it's essentially a script manager that's somewhat similar to the ASP.NET ScriptManager, except it doesn't rely on .NET 3.5 and doesn't output MS Ajax scritps by default. It also provides a bit more control with the ability to determine where scripts are rendered: In the header, after the form tag (standard ASP.NET mode) or inline where the control sits. This setting can be applied either to the control in general or to the individual scripts added, which allows you a little more control over how scripts get loaded.

Scripts can be added either in markup or programmatically and there's only a single instance on a page that's allowed so all scripts can be added to the same manager. This means controls, page code and markup can ensure that scripts only get added once. The syntax uses HTML generic controls using <script> tags so there's Intellisense support for the embedded scripts.

Additionally you can specify whether you want to allow min script to be accessed (ie. .min.js files that are compressed or minimized). If you do and the file exists the control will use the minimized files when running the site in non-debug mode.

JavaScriptMinifier.MinfyDirectory Method

This new method can be used to minify all java script files in a directory or directory hierarchy in batch to create min script files. You specify the path the min extension and whether to recurse into child paths and this method will create the min files automatically checking for changes as needed. This works great in combination with the ScriptContainer class by sticking a call to this static function into Application_Start which will check for script changes on startup of the App.

A few JavaScript Helper classes for Formatting

This update also includes a number of simple helper functions for string, number and date formatting. String gets a basic but highly useful .format() function that uses simple C# string replacement (but without format options). Number gets a .numberFormat() function that does decimal and currency style formatting (c,n,f3,n2) and Date gets formatDate that provides basic formatting using the .NET date format specifiers ( ie. MM dd yyyy, HH mmy). This is nothing new, but it's just so damn useful and necessary that it has to be in the utility library.

Additional changes

There are many more small changes and updates especially in the JavaScript library that fix a number of small issues that have been reported and you can find out what's updated here:

Interested in Feedback

As always I'm interested in feedback on the components and how you might be using them. There's a lot of functionality in this toolkit, yet I suspect a lot of people are taking components out of it and using individual pieces in their own libraries or applications, which is great.

I'm especially interested though in feedback about the new ScriptContainer and ScriptVariables classes as I think they are great generic tools that could be expanded upon a bit more. Feedback can drive this better so if you have any comments post them here or on the support forum

What's Next?

A couple of things really should happen next. First of all the samples of the toolkit are getting reaaaallly long in the tooth. While they work and get the point across, most look crappy and use some rather lame examples. So the samples will be updated at some point shortly.

For the next major version there will be a complete reworking of the client library to use jQuery. There's a ton of overlap between wwScriptLibrary.js and what jQuery provides and using jQuery to provide the base and core library would reduce the code in wwScriptLibrary by more than half. jQuery doesn't provide all the utility functionality provided in wwScriptLibrary but there's definitely some overlap. I think most of the higher level components - especially the client side control interfaces - can easily be maintained backwards compatible or with only minor changes even given this major of an update. This will be a major change but it's looking good for keeping the interface intact and not breaking old code. Once this is done it'll be much easier to start integrating more jQyery based components in a similar fashion as the wwDatePicker.

I am considering this for a project that I'll probably soon be tackling.

One of the reasons the project has been on hold is unease with the official ASP.NET Ajax implementation. This gives a bridge to roll my own where that's sensible. (Logjam is likely broken.)

First thanks for making this work available and on such open terms that it isn't an impediment for business.

A couple of questions that come to mind.

1) With this there is a way to bridge the ASPX and ASP worlds. (I have an application which uses ASPX to load a database to an ASP application, the "test it works" stage uses near clones of ASP content. This is not a frivolous issue!) Has anybody done that using this toolkit? What suggestions?

2) I like blanket coverage of tests in some of the work I do. (Not strictly unit tests only.) How does the toolkit play with and contribute to such testing? What suggestions and examples?

Some very nice pieces of functionality here Rick.I reckon you'd easily give the AJAX Control Toolkit a run for its money in the modal scenarios etc. I've been working with a client-side only modal implementation that takes any element and wraps it - lots of fun aren't they!

@Mike - you probably will need to be more specific with your questions. I don't understand #1 and #2 is really up to you. Essentially this is a component library and you can use it as such (as an added assembly). If you want to run full tests on it, you can do this but it's up to you to set this up. I have a small suite of unit tests I run on a few of the system level components (like the JSON Parser, minifier and utility libraries), but it doesn't extend to the control or components that heavily rely on the HttpContext...

@Brandon - JsonParser.cs is not actually used. You can remove that from the project and the code should compile just fine. I've uploaded another version that includes the JsonParser (which is Joe McClain's code actually), but it's currently not directly plugged into the toolkit.

Hey Rick - I've enjoyed your blog a lot, keep up the good work. Have you never used ExtJS? It's control library is very much untouchable, you should think about adopting it rather than trying to roll your own solution. Your server helpers are good however. But with .NET 3.5 a lot of your helpers aren't really necessary such as your JSON serialization. However if I ever am in a need to do a legacy 2.0 app I'll snag your toolkit.