IEMobile Team Weblog

Information about Internet Explorer for Windows Mobile

From XML Data Islands to XMLHTTP

This is Steve Meredith again. Last time, I wrote about XML Data Island support in IE Mobile. The <xml> element is an IE-only extension. Most web authors prefer Ajax these days. This time, I want to change the sample page we developed last time to use XMLHTTP instead of the <xml> element. If you haven’t already, please go read the Data Islands article first.

 

As a reminder, we are creating a web page that lets you select a food from two dropdown lists. The first list contains a category of food: fruit, vegetables, or nuts. The second list contains foods appropriate to the currently selected category. So if “fruit” is selected, the second list contains kinds of fruit. If “vegetables” is selected, the second list contains kinds of vegetables. We don’t want the browser to request a new page from the server each time the category is changed.

 

Below is the HTML that used the <xml> element. Again, I have left out the bodies of the two script functions.

 

<html>

<head>

<title>IE Mobile XML Data Island Example</title>

</head>

 

<body onload='loadCategoryList(); loadFoodList()'>

 

<!-- xml data island: 3 categories for dropdown 1, each with different foods for dropdown 2. -->

<xml id='myFoods'>

  <categories>

    <category name='Fruit'>

      <food>Apples</food>

      <food>Bananas</food>

      <food>Strawberries</food>

    </category>

    <category name='Vegetables'>

      <food>Peas</food>

      <food>Carrots</food>

      <food>Corn</food>

    </category>

    <category name='Nuts'>

      <food>Almonds</food>

      <food>Walnuts</food>

      <food>Pecans</food>

      <food>Pistachios</food>

    </category>

  </categories>

</xml>

 

<script type="text/javascript">

function loadCategoryList() {}

function loadFoodList() {}

</script>

 

<hr />

Select from the available foods:

 

<form id='myForm'>

  <select id='categoryList' onchange='loadFoodList()'></select>

  <select id='foodList'></select>

</form>

 

</body>

</html>

 

Let’s talk about what it will take to change this to an XMLHTTP sample.

 

  1. First, we remove the <xml> element from the HTML.
  2. We need a function to request the XML from server. Let’s call it requestFoodListFromServer().
  3. We need a function that handles the response from that request. Let’s call it processFoodListResponse().
  4. We need to change what function gets called in the body’s onload handler.
  5. We need a global to hold the XMLHTTP request object.
  6. We need another global to hold and XML DOM object with the results from the server.

 

Our new HTML page looks like this. We’ll fill in the bodies of the functions later.

 

<html>

<head>

<title>IE Mobile XMLHTTP Example</title>

</head>

 

<body onload='requestFoodListFromServer()'> <!-- Step 4 -->

 

<script type="text/javascript">

 

var g_request; // XMLHTTP request object     Step 5

var g_foodXML; // XML document object        Step 6

 

 

function loadCategoryList() {}

function loadFoodList() {}

function requestFoodListFromServer() {}  // Step 2

function processFoodListResponse() {}     // Step 3

</script>

 

Select from the available foods:

 

<form id='myForm'>

    <select id='categoryList' onchange='loadFoodList()'></select>

    <select id='foodList'></select>

</form>

 

</body>

</html>

Let’s fill in the body of requestFoodListFromServer() first.

 

// Make an HTTP request for the food list.

function requestFoodListFromServer()

{

 // Cancel any outstanding requests.

 if (g_request)

 {

  g_request.abort();

 }

 

 // Make a new XMLHTTP request object.  

 g_request = new ActiveXObject("Msxml2.XMLHTTP");

   

 if (g_request)

 {

  // Call processResponse() when response is received.

  g_request.onreadystatechange = processFoodListResponse;

       

  // Make an asynchronous request.

  g_request.open("GET", "http://iemobile.members.winisp.net/XMLHTTP/myFoods.xml", true);

 

  // Send it.

  g_request.send();

 }

}

 

We create a new XMLHTTP request object. The way to do this in IE Mobile is with ActiveXObject(). “Msxml2.XMLHTTP” is the name to pass to this function. We set up the onreadystatechange handler, which is a function that gets called at various times as the request object is processed. Passing ‘true’ to open() as the 3rd parameter causes this process to be asynchronous.

 

Let’s move on to processFoodListResponse().

 

// Called when the http request is finished.

function processFoodListResponse()

{

 // Done getting response.

 if (g_request.readystate == 4)

 {

  // Success.

  if (g_request.status == 200)

  {

   // Treat as a plain-text reply.

   g_foodXML = new ActiveXObject("Msxml2.DOMDocument");

   g_foodXML.loadXML(g_request.responseText);

 

   // Load both listboxes.

   loadCategoryList();

   loadFoodList();

  }

  else

  {

   alert("Could not get requested food list from server.");

  }

       

  g_request = null;

 }

}

 

There’s not much new here. We create a new XML DOM object instead of using the one on the XMLHTTP request object. We do this because we don’t control the content-type for this particular XML file. Normally, in a web app, we control the server and this won’t be necessary.

 

We have to make a small change to loadCategoryList(). We remove the reference the XML DOM attached to the myFoods <xml> element and replace it with a reference to our global XML DOM object, g_foodXML. Here’s the modified code:

 

// Initialize the first dropdown (categories) from the XML.

function loadCategoryList()

{

 // Get all the categories.

 categories = g_foodXML.getElementsByTagName('category');

 for (g = 0; g < categories.length; g++)

 {

  // Add the category to the <select> element.

  option = new Option();

  option.text = categories[g].attributes.getNamedItem('name').text;

  option.value = option.text;

  document.all.categoryList.options.add(option);

 }

}

 

Finally, we have to make the same change to loadFoodList(): replace the reference to the <xml> element’s XML DOM and replace it with g_foodXML. Here’s the modified code:

 

// Initialize the second dropdown (foods) from the XML based on

// selected category.

function loadFoodList()

{

 // Find the name of the selected category in the 1st box.

 selectedIndex = document.all.categoryList.options.selectedIndex;

 categoryName = document.all.categoryList.options[selectedIndex].text;

 

 // Search the XML for the selected category.

 categories = g_foodXML.getElementsByTagName('category');

 for (g = 0; g < categories.length; g++)

 {

  // Found the selected category.

  if (categoryName == categories[g].attributes.getNamedItem('name').text)

  {

   // Delete any current option elements.

   document.all.foodList.length = 0;

 

   // Fill the select element with food from this category.

   foods = categories[g].getElementsByTagName('food');

   for (i = 0; i < foods.length; i++)

   {

    option = new Option();

    option.text = foods[i].text;

    option.value = foods[i].text;

    document.all.foodList.options.add(option);

   }

  }

 }   

}

 

That was easy. You can see that the XMLHTTP method requires a little more code than the XML Data Island approach. It also gets the XML data in a separate, asynchronous request so the rest of the UI can be display before the listboxes are initialized. This may be important in a mobile browsing scenario, depending on the size of the data set and speed of the network connection.

 

You can find the complete HTML source for this sample here: http://iemobile.members.winisp.net/XMLHTTP/sample.htm

Published Wednesday, May 03, 2006 6:31 PM by iemoblog

Attachment(s): sample.htm

Comments

 

John Cornell said:

What's the modern day obsession with XML and Java/OOP? European systems especially rely heavily on XML and they're all very sluggish. Try using 1&1's control panel sometime, very XML, very slow. Linear, non-associative data storage was what we had before relational databases, and was abandoned for a reason. Java has proven unreliable for enterprise applications and the OOP model inherently requires huge and unnecessary complications for simple tasks.

Moreover, can we spend a little less time focusing on XML and .NET OOP enhancements, and maybe just a little bit of time on *what* the current browser supports? Does your team realize how maddening it is to develop a heavy jS application on this browser with hit-and-miss jS support that is only determinable by trial-and-error? Let's try to get our priorities straight guys.
May 7, 2006 1:15 AM
 

Jeremy said:

Is there a resource somewhere that has a listing of what Javascript funcationalities IE Mobile currently has?  For example I'm trying to do a document.createElement("div") and I'm getting "Error: Object doesn't support this property or method".  It does recognize document as an object.  Any suggestions?
May 8, 2006 5:05 PM
 

iemoblog said:

We have recently upgraded our documentation on MSDN. See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/mobilesdk5/html/mob5conPocketInternetExplorerReference.asp and look for the DOM Reference Guide.
-Steve
May 23, 2006 7:07 PM
 

Jeremy said:

Thanks for the response.  That was very helpful.  I want to make sure I'm understanding this documentation correctly.  In the DOM Reference Guide, under "Common Properties for all DOM Elements in Internet Explorer Mobile" I see the property "document" is listed as read-only.  Is this why I cannot do a document.createElement("div")?  If so why was this set as read-only and is there a way to get around this?  Thanks again for your help.
May 25, 2006 3:37 PM
 

iemoblog said:

Yes, Jeremy, we do not support document.createElement.  At present, the only way you can create elements is by setting innerHTML on an element.  
June 6, 2006 5:39 PM
 

Marco Amaro Oliveira said:

First of all, thank you for this very helpful blog (at least it was/is for me).

I would like to know if there is any way I can identify when an image has finished loading.
I've tried using both Javascript and HTML onload events, with XMLHTTP request, tried using setTimeout with the complete method of the Image object. And none is working.
Is there any way I get around this issue? I need to know when an image finishes loading.

NOTE: My code is fully working on IE6.
July 17, 2006 3:56 PM
 

iemoblog said:

<img onload=""> should work. Are you having trouble making it work?
July 17, 2006 9:03 PM
 

Marco Amaro Oliveira said:

Thank you for the quick response.

This is one of the pieces of code I've tested, and doesn't work. I though to add it because you said <img onload=""> should work.

//-- Start code --
<html>
<head>
<script>
function loadImage(img_url){
var selectHTML = "<img height=\"200\" width=\"200\" onload=\"img_onload(); return false;\" src=\"" + img_url + "\">";
mainSpan.innerHTML = selectHTML;
}
function img_onload(){
alert("The image has loaded.");
}
</script>
</head>
<body>
<a href="" onclick="loadImage('images/icon.gif'); return false;">load image</a>
<span id="mainSpan"></span>
</body>
</html>
//-- End code --

I must say I've tested this on Pocket IE under Microsoft Pocket PC versions 4.20.0 (Build 14350) and 4.21.1088 (Build 14235.2)

It was supposed to popup an alert after the image finished loading, but nothing happens
July 18, 2006 7:02 AM
 

Marco Amaro Oliveira said:

Ok, I've managed to test the above code on a IE Mobile under Microsoft Pocket PC 5.1.70 (Build 14406.1.1.1) and it worked well, both with the Javascript Image Object and HTML <img> tag, onload events, but it doesn't respond to the 'complete' method of the Javascript Image object.

Although it works on IE Mobile, my question remains:
- How can I make it work on Pocket IE? Is there any way of doing it?

NOTE: I think I used the correct terms, 'Pocket IE' for the browser on Pocket PC 2003 and 'IE Mobile' for the browser on Pocket PC 5. Correct?
July 18, 2006 9:53 AM
 

iemoblog said:

Yup - the onload() handler was added for on Windows Mobile 5.0.

You're correct in your use of Pocket IE vs. IE Mobile - actually, we're pretty happy to see that make inroads, as we can't even get the staff around these parts to make the switch!  :)

IE Mobile does not support the "complete" property which our other browser has.  There's no actual standard behind that one, so it's been less of a focus for us to get to implementing.  WE've heard some requests for this support from some other customers and may consider it in the future, but it's not a particularly high near-term priority for us, unfortunately.  We're sorry that it's causing you some pain, though, in your implementation.

-Cameron
July 18, 2006 9:28 PM
 

Marco Amaro Oliveira said:

You missed my most important question.
Is there any way, in Pocket IE, of knowing when an image finishes loading?

Or, for example, is there a way of getting an image using a XMLHTTP request? I've tried it but without success.
July 19, 2006 5:54 AM
 

Randy Ramig said:

Hi Marco:

Unfortunately there is no way to know when the image finishes loading on Pocket IE.  This is new as of Windows Mobile 5.0 (IE Mobile).

Randy
July 19, 2006 12:18 PM
 

gonzalordv said:

Someone can tell me why this code does not work on Windows Mobile 5.0?

<p id="pForTagName">Parrafo</p>

<script type="text/javascript">

var pForTagName = document.getElementById("pForTagName");

try{

 alert(pForTagName.tagName)

}catch(err){

 alert("Can't read pForTagName tagName. Error: " + err);

}

</script>

The alert windows says: "Can't read pForTagName tagName. Error: [object Error]"

Using Device Emulator: 8.0.50727.42 and Windows Mobile 5.0  OS 5.1.195 Build 14847.2.0.0

I'm trying to make a webapp compatible with windows mobile but i'm finding it very hard.

February 9, 2007 12:36 PM
 

iemoblog said:

Support for document.getElementById was added in one of the early Windows Mobile 5 updates.

The update can be found here:

http://www.microsoft.com/windowsmobile/business/directpushemail.mspx

document.getElementById can be implemented as follows:

if (document.all) return document.all[“elementid”]

where elementid is what you would normally pass to getElementById

I verified that your code worked on WM 6.0.

February 9, 2007 1:51 PM
 

IEMobile Team Weblog From XML Data Islands to XMLHTTP | Portable Greenhouse said:

June 1, 2009 6:13 AM
 

IEMobile Team Weblog From XML Data Islands to XMLHTTP | Portable Greenhouse said:

June 1, 2009 7:28 AM
 

IEMobile Team Weblog From XML Data Islands to XMLHTTP | Cast Iron Cookware said:

June 11, 2009 10:34 PM
 

IEMobile Team Weblog From XML Data Islands to XMLHTTP | internet marketing tools said:

June 16, 2009 12:33 AM
 

IEMobile Team Weblog From XML Data Islands to XMLHTTP | storage bench said:

June 19, 2009 4:08 AM
Anonymous comments are disabled

© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker