This article and the corresponding example code are available in a printable PDF download version.
Not all clear sailing
if ProductType=A then add items 1,2 & 3 to dropdown DD1
else if ProductType=B then add items 1, 4, 7 and 20 to dropdown DD1
else if Product Type=C then add null, 34, 78 to dropdown DD1
We then asked the users about frequency of change of the data concerned. If it did not change on a regular basis, then we could consider leaving it in as shown in Listing A and take the hit of the development team maintaining it. However, as this data was likely to change on a regular basis and the client required immediate updates—rather than logging a support ticket and waiting a few days—we decided to store it server side in a database table with a maintenance screen for the key user to manage the data. We began to discuss how we would pass this information from the server side to the client to be processed; we considered several options including:
- A hidden IFrame on the page.
- An XML file.
- A new popup window.
We decided to use the hidden IFrame approach so that we could hide the call from the users, but could also make the IFrame visible for debugging if required.
Our next problem was how to convert the tabular database table into a format that could be used by the rest of our application on the client side. We very quickly decided to simply dump the table into two Arrays—one for each column—and then cycle though them when required to populate the drop-down box.
Just as we were on the verge of resigning ourselves to this and preparing to brief the key users and management on this change and performance hit, one of the consultants from SolarFish—one of our consultancy firms—came up with an intriguing potential solution. He realized that the information needed to be updated using server-side code, but used on the client side. His suggestion was to amend the server-side script that updated the database to recreate a client-side script file on the server, which could then be loaded and cached like the rest. This file would then be as static for its lifetime as any of the static files, rather than being created dynamically every time it was called.
After some experimentation, we were able to get a working prototype using classic ASP's File Scripting Object to create the file on the server as part of the update process of the database table. The relevant fragment of code is shown in Listing C, and the result and output in Listing D. As this file would only ever by updated when the data was changed, we could treat it in the same way as the rest of our client-side script code and it would also be cached.
Having proved that this approach would work, we re-examined the rest of our Requirements Specification, and spotted several other situations in which the same approach could be reused, either to ease maintenance or to improve the offering we provided to our users. For example, we were able to create a database table of the field labels on the screen and then have any changes to the labels immediately populated to the end users' screens in the same manner.
Using this approach, we were able to meet our internal goal of delivering a system primarily using client-side code to minimize network traffic for our customer. In addition, we were able to add several items of functionality that could be managed by the customer rather than by a developer, allowing a quicker response time to most simple change requests, such as label changes.
Also, as the code was automatically generated and the data directly entered by the end users themselves, we were able to remove the developers—and any typos, errors, delays, etc. that they could be blamed for—entirely from the equation. This freed up the developers to work on other projects rather than making minor changes to existing code every time these bits of information changed.
Having created "code that wrote code" as we described it to our Project Manager, we had found a method that could be reused in other projects that we were working on. We had not come up with a name for this approach, but it seemed to be some kind of code factory, although most of the developers prefer to call these components "SkyNet" after the computer AI in the Terminator films, or "Hal" after the AI in the film 2001: A Space Odyssey; The latter seemed appropriate primarily because bugs were hard to find and fix and usually resulted in some really strange output.