How to implement AJAX callbacks on your NON-DOT.NET page

1. Enable AJAX callbacks by including the following JavaScript in your page:
<script type="text/javascript" language="javascript">

function ajaxFunction(AJAXurl,AJAXargument,AJAXreceivingFunction)
{
  var xmlHttp;
  try { xmlHttp=new XMLHttpRequest(); }
  catch (e)
  {
    try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); }
    catch (e)
    {
      try { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); }
      catch (e) { alert("Your browser does not support AJAX!"); return false; }
    }
  }
  xmlHttp.onreadystatechange=function()
  {
    if(xmlHttp.readyState==4)
    {
      eval(AJAXreceivingFunction + "('" + xmlHttp.responseText.replace(/\'/gi,"\\'") + "')");
    }
  }
  xmlHttp.open("GET",AJAXurl + "?arg=" + AJAXargument,false);
  xmlHttp.send(null);
  
  // alternative if you want to use multiple form data
  // 
  //xmlHttp.open("POST", AJAXurl, false);
  //xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
  //xmlHttp.send('arg=' + AJAXargument + "&var2=someothervalue");
}

</script>
This is your complete AJAX function. It takes three arguments :

(1) The URL of the file/script you want to call
(2) any arguments you want to pass, this must be a single string, so serialize up your multiple inputs using JSON or bar|separation
(3) the name of your JavaScript function to be called with the returned data, as a string

The first section of try...catch statements simply sets up the xmlHttp object across multiple browsers (Firefox, IE 6, and IE5.5). If the final catch fails, it will alert you that AJAX is not supported and the function returns false. If you want silent failure, take out the alert, and clean up on a false function return.

In the second part, a function is added to the onreadystatechange listener. Once it has checked that the change is a state 4 (which means data complete) it runs your given function (the name of which you passed in as an argument) with any text returned from the server file/script (escaping the single quotes). Your server script needs to serialize its return data using JSON or bar|separation.

The final part of the function is the call to the file/script. In the simple version the url is opened with your data appended as an 'arg' URL querystring variable. Your server side script can pick this out and process it. Commented out is the POST version, where you can post multiple arguments as if it was an HTML form being submitted. For simple data, it is quicker to use the GET method.
2. Create your function to call the AJAX and one to receive the data returned:
<script type="text/javascript" language="javascript">

function sendData(theData)
{
    ajaxFunction('/script/myscript.pl',theData,'receiveData');
}

function receiveData(AJAXargs)
{
    document.myForm.warning.value=AJAXargs;
}

</script>
sendData is the function to call when you want to callback to the server, with some optional data. It calls the ajaxFunction we set up in the previous step with the three parameters set out above. Note that the url of the resource can be a script or a static file, although a static file won't be able to respond to any passed inputs and will always return the same response, but you could use it to pick up static files generated by something else, such as logfiles.

receiveData is the function you named in the function above to be the receiver of your data back from the server. It can do whatever it likes with that data, but in this example, it sets a form input box to whatever is returned. If you want one data handler to do different things, you can tag the data using bar|separation, e.g. "result|1.344" or "error|time-out warning" and then split on | using var bits = AJAXargs.split("|") to create an array of strings and process the information differently depending on the first element.
3. Create some HTML to trigger the AJAX call. The sendData function you defined above needs to be called when some DOM event happens in the HTML. This could be a mouse onclick, onmouseover, a form element onkeyup or onchange. Whatever your requirement is.

As an example, we'll write a small form with two text boxes, one with an onkeyup event to call the AJAX, and the other to display what we get back:
<form name="myForm">
Name: <input type="text" onkeyup="sendData(this.value);" name="username" />
Message: <input type="text" name="warning" />
</form>
You'll note that the onkeyup event listener will call the remote AJAX script every time you type a key in the 'username' textbox. We also pass what the textbox contains to the remote function with "this.value".
4. Create your server-side script or file to do the processing. In this example we create a perl script to check the data (the current contents of the 'username' textbox) and return a different message depending on what it is:
#!/usr/bin/perl

use CGI;
use CGI::Carp qw(fatalsToBrowser);
$query = new CGI;
$AJAXarg = $query->param('arg');

print "Content-Type: text/html\n\n";

if (     lc($AJAXarg) eq "james")    { print "Great!"; }
elsif (  lc($AJAXarg) eq "adolf")    { print "Boo!"; }
else {                                 print "OK"; }

exit(0);
You don't need to understand the details, but basically the above script looks at the text it has been passed in (from the 'username' textbox, via AJAX) and if it's the word 'james' (case insensitive) it returns "Great!", if the text is 'adolf' it returns 'Boo!"'. Otherwise it returns 'OK'. This text will go back to the calling function on the original page and be displayed in the 'message' box.
5. Try it out for yourself! I've included the scripts on this page and the perl script on the server. Try typing any random text, then 'james' then 'adolf' to see the message coming back instantly from the server using AJAX.

Name: Message:
The AJAX callback is called on every keypress, this is a little bit wasteful, since an HTTP connection is used on every key. If you type really fast, the asynchronous calls to the server can't keep up, and the script may not behave properly. A possible improvement could be a timer which is set off when you press a key, and the AJAX is only called if you don't press any more keys for a set time, say a second. This would cut down on unneccessary server calls.
And that is all there is!