Support for Scripting
script tags in Listing 1 add this functionality to the XUL applet. The applet works as follows:
- All menu items except the Login and Help menu are disabled until the user logs in. Logging in means acquiring a session ID from the Web server of origin.
- Once logged in, the Ticket menu is enabled.
- Once a specific ticket is chosen from that menu, the related form elements appear in the body of the widget and the Action menu is enabled.
- The server is queried for a ticket number that can be used for that ticket.
- If Submit is chosen from the Action menu, the ticket is sent to the server using an ordinary HTTP
GETrequest, where it is processed as for any other HTTP submission.
I'm not examining the mundane server code required to accept that submission in this article.
code. Three source files are included to do this work, using XUL's
version of the HTML
tag. The script file init.js performs sundry initialization, while
commands.js implements all the menu options, and server.js acts as the
nuts and bolts of the client-server interactions.
The init.js file, shown in Listing 4, reveals the environment in which XUL scripts run.Listing 4. init.js performs initialization
Since XUL is a flavor of XML, the many W3C standard DOM interfaces are available. These interfaces make the XUL and HTML document available as an apparent tree of Element nodes, including DOM 0 features such as cookie support and the navigator object.
getElementById() is the standard version of Microsoft's
functionality. The objects made available by the DOM standards are
entirely separate to the thousand objects that are supplied by the
Mozilla platform. Only the former are used here.
In the Listing 5, the DOM is used to lodge an onload event handler which fires the
initialize() function once the XUL page is fully received. The
function gropes through the DOM of the applet and its parent HTML
document looking for an existing session ID in the form of a cookie,
and disabling menus appropriately. Unlike with a Java applet, no
enforced using automated checking.
The second listing, commands.js, is routine. It provides an event
handler for each menu option. In Listing 5, the example snippet of that
file shows how the panel content of the applet's
deck tags can be flipped with basic DOM-style operations:
selectedIndex for the two
starts with zero (which is a blank pane) and is flipped to one (a set
of checkboxes) if the Ticket|User Ticket menu option is picked. See the
full listing for commands.js to see how these form elements are queried
to extract the user's data and to construct a parameter string suitable
for a HTTP
GET request. Technically, a submitted ticket should use an HTTP
POST request, since it's not a retrieval action, but
GET is used here for simplicity.
The final script, server.js, uses the special
object that is now a standard feature of modern browsers. This allows an
origin through HTTP without disturbing the currently displayed page.
Mozilla supports other protocols as well, such as SOAP and WSDL, and also raw sockets. This functionality means that XML-based interfaces are now as network-enabled as Java-based interfaces. Listing 6 shows a snippet of the network-oriented code:Listing 6. server.js lets the applet connect to server of origin
The first implementation of
init_ticket() allows the
applet to be played with, without any real server support. The second
implementation shows how a request can be silently processed (subject
to security restrictions) with the aid of a server. The
req object constructs the request with
open() and sends the request using
send(), which blocks until a response is received.
send() can also be called in a non-blocking way. When the
response is received, error checking ensures that the server succeeded.
In this case, I rely on the server setting a special HTTP header named
X-Ticket-Sequence-Number, which holds the unique identifier for the
ticket the user is constructing. This approach is also used for
acquiring a session ID and for submitting the final ticket. Feedback is
provided to the user in the form of status bar messages: Green for good
news, red for bad news.