September 10, 2004

Using ASP.NET to Implement the Template Method Design Pattern in JavaScript

Usually, developers use ASP.NET to create Web Forms or dynamic pages for display in a browser. But ASP.NET is really a powerful general-purpose server-side host for the .NET Framework. ASMX Web Services are an example of using the IIS infrastructure to expose the power of .NET over SOAP. In this article I’m going to discuss another way to leverage the power of ASP.NET – as a means of dynamically generating JavaScript code. Specifically, I’ll show you how I used ASP.NET in a real-world scenario to provide a Template Method implementation in JavaScript.

Consider the following constraints:


  1. There is a website in a different domain that needs to populate the contents of an HTML select box with some data that our company must provide dynamically at runtime.
  2. The proprietors of the website do not have developers available that can write code that consumes a web service. In fact, a copywriter with only basic knowledge of HTML will be adding any needed code to the website.
  3. We cannot actively populate a select box that lives in another domain (this would be a security violation) via JavaScript.

One solution to these constraints is to include some generic JavaScript in the page that needs to update its select box. This JavaScript code will contain the algorithm for reading the values of an array and using them to create a new Option object that can then be added to the select box. The only caveat is that this JavaScript will defer the creation of the value array to some other script. This closely resembles the GOF design pattern Template Method, at least in its intent. The Template Method design pattern establishes a virtual or abstract method that subclasses should implement. In the case of JavaScript, we can’t make use of inheritance, so we will simply rely on an included script to provide the method implementation for us.

Let’s look at some code. The html page will look something like this:




Test Page






Notice the call to getDataArray(). We have not defined this JavaScript function anywhere. This is our Template Method. We will rely on an included script to provide the implementation of this method for us. Let’s add a script tag BEFORE our algorithm that includes an external script – but let’s make the src of the script an ASP.NET page that will generate the JavaScript dynamically for us.

We’ll add the following line of code before our original script tag:

Our head now looks like this:



Test Page




The only thing that remains is to provide the ASP.NET implementation. To begin with, we will create an ASP.NET web form and strip out everything the IDE generates for us with the exception of the directive. Our default.aspx page looks like this:

<%@ Page Language="C#" CompileWith="Default.aspx.cs" ClassName="Default_aspx" %>

I’m using the .NET Framework 2.0 beta, but you can implement this technique with any version of the framework. The code-beside (or code-behind) page will contain the following code:


protected override void OnLoad (EventArgs e)
{
string javascript = @"
function getCityCodeArray()
{
var cities = [{0}];
return cities;
}
";
Response.Write(javascript.Replace("{0}", GetCities()));
}
private string GetCities ()
{
return "'Miami', 'Orlando'";
}

Of course, a meaningful implementation of GetCities() would probably access a database, file, or web service and return the string with that data. This technique allows the partner with ASP.NET to generate the data dynamically for the site that lacks the capability or resources to implement a dynamic solution. Lastly, I would like to point out a small optimization we made in the client side script.

document.getElementById('ListBox').length = cityList.length;

The code above sizes the Options array of the select box large enough to hold all the data returned from the external ASP.NET/JavaScript. Leaving this line out will cause the JavaScript engine to dynamically size the array on every iteration of the for loop. In this article I’ve showed you a real-world hack that leverages the power of ASP.NET to write dynamic client-side code to be included in another domain. Ideally, we wouldn’t jump through hoops like this but sometimes you have to rely on a clever hack rather than an elegant solution.

Posted by Christian at September 10, 2004 03:53 PM |
Comments
Post a comment