Tags:
create new tag
, view all tags

Web 2.0 Primer: How Does Ajax Work? With Ajax Example

2011-01-07 - 11:24:27 by PeterThoeny in Development
What is TWiki?
A leading open source enterprise wiki and web application platform used by 50,000 small businesses, many Fortune 500 companies, and millions of people.
MOVED TO... Learn more.
By now you are very familiar with Ajax: Photos on Facebook load in the background without reloading the whole page, and when you type a word into the Google search box, the search results updates while you type. How does this work? Ajax, which is shorthand for Asynchronous JavaScript and XML, does the magic. Let's first review the summary on Wikipedia:Ajax:

Ajax diagram
"Ajax is a group of interrelated web development methods used on the client-side to create interactive web applications. With Ajax, web applications can retrieve data from the server asynchronously in the background without interfering with the display and behavior of the existing page. Data is usually retrieved using the XMLHttpRequest object."

Simply put, we have an HTML page where the user does some action, like pressing a button. This action calls a script on the server, and the output of that script is shown somewhere on the page, without reloading the whole page. In the Facebook image example, when you press the right arrow key, a call to the server is done to fetch and display the next image (this is a simplified view, images are pre-fetched for speed).

As an exercise, let's create an HTML form that has a form field and a button. The task is to load some data from the server when the button is pressed, without reloading the current page. For this exercise, basic understanding of HTML and some JavaScript is assumed.

There are three basic steps:

  1. Create an HTML form with a form field and a button.
  2. Create a server side script that is called when the button is pressed.
  3. Create JavaScript code to do an Ajax call when the button is pressed.

Step 1: Create an HTML form with a form field and a button

We have an HTML form with an input field named demo, and a button:
<form name="form1">
 Demo:
 <input name="demo" type="text" />
 <input value="Go" type="button"
  onclick="JavaScript:alert( 'Value is: ' + this.form.demo.value )" />
</form>
Try it out:

Demo:

For now, when the user presses the [Go] button, the onclick event simply pops up an alert box with the value of the text field. In step 3 we change that to an Ajax action.

Step 2: Create a server side script that is called when the button is pressed

The script can be created in any language. If you do not bother about dynamic content it can even be a static HTML page or a page fragment. For this exercise we (ab)use the TWiki Enterprise Collaboration Platform, but it could as well be a shell script, PHP, Perl or another language. TWiki is suitable for this exercise because pages can be dynamically driven by URL parameters. Let's create a TWiki page that returns three bullets. To add some dynamic behavior, we return the value of a URL parameter in the first bullet.

The page AjaxExampleScript (raw view) has this content:
   * URL parameter demo: %URLPARAM{ "demo" default="(empty)" }%
   * You are: %WIKIUSERNAME%
   * Your IP address: %REMOTE_ADDR%
<!--
   * Set SKIN = text
-->
The same page viewed in an inline frame:

The first bullet returns the value of the URL parameter called demo. If the parameter is empty or missing, we show the string (empty). The second bullet shows the name of the user, and the third bullet shows the IP address of the user's computer. There is one more bullet, hidden in HTML comments. It tells TWiki to treat the page as plain text, e.g. it does not add the usual HTML header and body tags.

Step 3: Create JavaScript code to do an Ajax call when the button is pressed

Although it is possible to hand-code Ajax, it is usually the easiest to use an Ajax framework, which is a JavaScript library. For this exercise we use the popular jQuery library.

Source code:
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
<form name="form3">
 Demo:
 <input name="demo" type="text" />
 <input value="Go" type="button"
  onclick="JavaScript:$( '#result2' ).load(
   '%SCRIPTURLPATH{view}%/%WEB%/AjaxExampleScript?demo=' +
   escape( this.form.demo.value ) );" />
</form>
<div id="result3"></div>

Try it out:

Demo:

First we define a place where the result of the Ajax call should be put. We use a div with ID result3. jQuery has at least three API calls for Ajax. We use the very basic .load() method. It loads data from the server and places the returned HTML into the matched element. In our case, $( '#result3' ) identifies the div with ID result3. The .load() method expects a parameter containing the URL of the server script. We supply the URL of our AjaxExampleScript page in a portable way using the %SCRIPTURLPATH% TWiki variable. We also append a URL parameter named demo with the URL-escaped value of the input field.

That's it! Now you understand the basics of Ajax.

Alternative step 3: Use handcrafted JavaScript for Ajax call

For the adventurous folks, let's look how we can code an Ajax call from scratch, without using an external Ajax framework, and in a browser agnostic way. Some more JavaScript is involved:

Source code:
<script language="Javascript">
function ajaxCall( urlStr, queryStr, divID ) {
  var request = false;
  var self = this;
  if (window.XMLHttpRequest) {
    self.request = new XMLHttpRequest();  // Mozilla and Safari
  } else if (window.ActiveXObject) {
    self.request = new ActiveXObject("Microsoft.XMLHTTP"); // IE
  }
  self.request.open( 'POST', urlStr, true );
  self.request.setRequestHeader( 'Content-Type',
    'application/x-www-form-urlencoded' );
  self.request.onreadystatechange = function() {
    if (self.request.readyState == 4) {
      document.getElementById( divID ).innerHTML =
        self.request.responseText;
    }
  }
  document.getElementById( divID ).innerHTML =
    '<ul><li>%ICON{processing-bar}%</li></ul>';
  self.request.send( queryStr );
}
</script>

<form name="form4">
 Demo:
 <input name="demo" type="text" />
 <input value="Go" type="button"
  onclick="JavaScript:ajaxCall(
    '%SCRIPTURLPATH{view}%/%WEB%/AjaxExampleScript',
    'demo=' + escape( this.form.demo.value ), 'result4' )" />
</form>
<div id="result4"></div>
Try it out:

Demo:

Let us dissect the JavaScript code. On the oncall event, the function ajaxCall() is called with three parameters: The URL of the script, the query string containing the value of the form field, and the ID of the div where we want to put the result of the Ajax call.

The function ajaxCall() first initializes an XML-HTTP request object that does the communication to the server. Unfortunately there is not one standard, so we need to use some conditionals to make it work on Mozilla, IE and Safari. request.open() opens the connection to the server. We set the proper header using request.setRequestHeader(). Then we define the callback function, to be used when the server sends a response. We set a processing bar to let the user know that the request is under way. As a last step, we send the query string, which triggers the call to the server. Once we get the callback, we check for proper state, and we set the div with the response from the server using the innerHTML method.

This is a simple working Ajax example. We could make the code more robust, for example with proper handling in case there is no response from the server.

TWiki uses Ajax in several places, for example to convert from TML (TWiki Markup Language) to HTML when you edit a page with the WYSIWYG editor. TWiki has also a REST API that can be used to communicate with the TWiki server.

Let us know if this was helpful in understanding how Ajax works. And let us know what projects inspire you to try to add some Ajax.

TWiki References:

External References:

The Ajax diagram is courtesy of Jesse James Garrett

Comments

A word of caution if you use this on a TWiki site together with the BlackListPlugin: The plugins bumps you on the blacklist if you save a page that contains a escape() JavaScript function, as is the case in these examples. You are OK of your IP address is on the whitelist.

-- Peter Thoeny - 2011-01-09

I know this might not be the right place to ask, but if I want to replace the TML in this tutorial with PHP, should I simply define all the PHP variable on a page load and use php tags (<? ?>) to put them in the Javascript? (is that all there is to it or would I be forgetting something important?)

I'm fairly familiar with PHP, but am far from earning a 'PHP expert' title. I'm just asking to be safe, for the moment it seems to be working this way with for small scaled example projects.

-- Chris Ankomah - 2012-07-10

Chris: Yes if you are referring to the Ajax example script. This script runs server side, like your PHP. No change is needed on browser side except for the script URL.

-- Peter Thoeny - 2012-07-11

Thank you! This example has been very helpful. Indeed, changing the scriptUrl was enough.

(In case anyone who passes this thread is wondering how to sub the TML with PHP in this example:) After that I could just check the value of demo by checking it with if(isset($_POST['demo'])) and by echoing the result of my script aftwerwards.

-- I've got another question about defining the value of the form though: If I want to post more than 1 value, could I simply use a comma and duplicate the sentence 'this.form.df1.value' inbetween the escape brackets?

For example: [code] onchange="JavaScript:ajaxCall(\'/demo/twikiExample.php\', \'dfilter=\' + escape( this.form.demo.value, this.form.demo2.value ), \'result4\' )" [/code]

Because I have two selection (dropdown) menu's of which I need both values. The problem is that when I try the code I suggested above, I only receive the value of the first selection menu, and when a new selection is made from the menu's, this value isn't refreshed.

Does the refreshing not occur because I'm using a PHP file? Or do I need to add a couple of lines to the AJAX function in order for it to refresh the value('s) onchange?

I'm sorry to bother you with questions like this It's just a problem I can't seem to get my head around and has bee driving me nuts trying to figure it out all day...

-- Chris Ankomah - 2012-07-12

Sorry for bothering you.... The refresh is definitely happening, I just forgot to replace the placeholder code I put in the other selection menu items with the code I mentioned in my previous comment.

Though I still only receive only 1 value (of the first selection menu).

-- Chris Ankomah - 2012-07-12

.

Edit | Attach | Watch | Print version | History: r5 < r4 < r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r5 - 2012-07-11 - PeterThoeny
 

Twitter Delicious Facebook Digg Google Bookmarks E-mail LinkedIn Reddit StumbleUpon    
  • Help
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.