With the combination of the VDF Ajax web service, Sture Andersen’s SomeDegreeOfIntrospection package, John Tuohy’s JSON parser and our JSON service, the server side of our example is complete. That however is only half the story, since without a client to invoke it from, it will just sit there and do nothing.
The page is made up of nine tab-pages – one for each of the eight operations exposed by the VDF Ajax interface, plus one for the Login mechanism, which is only required for updating (save and delete) calls to the “Request” operation.
You can see the HTML code which makes up the sample by going to it and right mouse-clicking, then selecting “view source” (or similar, depending on your browser). Each of the tab pages is in its own “<div>” element, with the tab-buttons as “<li>” elements of an unordered list (“<ul>”) at the top.
- json2.js: Douglas Crockford’s JSON serialiser/deserialiser utility.
- UIG.util.js: Some little utility functions we use, but most importantly the “createXMLHTTPObject” method which returns the crucial objects for communicating with the server in a cross-browser fashion.
- UIG.json.js: This just contains a couple of utility functions for dealing with JSON, reducing the code verbosity in the main program.
- VdfAjaxJsonInterface.js: The main program for the sample.
Note that both Crockford’s json2.js and our own two utility scripts are placed in “namespace” objects (respectively “JSON” and “UIG”), so they only pollute the “global’ namespace with those two variables.
The main program is placed inside a function expression, which, since it does not need to expose an interface to any other code, so is not assigned to a global variable, never appears in the global namespace at all.
Within the main program, the code is broken down into sections with comment lines.
The first section contains some general functions: a couple to manage displaying and hiding the tab pages, a generic error-handling routine (for errors returned by the web services, which you will probably see quite a bit if you play with the interface) and another to generically handle the web services responses and deal with any HTTP errors before passing them on to their respective display routines.
Next there are a pair of functions to call the “CreateSession” operation of the JsonService (invoked immediately after the page is loaded) to get a sesson key to use with all the other web service calls.
Following that there are the nine sections dealing with the eight web service operations plus the login mechanism.
Finally there is the initialisation section. In this the function “init” is defined, following which the utility method “addHandler” (just a cross-browser event handler mechanism) is called to cause “init” to be invoked once the window has fully loaded the page.
In the “init” function “createSession” is called, then an event handler is added for the tab-button row (catching “click” events on any of its component tab-buttons) and a handler is added for the “click” event of each of the buttons which will be used to invoke the various operations or clear down the results. There is then some code to allow the page to automatically open a tab at start-up based on a query-string parameter – “tab=xxxx” – being passed to it (case-insensitive working values are “login“, “wo“, “fields“, “props“, “descs“, “request“, “valid“, “rmi” and “tree“), otherwise the default “Login” tab is opened.
Each of the operation invocation sections has three functions: one to initiate the operation – getXxxxx – one to display the results – dispXxxxx – and one to clear the results again – clrXxxxx.
The preparation of the input to the “Request” method (in the function getReq) is also a bit of a monster, making use of an inner function (whichDD) and calls to the jsonField utility method.
There are instructions on each of the tab pages which should make most of them relatively obvious to use (we would recommend working through the tabs from left to right for ease of understanding), but the “Request” operation is so versatile (and hence so complicated) that it may require considerable ingenuity to get results from its many modes of operation (indeed we are far from sure that we have all of the invocation implementation correct, so all of the problems may not be your own). Don’t worry if you do manage to get updates or deletions to work – if the underlying data gets in too much of a mess we can just restore a fresh version of the data files.
So now… proceed to the sample! Enjoy!