I’m working with the awesome ExtJS framework again, creating an administrative interface to a huge amount of data. Each screen on this interface is basically a pageable grid with an editor window which pops up if you click a row. The grids can be sorted, and a separate filter area allows you to narrow down the items displayed on the grid in a manner unique to each screen.

The first time I wrote something like this using Monorail and ExtJS, I’d estimate that the javascript code was about 300 lines and the C# was maybe 150. Bear in mind that these screens, while differing due to the data being displayed, were essentially just CRUD interfaces. That means that to create a new screen, I’d be copying and pasting a lot of very similar code.

I’m sure you’ve been in this sitation before. If you’re really only going to be using this code in one or two places, there may be little value in making it a bit more generic. However, as soon as you break past that and find yourself copying and pasting the same code over and over, it’s a sure sign that you need to step back and pull out common functionality. That’ll provide three benefits:

  1. Less code means less to maintain
  2. It’s easier to create a new screen (copy/paste is never nice)
  3. Code reuse means silly errors are more quickly caught

In my situation I first created an abstract CrudController class, which accepts a type parameter of the entity which you’re Creating, Reading, Updating and Deleting. Later I changed this class to CrudController to allow me to add search specifications in a generic way. This class contains all of the actions you’d expect for CRUD as well as some for writing out JSON strings.

In the ExtJS side of things, I was able to subclass the GridPanel component and have a component that would automatically have a PagingToolbar, a particular click handler, and other default settings. I was also able to tailor the arguments to reduce the amount of code I needed to write to create it. Here’s a simple example.

this.grid = new App.standardGrid({
	cm: new Ext.grid.ColumnModel([{
			header: 'Id',
			dataIndex: 'Id'
		}, {
			header: 'Created',
			dataIndex: 'CreatedOn',
			renderer: function(val) {
				return val.format('l d F Y');
			}
		}]),
	fields: [
				{name:'Id', type:'int'},
				{name:'CreatedOn', type:'date'}
			],
	url: '/admin/quote/getjsonlist.castle',
	edit: this.edit,
	scope: this
});

Secondly, I could create a subclassed Ext.Window which would give me a better reusable editor dialog. Here’s how I defined that:

App.window = Ext.extend(Ext.Window, {
	height: 500,
	width: 500,
	modal: true,
	resizable: false,
	draggable: false,
	closable: false,
	bodyStyle: 'background: #eee'
});

As you can see, this is just a matter of giving sane defaults for a modal window, but later I subclassed App.window itself to create App.formWindow which was much more powerful.

These three steps dramatically reduced the code required to create a new admin screen in my application. More importantly, I cut the amount of boilerplate code I was copying every time to zero, which meant the code I did have to write was all important stuff. Less wading through identikit javascript means I’m a much happier developer!

My screencasts are consistently popular, so I thought I’d create another which talks about a slick usage of my favourite JS framework, Ext JS. In this screencast, I show how to display images stored on a server directory using a PHP JSON backend which provides data to an Ext DataView. I then allow deletion of these images and uploading of new images in an Ajax-style fashion, with no page refreshes.

This approach can be useful when editing a complex form - the details of a product you’re selling on your ecommerce site, for example - and you want to upload images without having to repopulate the other form fields when the page reloads, as it would with a standard file upload.

You can view the screencast here or download the full download the source code. I use loeppky’s BrowseButton extension for Ext 2, which you can read more about at his forum post. I hope you enjoy the screencast which is provided in association with Plastiscenic Ltd.

Reviewing ExtSharp 2.0.1

April 3rd 2008, 12:56 am in .NET, C#, Ext, Javascript.

After my earlier post on JS generation from C#, I wanted to investigate my options. Although zproxy highlighted the jsc project, I wanted to focus on a real world scenario first and so I’m looking at ExtSharp, which relies on Script#, a project which will “compile your C# source code into JavaScript”.

ExtSharp leverages Script# to allow you to write ExtJS applications in C#, which was my target when I began thinking about JS generation. I’d like full intellisense, documentation and compile-time checking when working with this rich framework. Will ExtSharp give me that?

Downloading ExtJS2Samples-v2.0.1.zip from the Google Code site gives me a solution of samples. Here an interesting implementation issue arises - all of the actual C#-Javascript class files are in a separate project to the .aspx pages which display them. This is down to necessity; Script# uses an assembly called sscorlib which, bizarrely, seems to provide its own implementations of many of the .NET types found in the mscorlib assembly.

This separate project also runs an MSBuild targets file from Script# which runs after main compilation to compile the C# into Javascript. Straight away I’m seeing two bits of magic - sscorlib and post-build events - which I’m not too keen on. But the solution builds, and after changing the web.config references to nStuff.ScriptSharp.Web to 0.4.5.0, I am able to view the samples.

Based on my earlier post, I was interested in the Window sample, but unfortunately that didn’t work. The array Grid one did though, and it operated just as the ExtJS website sample does. Many of the other samples are missing, which is disappointing; of the ones which are present, most work very well. Overall, I was encouraged, and I moved on to looking at the C# code which was generating these samples.

Let’s look at how a ColumnModel is built when working in Javascript:

var colModel = new Ext.grid.ColumnModel([
           {id:'company',header: "Company", width: 160, sortable: true, dataIndex: 'company'},
            {header: "Price", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},
            {header: "Change", width: 75, sortable: true, renderer: change, dataIndex: 'change'},
            {header: "% Change", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},
            {header: "Last Updated", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange'}
 ]);

I think that’s pretty concise - there’s not a lot of cruft. Now the ExtSharp version:

ColumnModel colModel = new ColumnModel(new Dictionary[] {
    new Dictionary("id", "company", "header", "Company", "width", 160, "sortable", true, "locked", false, "dataIndex", "company"),
    new Dictionary("header", "Price", "width", 75, "sortable", true, "renderer", new MoneyRenderer(Format.usMoney), "dataIndex", "price"),
    new Dictionary("header", "Change", "width", 75, "sortable", true, "renderer", new ColumnRenderer(change), "dataIndex", "change"),
    new Dictionary("header", "% Change", "width", 75, "sortable", true, "renderer", new ColumnRenderer(pctChange), "dataIndex", "pctChange"),
    new Dictionary("header", "Last Updated", "width", 85, "sortable", true, "renderer", Format.dateRenderer("m/d/Y"), "dataIndex", "lastChange")
});

Hmm. Lots of strings - I’m not keen. This is one of two methods of providing a configuration to an Ext class, the second of which involves a specific config class:

Ext.grid.GridPanel grid = new Ext.grid.GridPanel(new Ext.grid.GridPanelConfig()
    .el("grid-example")
    .ds(ds)
    .cm(colModel)
    .autoExpandColumn("company")
    .height(350)
    .width(600)
    .title("Array Grid")
    .ToDictionary()
);

Unconventional style, to say the least, but at least it’s properly typed. This is pretty far away from my ideal API for this kind of thing. Let’s look at how this is turned into Javascript.

As I previously mentioned, the Script# project contains MSBuild targets which generate the JS code after the build is complete. This code can then either be referenced directly, or via some ASP.NET controls from your ASPX pages. As well as your own generated code, you must also reference a couple of Script# files and a wrapper file for Ext itself. That wrapper file is actually what makes everything work here - rather than your C# code being converted into something which works with the Ext library, it instead only works with the Ext wrapper provided by ExtSharp.

Looking at the ExtSharp project overall, I’m not a convert. There are too many layers between your C# and where it finally touches the “real” Javascript:

1. Your generated JS
2. ExtSharp JS wrapper
3. Script# utility JS

The C# API is also pretty horrible - certainly not in my style but also far from being an API I recognise from any other project I’ve worked on. Whether this is a style choice or due to technical limitations, I’m not sure.

The ExtSharp project definitely drew my curiosity, and could hold promise. In its current state, I wouldn’t consider using it in a project of my own, as the API is not strong enough to make me swap from native Javascript. Still, I will continue to follow future work with interest.

I’ve previously talked about my dislike for code generation in Javascript. I still standby that, but I am beginning to have a change of heart for certain scenarios. I’ve been working on a couple of ExtJS applications recently and I’ve got lots of code which is purely ExtJS stuff on its own - no HTML or other code in there really. It’s been a project where I’ve been using C# 3 and it’s partly the similarities between the two languages which have triggered this rethink.

Take a look at this code:

var win = new Ext.Window({
	title: 'Order Viewer', layout: 'border',
	width: 500, height: 500,
	modal: true, resizable: false, closable: false, draggable: false,
	items: [ frm, lst ]
});

win.on('render', function() {
	load(5);
});

win.show();

That’s pretty standard stuff for what I’m doing with Ext right now - I create a new window with a load of configuration options, then add in an event handler for the window’s render event, and finally show the window on screen. Now imagine that you could write the following in C# 3:

var win = new Ext.Window{
	Title = "OrderViewer", Layout = Layout.Border,
	Width = 100, Height = 200,
	Modal = true, Resizable = false, Closable = false, Draggable = false,
	Items = new [] { frm, lst }
};

win.Render += delegate {
	load(5);
};

win.show();

As far as I’m aware, all of the above is valid C# 3 code. I’ve basically written it as I’d like to use it, with an enum for the Layout type, and C# style event handler syntax, but the interesting thing to me is how very similar it is to the Javascript version.

The ExtSharp project allows you to write your Ext code in C# and have it rendered as Javascript. I’m going to explore it in my next post, and examine how closely it can be made to fit the code sample above.