To make ajax simpler we will use Dojo
the free (multi licensed)
javascript toolkit that encapsulates the use of XMLHttpRequest
object (and so much more). goto dojotoolkit.org and download the
toolkit. Copy the toolkit to your web server's directory
structure. If you put the toolkit at the root of the web server's files
it will work straight up with the html file we are about to produce if
not adjust the path in the script tag in the head of the html. So we
want a basic html page with a form:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"> <title>Personnel Datbase Driver Page</title> <script type="text/javascript" src="/dojo/dojo/dojo.js"> </script> </head>
Name: <select tabindex="1" name="FullName" id="FullName" onchange="setpersoninfo();"></select> <br> <br> Social Security # <input readonly="readonly" tabindex="2" name="social" id="social"> Date Of Birth <input readonly="readonly" tabindex="3" name="dob" id="dob"> <br> <br> Street <input readonly="readonly" tabindex="4" name="street" id="street"> City <input readonly="readonly" tabindex="5" name="city" id="city"> State <input readonly="readonly" tabindex="5" name="state" id="state"> Zip <input readonly="readonly" tabindex="6" name="zip" id="zip"> <br> <br> Dept. <input readonly="readonly" tabindex="7" name="dept" id="dept"> Date of Employment <input readonly="readonly" tabindex="8" name="doe" id="doe"> <br><br> notes:<br> <textarea tabindex="9" readonly="readonly" cols="50" rows="10" name="notes" id='notes'></textarea> </form> </body> </html>
This
is the basic setup, only static html so far. However we have included
the script tag that pulls in the dojo toolkit (the line in green,
adjust this to the where you put your dojo toolkit). the form in red
gives us a basic html form one field for each variable of a row of the
person table in the database. Also note that each input field of the
form has an id and name that match the person table names, this makes
it easy later to reference the fields from code on the page. So now to
do something useful. Let's on page load query the database and get the
first and lastname out of the database to fill in the select element of
the form. Right after the dojo script line add this:
<script type="text/javascript"> function getajaxdata() { dojo.xhrGet( { // The following URL must match that used to test the server. url: "/cgi-bin/ceegeye/all.cgi", handleAs: "json", timeout: 5000, // Time in milliseconds
// The LOAD function will be called on a successful response. load: function(response, ioArgs) { var selector1 = dojo.byId("FullName"); for(i = 0;i < response.personnel.length; ++i) { var opt = document.createElement("option"); var name1 = document.createTextNode(response.personnel[i].last + ", " + response.personnel[i].first); opt.appendChild(name1); selector1.appendChild(opt); } return response; }, // The ERROR function will be called in an error case. error: function(response, ioArgs) { console.error("HTTP status code: ", ioArgs.xhr.status); return response; } } ); } dojo.addOnLoad(getajaxdata); </script>
What we have is a function named getajaxdata (this can have anyname) which is called on page load via dojo's addOnLoad method. This function just calls into the dojo library using xhrGet which encapsulates the XMLHttpRequest call. Let's break this down:
url: tells xhrGet what cgi to call in this case all.cgi we will write this later using the ceegeye library. handleas: tells xhrGet how to parse the data returned. load: is a function callback that is called on a succesful call of url: error: is a function callback called on failure (here it just prints to the console log)
When the load: callback is called it has an object passed to it named response this in this case is json or JavaScript Object Notation. Which means if we know what the object names/structure are/is we can directly reference the values of the variables. all.cgi sends back it's data like this:
we now call a loop that cycles through the values filling out the select object on the form
var name1 = document.createTextNode(response.personnel[i].last + ", " + response.personnel[i].first);
Ignoring
the id value returned in this case. As I said we will have to write the
cgi that returns this data later. Notice that the select form object has an onchange event that calls setpersoninfo. Add
the script below to the html page just after the body tag (i.e. on the page before the setuserinfo call is referenced).
dojo.xhrPost ({ // The page that parses the POST request url: '/cgi-bin/ceegeye/person.cgi',
// Name of the Form we want to submit form: 'person',
// get the data as a json object handleAs: 'json',
// Loads this function if everything went ok load: function (data) { // Put the data into the appropriate <div> dojo.byId('social').value = data.social; dojo.byId('dob').value = data.dob; dojo.byId('doe').value = data.doe; dojo.byId('street').value = data.street; dojo.byId('city').value = data.city; dojo.byId('state').value = data.state; dojo.byId('zip').value = data.zip; dojo.byId('dept').value = data.dept; dojo.byId('notes').value = data.notes; }, // Call this function if an error happened error: function (error) { console.error ('Error: ', error); } }); } </script>
The
first thing that this functon does in split the display of the name on
the select object in the form so we get the first and last names of the
person in question. Now everything should start to look familiar except
we are calling xhrPost this time however as we want the cgi called to be able to access the data on the form. We need a seperate cgi this time person.cgi to get a seperate subset of the data from the database. e.g.
Now
all we need do here is set each of the form fields with the data
returned. Thus on an onchange event of the
select element the form gets posted to the person.cgi & the data
returned is used to update the page without browsing away from the
current page.