Dojo & Javascript with ceegeye (AJAX)

The FrontEnd

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>

<body>
<div style="text-align: center;"><h2>Personnel Database</h2></div>
<form method="post" action="/cgi-bin/ceegeye/person.cgi" name="person" id='person'>
<input type="hidden" name="first" id="first" value="">
<input type="hidden" name="last" id="last" value="">

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:
{
"personnel": [
{ "id":"3", "first":"Endless", "last":"Charm" },
{ "id":"2", "first":"Hopeless", "last":"Dolt" },
{ "id":"6", "first":"Fete", "last":"Homeless" },
{ "id":"1", "first":"Reginald", "last":"Molehusband" },
{ "id":"5", "first":"Endless", "last":"Mutations" },
{ "id":"4", "first":"Nosebleed", "last":"Section" }
]
}
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).
<script type="text/javascript">
function setpersoninfo() {
var splitname = document.forms['person'].elements['FullName'].value.split(", ");
if(splitname.length == 2) {
document.forms['person'].elements['last'].value = splitname[0];
document.forms['person'].elements['first'].value = splitname[1];
}

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.
{
"id":"4",
"first":"Nosebleed",
"last":"Section",
"street":"100 kipper way",
"city":"vermouth",
"state":"va",
"zip":"123456",
"dob":"2003-09-02",
"doe":"1975-02-04",
"dept":"fishvats",
"social":"890-121-123",
"notes":"evil is everywhere",
}
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.