Here is a description of the actual code used to make the Sikyon interactive image work. To begin with, a conditional statement is required to check for browser type. The code first checks if the browser is Microsoft (by checking for ActiveX controls) and then goes through a try-catch statement to figure out which object to use to create the instance of XMLHttpRequest
. The Microsoft.XMLHTTP object works for IE 5 and later (including IE 6) while the newer version, Msxml2.XMLHTTP, works for IE 6. If the browser does not support ActiveX objects (and is therefore not Microsoft), the XMLHttpRequest
object is created natively using JavaScript.
The Web page then accessed the data in the XML file through the XMLHttpRequest
object and various JavaScript functions. The doSearch
function initiates the asynchronous communication after being triggered by an onmouseover event within the SVG file. As the mouse pointer moved over a tract, the doSearch function would be called with the tract ID passed as a parameter. The doSearch
function would then call the createXMLHttpRequest
function and initialise a new instance of the XMLHttpRequest
object.
A function is then needed to handle the changes in the XMLHttpRequest
object's state and then perform the desired action when appropriate. This is done using the onreadystatechange
property of the object to point to the handleStateChange
function. This action checks that the server is finished looking up the requested information by confirming the HTTP ready state is 4 and that the HTTP status code is 200. These verify that the server found the data the client was looking for and that the data are ready to be used. Once the server has confirmed it has finished sending the response, the handleStateChange
function calls two other functions that will be addressed below.
Next the properties of the request are assigned by the XMLHttpRequest
object's open() method. Three parameters are taken by this method which are a string indicating the mode used (usually GET or POST), a string for the URL of the destination resource, and a Boolean indicating whether the request should be made asynchronously. Finally the XMLHttpRequest
object's send() method forwards the request to the destination resource. These previous steps provide four general functions: create an instance of the XMLHttpRequest
object, tell the object what to do when it undergoes changes in its state, tell the object where and how to send the request, and then direct the object to transmit the request (Asleson and Schutta 2006, 31-32).
The function which actually requests the data from the XML file is the handleStateChange
function. If the HTTP ready state and HTTP status code are acceptable, the previous data is cleared from the Web page and the new data are acquired with the clearPreviousResults
and parseResults
functions respectively. The parseResults function retrieves data from the XML document using the XMLHttpRequest
object's responseXML
property. A function pointer, xmlDoc
, is used to point at the XML document. Then another function pointer, tractNode
, further isolates the XML document to only the tract which is relevant. The tract ID was originally passed during the onmouseover
event by doSearch
, which is now used within parseResults
by the getElementsByTagName
method. In this way the function only grabs data from the XML document which relate to the tract in question.
<polyline id="np1" onmouseover="doSearch('np1');" onmouseout="clearPreviousResults()" fill="#7DA799" stroke="#000000" stroke-width="0.24" stroke-miterlimit="10" points="407.98,79.484 411.84,77.278
416.069,75.807 424.892,95.844 420.847,97.683 417.356,98.969 407.98,79.484 " />
function setRaster()
{
if (document.getElementById("raster").checked==true)
{
svgDoc.getElementById("raster").setAttribute("visibility", "visible");
}
else
{
svgDoc.getElementById("raster").setAttribute("visibility", "hidden");
}
}
function setPlateau()
{
if (document.getElementById("plateau").checked==true)
{
svgDoc.getElementById("plateau").setAttribute("visibility", "visible");
}
else
{
svgDoc.getElementById("plateau").setAttribute("visibility", "hidden");
}
}
//Variable declarations
var xmlHttp;
var svgDoc;
var tract;
//Function to initialize the SVG document so other functions can access it
function initSVGvars ()
{
svgDoc = document.sikyon.getSVGDocument();
}
//Function to initialize the XMLHttpRequest object and enable asynchronous comunication
function createXMLHttpRequest()
{
//Check if browser is MS
if (window.ActiveXObject)
{
try
{
//First try the new MS version of the object
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (tryoldversion)
{
try
{
//If that doesn't work try the old one
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (failed)
{
alert("Error initializing XMLHttpRequest Object. Ajax functionality is unavailable");
}
}
}
else if (window.XMLHttpRequest)
{
//Otherwise the browser is non-MS so use this object
xmlHttp = new XMLHttpRequest();
}
}
//Function that initiates the Ajax and communication
function doSearch(tract)
{
requestType = tract;
createXMLHttpRequest();
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.open("GET", "tract.xml", true);
xmlHttp.send(null);
}
//Function that checks if the server has finished and is ready
function handleStateChange()
{
if (xmlHttp.readyState == 4)
{
// Take this out for local debugging purposes
if (xmlHttp.status == 200)
{
clearPreviousResults();
parseResults(requestType);
}
}
}
//Function to clear out the previous results from the Web page
function clearPreviousResults()
{
var tableBody = document.getElementById("resultsBody");
while (tableBody.childNodes.length >0)
{
tableBody.removeChild(tableBody.childNodes[0]);
}
}
//Function which goes and gets the data from the XML file
function parseResults(tract)
{
//Function pointer to the XML document
var xmlDoc = xmlHttp.responseXML;
//Isolates XML document according to tract
var tractNode = xmlDoc.getElementsByTagName(tract)[0];
var squares = "";
var lu = "";
var condition = "";
var st = "";
squares = tractNode.getElementsByTagName("squares")[0].firstChild.nodeValue;
lu = tractNode.getElementsByTagName("lu")[0].firstChild.nodeValue;
condition = tractNode.getElementsByTagName("condition")[0].firstChild.nodeValue;
st = tractNode.getElementsByTagName("st")[0].firstChild.nodeValue;
addTableRow(tract, squares, lu, condition, st);
document.getElementById("resultsTable").setAttribute("border", "0");
}
//Function that updates the XHTML document with the acquired data from the XML document
function addTableRow(tract, squares, lu, condition, st, loop)
{
var row = document.createElement("tr");
var field = createCellWithText('Tract:');
row.appendChild(field);
var cell = createCellWithText(tract);
row.appendChild(cell);
document.getElementById("resultsBody").appendChild(row);
var row = document.createElement("tr");
var field = createCellWithText('Squares:');
row.appendChild(field);
var cell = createCellWithText(squares);
row.appendChild(cell);
document.getElementById("resultsBody").appendChild(row);
var row = document.createElement("tr");
var field = createCellWithText('Land Use:');
row.appendChild(field);
cell = createCellWithText(lu);
row.appendChild(cell);
document.getElementById("resultsBody").appendChild(row);
var row = document.createElement("tr");
var field = createCellWithText('Soil Condition:');
row.appendChild(field);
cell = createCellWithText(condition);
row.appendChild(cell);
document.getElementById("resultsBody").appendChild(row);
var row = document.createElement("tr");
var field = createCellWithText('Soil Type:');
row.appendChild(field);
cell = createCellWithText(st);
row.appendChild(cell);
document.getElementById("resultsBody").appendChild(row);
document.getElementById("resultsBody").appendChild(row);
}
//Function to create the table cell
function createCellWithText(text)
{
var cell = document.createElement("td");
var textNode = document.createTextNode(text);
cell.appendChild(textNode);
return cell;
}
© Internet Archaeology/Author(s)
URL: http://intarch.ac.uk/journal/issue23/5/appendix.html
Last updated: Tue Mar 25 2008