Using Ajax to Develop Web Applications

Tuesday 21st of February 2017 03:48:32 AM

By Jonathan Fenocchi

In the past, web applications were limited because a web page had to be reloaded (or another page loaded in its place) in order for new data to be obtained. Other methods were available (without loading another page), but the techniques weren’t well supported and had a tendency to be buggy. In recent months, a technique that had not been widely supported in the past has become available to a large number of web surfers, giving developers more freedom to develop cutting-edge web applications. These applications, which asynchronously retrieve XML data via JavaScript, are affectionately known as “Ajax applications” (Asynchronous Javascript and XML applications). In this article, I will explain how to retrieve a remote XML file via Ajax to update a web page, and as this series continues, I will discuss more ways that Ajax technology can be used to take your web applications to the next level.

The first step is to create an XML file with some data. We’ll call this file data.xml. It’s a simple XML file and would most certainly be more complex in a real-world application, but for clarity our examples will be simple and concise.

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <data>
    This is some sample data. It is stored in an XML file and retrieved by JavaScript.
  </data>
</root>

Now let’s create a simple web page containing some sample data. This is the page that all our JavaScript will be in, and the page that users will visit to see the Ajax script in action. Let’s call this file ajax.html.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en" dir="ltr">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>Developing Web Applications with Ajax - Example</title>
  </head>
  <body>
    <h1>Developing Web Applications with Ajax</h1>
    <p>This page demonstrates the use of Asynchronous Javascript and XML (Ajax) technology to
    update a web page's content by reading from a remote file dynamically -- no page reloading
    is required. Note that this operation does not work for users without JavaScript enabled.</p>
    <p id="xmlObj">
    This is some sample data. It is the default data for this web page. <a href="data.xml"
    title="View the XML data." onclick="ajaxRead('data.xml'); this.style.display='none'; return false">View XML     data.</a>
    </p>
  </body>
</html>

Note that we link to the data.xml file for users without JavaScript. For users with JavaScript, the function “ajaxRead” is called, the link is hidden, and the link does not redirect to the data.xml file. The function “ajaxRead” isn’t defined yet, so if you test the example code above, you’ll get a JavaScript error. Let’s go ahead and define that function (and another) so you can see how Ajax works. The following SCRIPT goes in your HEAD tags:

<script type="text/javascript"><!--
function ajaxRead(file){
  var xmlObj = null;
  if(window.XMLHttpRequest){
      xmlObj = new XMLHttpRequest();
  } else if(window.ActiveXObject){
      xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
  } else {
      return;
  }
  xmlObj.onreadystatechange = function(){
    if(xmlObj.readyState == 4){
       updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
     }
    }
    xmlObj.open ('GET', file, true);
    xmlObj.send ('');
  }
  function updateObj(obj, data){
   document.getElementById(obj).firstChild.data = data;
  }
  //--></script>

That’s quite a bit, so let’s take this one piece at a time. The first function is “ajaxRead” – what we call from our “View XML data” link on the web page. In the function, we define an “xmlObj” variable – this will be the middleman between the client (user viewing the web page) and the server (the web site itself). We define this object in an if/else chunk:

if(window.XMLHttpRequest){
   xmlObj = new XMLHttpRequest();
} else if(window.ActiveXObject){
   xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
} else {
   return;
}

This is just a test for the availability of different objects – some browsers implement the XMLHttpRequest object differently, so when we define “xmlObj” as our XMLHttpRequest object, we have to define it depending on what browser implementation is available. If no XMLHttpRequest object is available, we end the function with a “return” statement to avoid errors. Most of the time, this check will return an XMLHttpRequest object – this particular code should work in almost every browser out there, with the exception of some older browsers (it works in IE 5.01, but will cease to function in Netscape 4).

Next is this block:

xmlObj.onreadystatechange = function(){
  if(xmlObj.readyState == 4){
      updateObj('xmlObj', xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);
  }
}

How to Develop Web Applications with Ajax, Pt. 1

Each time the state of the XMLHttpRequest changes, the “onreadystatechange” event is triggered. By using “xmlObj.onreadystatechange = function(){ … }” we build and run a function on-the-fly each time the state of the XMLHttpRequest object changes. There are a total of 5 states, starting with 0 and going through 4.

0 – uninitialized (before the XMLHttpRequest begins)

UL {list-style-image: url(ohio.gif); list-style-type: square;}UL UL {list-style-image: none;}

Since the nested list inherits the item typesquare but has been set to use no image for itsbullets, squares are used for the bullets in the nested list, asshown in Figure 7-84.

Figure 7-84

Figure 7-84. Switching off image bullets in sublists

WARNING

Remember that this may not be true in the real world: a user agent

1 – loading (once the XMLHttpRequest has been initialized)

2 – loaded (once the XMLHttpRequest has gotten a response from the server)

3 – interactive (while the XMLHttpRequest object is connected to the server)

4 – complete (after the XMLHttpRequest has done everything it was told to and is finished working)

The fifth state (number 4) is when we are certain that data will be available, so we check the xmlObj.readyState for “4” to see if data is available. If it is, we run the updateObj function. That function takes two parameters: an element ID on the current web page (the element on the current web page to update) and the data to fill in that element. The way this function works will be explained in more detail later.

Our web page’s P tag has an ID of “xmlData,” that’s the paragraph we’re going to update. The data we’re getting is from the XML file, but it’s a bit complicated. Here’s how it works.

The xmlObj.responseXML property is a DOM object – it’s a lot like the “document” object, except it’s for the remote XML file. In other words, xmlObj.responseXML is the “document” object if you ran a script in data.xml. Since we know this, we can retrieve any XML node via the “getElementsByTagName” method. The data is contained in the XML node is accurately named “<data>” so our task is simple: retrieve the first (and only) data node. Thus, xmlObject.responseXML.getElementsByTagName(“data”)[0] returns the first <data> node in the XML file.

Note: it returns the XML node, not the data within that node – the data must be extracted by accessing properties of that XML node, which is the next step.

After that, it’s as simple as retrieving the data by specifying “firstChild.data” (firstChild refers to the text node which is contained within the <data> node, and the “data” property is the actual text of that text node).

xmlObj.open ('GET', file, true);
xmlObj.send ('');

This is the last bit in our ajaxRead function. What does it say? Well, the “open” method of the xmlObj opens a connection to the server (via a specific protocol, specified here as “GET” – you can use “POST” and others as well), requests a file (in our case, the variable “file” that was sent as a parameter to the ajaxRead function – data.xml), and whether JavaScript should handle the request synchronously (false) or asynchronously (true, the default). Since this is asynchronous Javascript and XML, we will be using the default asynchronous method – using since synchronous won’t work in this case.

The last line of our function simply sends an empty string literal back to the server. Without this line, the ready state of xmlObj will never get to 4, so your page will never update. The send method can be used for other things, but today we are only retrieving data from the server – not sending to it – so I won’t go into any more detail about the send method in this article.

function updateObj(obj, data){
  document.getElementById(obj).firstChild.data = data;
}

Now to explain the updateObj function a little more: this function updates any specific element on the current web page with a new value. Its first parameter, “obj,” is simply a specific ID of an element on the current web page – this is the object that will be updated; its second parameter, “data,” is a string that specifies the new value to be placed in the object that is to be updated (“obj”). Normally, it would be advisable to check and be sure that an element on the current page has the ID specified in “obj,” but that check isn’t necessary due to the level of isolation of our script. The way this function updates is similar to the way we retrieved data from the “data” node in the XML file earlier – it locates the element it wants to update (this time by that element’s ID instead of its tag name and index on the page) and sets the data of the first child (the text node) of that element to the new data. If you wanted to update an object with HTML instead of just plain text, you could also use document.getElementById(obj).innerHTML = data.

That’s all there is to it

The concept is simple, and the code isn’t too difficult. You want to read a file from somewhere else without having to reload the web page. There is enough flexibility to allow you to do all sorts of things, including posting data from forms without reloading the web page and using a server-side language to generate the XML file dynamically. If you want to be a step ahead, remember that a reference is always helpful – oh, and remember that Google is your friend. In another article, I’ll explain how you can further use Ajax with server-side technologies to make powerful web applications.

widthIE4 P/Y IE5 P/Y NN4 P/P Op3 Q/-

Used to set the width of an element. This is most often applied to images, but can be used on any block-level or replaced element. Negative values are not permitted.

Example

word-spacingIE4 N/Y IE5 N/Y NN4 N/N Op3 Y/-

Used to set the amount of whitespace between words. A "word" is defined as a string of characters surrounded by whitespace. Length values are used to define a modifier to the usual spacing, not the entire space itself; thus, for color, which in this circumstance is likely to be blue (although we can't show that in print). This is due to the fact that the image is contained with a hyperlink, and the foreground color of hyperlinks is usually blue. If we so desired, we could change that color to be silver, like this:

A:link IMG {border-style: outset; color: silver;}

As Figure 7-32 shows, the border is now based on the light gray silver, since that's now the

And what is the format of an external style sheet? It's simply a list of rules, just like those we saw in the previous section and in the example above, but in this case, the rules are saved into their own file. Just remember that no HTML or any other markup language can be included in the style sheet -- only style rules. Here's the markup of an external style sheet:

H1 {color: red;}
H2 {color: maroon; background: white;}
H3 {color: white; background: black; font: medium Helvetica;}
attempting to render the document.

Figure 9-11

Figure 9-11. Contracting the clipping region

The syntax of rect is an interesting case.Technically, it can becommas -- butthe CSS2 specification contains examples both with and without commasand defines rect as accepting both the comma andnoncomma versions. This text will stick to the comma version mostlybecause it makes things easier to read. element's inline box. The following markup gives one suchexample, (shown in Figure 8-65):

P {font-size: 12px; line-height: 18px;}IMG {height: 30px; margin: 0; padding: 0;}
Figure 8-65

Figure 8-65. Replaced elements don't actually increase the line height

Despite all the blank space, the effective value ofline-height has not changed. It simply has noeffect on the image's inline box, which is in this case30px tall.