Writing applications that use the power of the Web.
Ajax is a design model that has the aim of making web sites that are close to applications in terms of responsiveness and usability. Ajax applications are very suited to mobile devices, as they are lightweight, do not require any code to be installed on the device itself, and can be accessed remotely using the built-in (Internet Explorer Mobile) client that's present on every device.
Presentation
*
Mel Sampat's excellent talk on Ajax from MEDC
Sample
This sample demonstrates how to use the Ajax-model of web page design in a way that is compatible with Internet Explorer Mobile. Although completely compatible with Ajax-style applications, there are a few points that developers targeting Windows Mobile devices need to take into consideration.
This project consists of a web page, Rates.html, and an XML file, Exchangerates.xml. Both files must be in the same directory, and located on the same web server.
Rates.html
This HTML page consists of the Jscript that uses an Ajax-approach to asynchronously load an XML file from the web server, parse it, and use the date to populat a pop-down select control, perform a simple calculation and update a control. It also displays some text in a <div/> section.
Exchangerates.xml
The XML file that contains the sample data, listing four counties and their supposed exchange rate compared to the US dollar. A real-world application would need to consider how this file could be updated, probably by an application running on the server.
Usage
Place both files in the same directory on a web server, and access using Internet Explorer Mobile from a Windows Mobile-based device (5.0 or 6). To use the application, enter a number of dollars in the first input box, and select a currency from the pop-down select box.
Notes
The degree of DOM support provided by Internet Explorer Mobile varies from Windows Mobile 5.0 to Windows Mobile 6. In particular, Windows Mobile 5.0 does not support the
getElementById method, and so instead the name of the element is used as a reference. For example, given a text box element with the ID of “results”, it might be common to use the following statement:
getElementById(“results”).innerText = “The exchange rate is 0.50”
However, to make this compatible with Windows Mobile 5, it would have to become:
results.innerText = “The exchange rate is 0.50”
There are a few other idiosyncrasies – for example, in the Internet Explorer Mobile implementation the collection that stores the select box’s options is Read Only. The new options need to be appended to the control using Add(“menu option”) rather than assigning them to the control’s existing list of options. See the HTML file for the implementation.
Example Files
Both these files need to be in the same location on a web server in order to work. An
JavaScript/JScript program can only access data from the same domain as the page in which it resides - so for example, it's not possible to go to a different site to pull down the exchange rate data. For that to happen, a secondary program running on the web server would get the exchange rate data, and format it into the XML file.
Rates.html
<?xml version="1.0" encoding="utf-8" ?>
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=iso-8859-1" />
<title>Exchange Rate</title>
<script language="javascript">
<!--
// This example web page loads an XML file of currency information, and uses it
// to dynamically define elements in a pull-down menu.
// The XML file must be on the same server as the HTML file, and could be updated
// by a secondary application running on the server.
var req; // The XML request object
var max_currencies = 10; // A maxmimun number of currencies supported.
// Declare two arrays to store country names and exchange rates.
var country = new Array(max_currencies);
var rate = new Array(max_currencies);
// Asynchronously load the XML file containing currencies.
function [getXmlFile()]
{
req = new ActiveXObject("Msxml2.XMLHTTP");
req.onreadystatechange = [processXmlFile;]
req.Open("GET", "ExchangeRates.xml", true);
req.Send();
}
// Once the XML file has loaded, this callback function parses it and places
// values into the country name and rate arrays. The pull-down menu
// options are then cleared and updated.
function [processXmlFile()]
{
// Continue only if req status "complete"
if (req.readyState == 4)
{
// and status is "OK"
if (req.status == 200)
{
// Access the loaded XML file
var ratedoc = req.responseXML;
// Process the XML file to get currency nodes containing name and rate.
// Get the list of countries and rates in the file.
var items = [ratedoc.getElementsByTagName('currency');]
// Make sure there aren't too many.
if (items.length>max_currencies) alert("Error: There are too many entries in the XML file");
// Assign each element in the array to the country name and currency rate
for (i=0; i<items.length; i++)
{
country[i]=items[i].getElementsByTagName('name')[0].firstChild.data;
rate[i]=items[i].getElementsByTagName('rate')[0].firstChild.data;
}
// Update the drop-down selection button
// First clear any existing options
var control = document.forms[0];
control[2].length=0; // The menu control is #2 in the form
// Now add the countries from our array.
for (i=0; i<items.length; i++)
{
control[2].add(new Option(country[i]));
}
}
else {
alert("Error: There was a problem retrieving the XML file \n" + req.statusText + " " + req.status + ":" + req.responseXML.xml);
}
}
}
function getRate(selected_country)
{
// Display the exchange rate of the selected country.
var control = document.forms[0];
// Perform some basic validation: only numeric values should be entered.
if (1!=(control[0].value/control[0].value))
{
alert("Please enter a non-zero, numeric value");
return;
}
// Display the calculated rate in the appropriate text box
control[1].value = Math.round((control[0].value / rate[selected_country])*100)/100;
// Also display the exchange rate.
rateresults.innerText="1 US dollar is worth " + rate[selected_country] + " " + country[selected_country] + ".";
}
//-->
</script>
</head>
<!-- The HTML that defines the web page. -->
<body onload="getXmlFile()">
<form>
<h2>Exchange Rate Calculator</h2>
<p><label for="dollar_amount">US Dollars: <input type="text" size="8" id="dollar_amount" value="1" /> is worth</label></p>
<input type="text" size="8" id="other_amount" value="?" READONLY=true/>
<select id="currency" onchange="getRate(this.form.currency.selectedIndex)"/>
</label></p>
<!-- The button that calculates the rate -->
<input type="button" value="Calculate" onclick="getRate(this.form.currency.selectedIndex)"/>
</form>
<p><div id="rateresults"/></p>
</body>
</html>
Exchangerates.xml
Here is a sample exchange rate file. There is nothing magic about this schema, it was just created to suit this example.
<?xml version="1.0" encoding="utf-8" ?>
<!-- List of Exchange Rates -->
[<ExchangeRates>]
<currency>
<name>British Pounds</name>
<rate>1.95</rate>
</currency>
<currency>
<name>Canadian Dollars</name>
<rate>0.85</rate>
</currency>
<currency>
<name>Japanese Yen</name>
<rate>1.95</rate>
</currency>
<currency>
<name>Euro</name>
<rate>1.31</rate>
</currency>
[</ExchangeRates>]