Reconsidering Standard Web UI
A year or so ago, I took it upon myself to write a PHP class that would make form-building simple. Call the constructor with a few options (such as the URL, the method, and whether or not to include a js validation script) and then begin adding your elements, passing various bits of data such as the row and column within a table, the name, type, value(s), CSS class, validation rule, etc. Then call the execute method and you’ve got a nice form generated from PHP code without having the HTML tags written in the code itself and rendering it unreadable. Pretty nifty.
Shortly after writing the first version of this code, I discovered CSS Zen Garden, which showed just how versatile CSS can be. Given the same HTML source code and allowed to alter only the CSS definitions, dozens of designers have created vastly different site templates of sometimes staggeringly good quality. Well if they could do that, I thought, then surely I could use CSS to build a sharp looking Web application interface that looks less like a Web form and more like a desktop application. My particular challenge was to roughly emulate a Windows application my company uses to manage projects and resources. It’s a tabbed application, and each tab panel has subsections with nice sunken borders and blue header labels. It’s not the sort of thing you’d typically try to build using HTML, but with my newfound reverence for CSS as an architectural tool rather than simply as a way of defining font and color attributes, I decided to try the typically untried.
With a few changes to my form class, I was able to pass div names and to set titles for subsections within a given page. The class generated divs within divs (a title and a content div within a parent div) for each element group defined for a given form. The CSS included for a given page contained definitions for each of these parent divs as well as more generic definitions for the look of the title div (blue background, bold white font, some padding, offset from the parent by X pixels in one direction and Y in the other) and the content div (gray background, gray/white borders to give the appearance of depth, some padding, and an offset) within the named parent divs. With really minimal effort, I built an application front-end that resembles very closely the appearance of a thick desktop application. Yay for CSS.
But even that has limitations. First off, although it’s good to separate the content from the logic from the styles, it’s sometimes a pain to keep everything in sync. Add a field to a subform within a page and you’ve got to go to your CSS to change the vertical position of any subforms below the one you just changed. And to do that, you have to go into the display code to determine the name of the subforms in question so that you can change the appropriate style defintions. And then you have to test it in all the browsers you anticipate will be using the application. What’s more (and this is a minor consideration, but it is a consideration), if a Mac user saw my application, he’d find it odd and perhaps a little off-putting that it looked like a Windows application. And finally, the main barrier to using Web applications efficiently is the time spent going back and forth to/from the HTTP server. You request a page and wait for it to render in your browser. If the page has a data grid representing 100 rows of data with 20 columns per row and all sorts of validation routines, select boxes, etc., for many of the columns, it can take a few seconds for the page to render. When it finally renders, you make your changes and submit the form. It goes out, talks to the business logic part of the application, and returns. My applications most often return to the page just submitted, with the values changed and a status message prominently displayed. Which means that the 100 rows of 20 columns have to be reloaded. Which can get a little annoying for the user in spite of how cool an accomplishment the application is from a technical standpoint.
The Plot (and Application) Thickens
So if Web applications are such a pain and are especially prone to scalability and performance issues, why use them? The application I originally modified my form class to emulate was a thick desktop application, after all; if I was wanting to get away from that particular application, why not just code a better thick desktop application from scratch?
In short, I didn’t do that because it’s just so darned hard. While I’m sort of proud to be able to answer the “so what do you do” question with “I’m a developer,” I’ve always drawn a line between the kind of development I do and the kind “real” programmers do. I’m a glorified script kiddie, hacking together interpreted code and using simple markup languages to perform some really pretty basic tasks. There’s a big difference between collecting form data for input into a database and engineering complicated applications for manipulating satellites, say, or for editing images.
To my mind, the substantial difference can be boiled down to having (vs. not having) the ability and resources to write compiled user interface code for the front end that hooks into compiled business logic code on the back end. Any number of times, I’ve fired up an IDE for building user interfaces and have dumped some widgets onto a layout grid to make a neat looking application. But then I’m confronted with making the widgets actually do something, which means facing the blank screen of a C or C++ editor and figuring out what to write. Which is a lot different (for me) from confronting a blank screen when writing a Web application and knowing that if I just use the elements contained in the $_POST array, I can work magic with the data submitted by form to the page I’m editing. It’s not that I’m incapable of figuring out how to write the C or C++ or python or java code, incidentally. I just always get to that point and remember that I haven’t learned yet how to connect the UI to the back end. And I move on to the next thing because I don’t have the time or the resources or, in some cases, the gumption to figure out the rough equivalent in the given language of using the $_POST array in PHP or the beefy CGI.pm in perl.
For all their benefits (most notably efficiency and a reduced likelihood of hackability), thick applications don’t come without their warts. As noted above, for example, connecting the UI to the back end strikes me as a bit more abstract. And I find rapid application development in strictly-typed languages to be darned near impossible, not to mention that deployment and maintenance of thick applications can be a bear. Need to change the spelling of a hard-coded label? Edit, recompile, test, and install on necessary desktop systems rather than just changing a text file on the Web server. Cross-platform functionality and easy installation across platforms can also be painful for thick applications.
Web < Rich < Thick, or Meeting Somewhere in the Middle
If Web applications don’t quite cut it for the user but thick applications are overkill for the wannabe programmer, what’s to be done? Are we script monkeys resigned to delivering sub-par applications to our users, and are uber-programmers made to kill flies with cannons by writing thousands of lines of code to build simple applications? Well, no.
The Tip of the Iceberg
But all XUL does is to define the user interface. Don’t get me wrong — this is no trivial accomplishment: We’ve gone from having to build and name and size and position and otherwise tweak (wrestle with) form elements in a complicated IDE to writing a brief structural document outlining what elements should appear within an application and roughly where they should go (XUL’s pretty smart about stretching and moving things to fit nicely, though you can provide hints and even add CSS definitions if you want more granular control over elements). For example, a sample application I put together contains three tabs, configured as follows:
- Search Tab. Contains a search box and button to trigger the search.
- General Tab. Contains about a dozen fields to hold contact information for a given person.
- Extra Tab. A blank tab that other fields could be added to and that I originally built to help me test my database functionality (about which more in a moment).
The tidy and utterly readable code to produce this GUI runs 135 lines including white space and declarations of scripts used to perform the business logic of the application. If I want to change a field label, I make a change to the file, reload it in my browser (or using the chrome option as demonstrated above) and I see the change immediately and without recompiling a thing. If I happen to deliver the XUL file over the Web, once a given user redownloads the application (which, note, is very concise and, even with the download, takes less time to load than your standard thick application), he sees the change immediately. In other words, reworking and redistributing parts of the code need not be a nightmare.
The Rest of the Iceberg
The result is seamless communication between what appears to be a thick desktop application and some data source. There’s no page reload, no flicker or long pause as form elements are rebuilt. The application itself is running locally, so it’s rocket fast. And because I’ve got a speedy apache/mysql server, the data retrieval takes no time at all. Furthermore, I can eliminate the need for a submit button (one of the biggest complaints among my users, who use a blend of Web and thick applications) by executing update commands (for example) on tab focus or exit.
XUL applications provide the best of both worlds, a native, platform-independent client with the flexibility to hook into local or remote business logic of varying sorts. I’ve chosen to use XML-RPC as opposed to hooking into custom C code that does database connections natively and performs more like one of the applications I’ve had a mental block against writing in a complicated IDE. The nice thing about the XUL framework is that you can write your own C libraries to manage database connectivity natively if you want to (at a substantial overhead savings, no doubt), but you can also tap into existing code or write XML-RPC servers that you can access from several applications (at a code redundancy savings) or do pretty much anything you want to. If you’re intrigued, check out XUL Planet for a complete XUL reference, or download Mozilla Firefox and Thunderbird (Mozilla’s standalone mail client). Both of these full-featured applications are written in XUL. They’re trim and fast and cross-platform-friendly and serve as the best examples to date of what XUL can do.
With a little luck in the form of management buy-in, this wannabe programmer will have another fine example by the end of the year.