XML - Managing Data Exchange/AJAX



Previous Chapter Next Chapter
XUL Web Services



AJAX is nowadays one of the most common used words in the WEB 2.0 era. While the historic remains of it are not really clear (similar logic to manipulate parts of a webpage was already thought of as DHTML, long before the term AJAX existed and suprisingly even using some type of DOM later on) it is now one of the most important technologies used by modern webdesigners.
But what does AJAX mean? - In short, AJAX stands for Asynchronous JavaScript and XML. It describes a concept of asynchronous data transfer (here: data encapsulated in XML) between the client (usually a webbrowser) and a server to only exchange/ alter a part of the webpage without the need of a full pagereload. That means the browser will issue an XMLHttpRequest in the background and receive only a part of the page - usually tied to one or more html-tags holding uids.

The following are the main components of the Ajax programming pattern.

  • JavaScript - The most popular scripting language on the Web and supported by all major browsers. Ajax applications are built in JavaScript.
  • Document Object Model (DOM) - Defines the structure of a web page as a set of programmable objects. In Ajax programming, the DOM allows us to redraw portions of the page.
  • Cascading Style Sheets (CSS) - Provides a way to define the visual appearance of elements on a web page.
  • XMLHttpRequest - Allows a client-side script to perform an HTTP request, effectively eliminating a full-page refresh or postback in Ajax applications.
  • XML - It is sometimes used as the format for transferring data between the server and client, but other text-based formats work as well.

Ajax offers a number of advantages. Some of the most important are listed below.

  • Lower demand of bandwidth: The fact that it is not necessary to re-load a page completely when additional information is requested allows minimizing the data transfer. The demand of bandwidth is also reduced by producing HTML locally within the browser (note: however as we have additional overhead produced by the embedding of the JavaScript this is only true in case of more than one or two pagerequests from the same site).
  • Browser plug-in not necessary: Ajax runs with every browser which supports JavaScript. There is no additional plug-in needed. This is an advantage over technologies like Shockwave or Flash (note: in some cases however it is possible that some browsers behave different; especially IE prior to version 6 is known for odd behaviour).
  • Separation of data and formats: This allows the web application to be more efficient. Programmers can separate the methods and formats for delivering information over the web. So they can use a language they are familiar with (note: the reason for this is CSS and not AJAX).
  • Websites more user-friendly: Because of the minimized data transfer the response to the actions of the user is much faster. Furthermore interfaces built with Ajax can be more user-friendly (note: however, AJAX without fallback to plain-vanilla HTML request-response cycle is infamous for being a big drawback to barrier free web design).

Classic RequestResponse vs. AJAX Cycle

edit

As you can see in the image, the AJAX cycle embedds an additional JavaScript library into the client side. The JS lib therefor is used to communicate with the server (in case the AJAX is in use) as well as manipulating the HTML page it is embedded on. For a small example well now take a look at a so called AutoComplete (we take a look at basic procesing there and skip the detailed JS-DOM manipulating). The traditional approach on the other hand allways requires a full request-response cycle that sends the whole page from the server to the browser.

A Simple Example: AutoComplete

edit

This example shows a simple AutoComplete textfield from the wicket examples (wicket is a component oriented JavaWebFramework under the hood of the ASF - http://wicket.apache.org/). The example is online live here so you can not only follow the code but rather see it live in action.

 


The idea behind an AutoComplete textfield is to aid users by showing useful possibilites during the filling of the field. Imagine you are at amazon.com looking for a product "foo" and you fill it into the search bar just to find out that it doesnt exist after submitting it - with an AutoComplete aware field you would already have known that after some letters. To have an easy example we now will look at a single field where you can enter the names of countries like "England", "Germany" or "Austria".

The HTML behind it is rather easy (the necessary JavaScript is automatically provided by wicket; similar to what pure JS libs like prototype do; you could of course provide your own implementation, even if this would not really make sense):

... header containing CSS + HTML-head left out...
The textfield below will autocomplete country names. It utilizes AutoCompleteTextField in wicket-extensions.<br/><br/>

        <form wicket:id="form">
            Country: <input type="text" wicket:id="ac" size="50"/>
        </form>
...footer left out...

So we currently only got a simple form holding a plain <input />. The "wicket:id" is only for tying it to the Java code and has no impact on AJAX (in fact in production mode it will be stripped out).

The Java is also not too complicated:

public class AutoCompletePage extends BasePage
{
    /**
     * Constructor of the AutoCompletePage
     */
    public AutoCompletePage()
    {
        Form form = new Form("form");
        add(form);

        final AutoCompleteTextField field = new AutoCompleteTextField("ac", new Model(""))
        {
            protected Iterator getChoices(String input)
            {
                if (Strings.isEmpty(input))
                {
                    return Collections.EMPTY_LIST.iterator();
                }

                List choices = new ArrayList(10);

                Locale[] locales = Locale.getAvailableLocales();

                for (int i = 0; i < locales.length; i++)
                {
                    final Locale locale = locales[i];
                    final String country = locale.getDisplayCountry();

                    if (country.toUpperCase().startsWith(input.toUpperCase()))
                    {
                        choices.add(country);
                        if (choices.size() == 10)
                        {
                            break;
                        }
                    }
                }

                return choices.iterator();
            }
        };
        form.add(field);

        ...more Java here, but not needed for this simple example case...

    }
}

So we see here a plain page that gets a Form attached. That Form on the other side holds an Ajaxified version of a TextField. The protected Iterator getChoices(String input) is called after hitting a key (entering some value into the field by using your keyboard) by an AJAX call (we see this later) - meaning this function is the representation of the business logic for the AJAX. Here we only check if we already have sth. entered (user may delete sth.) and if it is, then if there are countries existing that start with the already entered letters (e.g.: if you enter Aus it will find coutries like Austria and Australia).

The resulting WebPage will be this:

<html>
<head>
<script type="text/javascript"><!--/*--><![CDATA[/*><!--*/

var clientTimeVariable = new Date().getTime();

/*-->]]>*/</script>


	...title + css stripped out...
       <script type="text/javascript" src="resources/org.apache.wicket.markup.html.WicketEventReference/wicket-event.js"></script>
       <script type="text/javascript" src="resources/org.apache.wicket.ajax.WicketAjaxReference/wicket-ajax.js"></script>
       <script type="text/javascript" src="resources/org.apache.wicket.ajax.AbstractDefaultAjaxBehavior/wicket-ajax-debug.js"></script>
  
<script type="text/javascript" src="resources/org.apache.wicket.extensions.ajax.markup.html.autocomplete.AutoCompleteBehavior/wicket-autocomplete.js"></script>
<script type="text/javascript" ><!--/*--><![CDATA[/*><!--*/
Wicket.Event.add(window, "domready", function() { new Wicket.AutoComplete('i1','?wicket:interface=:1:form:ac::IActivePageBehaviorListener:1:&amp;wicket:ignoreIfNotActive=true',false);;});
/*-->]]>*/</script>

</head>
<body>
    
   ...head stripped out...
    

		The textfield below will autocomplete country names. It utilizes AutoCompleteTextField in wicket-extensions.<br/><br/>

		<form action="?wicket:interface=:1:form::IFormSubmitListener::" method="post" id="i2"><div style="display:none"><input type="hidden" name="i2_hf_0" id="i2_hf_0" /></div>
			
			Country: <input value="" autocomplete="off" type="text" size="50" name="ac" onchange="var 
                        wcall=wicketSubmitFormById('i2', '?wicket:interface=:1:form:ac::IActivePageBehaviorListener:3:&amp;wicket:ignoreIfNotActive=true', null,null,null, function() 
                        {return Wicket.$$(this)&amp;&amp;Wicket.$$('i2')}.bind(this));;" id="i1"/>
		</form>

		
<script type="text/javascript"><!--/*--><![CDATA[/*><!--*/

window.defaultStatus='Server parsetime: 0.0070s, Client parsetime: ' + (new Date().getTime() - clientTimeVariable)/1000 +  's';

/*-->]]>*/</script>

</body>
</html>

So we now got our html decorated with a bunch of JS resources (holding the DOM parser, transformer and so on) as well as a JS behaviour to our <input> field using the onchange="..." JS method.

If you now start entering some chars like "au" into the field, the onchange event is triggered and will call the wicketSubmitFormById() method issueing a call to the server and receiving XML:

1  INFO: focus set on i4
2  INFO:
3  INFO: Initiating Ajax GET request on ?wicket:interface=:1:form:ac::IActivePageBehaviorListener:1:&wicket:ignoreIfNotActive=true&q=au&random=0.9530900388300743
4  INFO: Invoking pre-call handler(s)...
5  INFO: Received ajax response (85 characters)
6  INFO:
<ul><li textvalue="Austria">Austria</li><li textvalue="Australia">Australia</li></ul>
7  INFO:

In line 1 the focus on the field (here with uid i4) was set. After we entered "au" into the field in line 3 an AJAX request to the server is issued. Line 4+5 illustrate the pre-call handlers and the receiving of the AJAX response. Line 6 displays the already decoded content of the response, holding a <ul> with the 2 expected countries that are starting with "au" and that are now placed by the JS header libs at the appropriate place on the page.

You now have seen a small, simple example in the big world of AJAX. To really understand it you should watch and use it live (dont forget to hit the "wicket AJAX debug" link on the right lower corner, so you can see the communication). Under http://wicketstuff.org/wicket13/ajax/ you'll find plenty more running examples all with code.