Friday, February 27, 2009

AJAX requests class

The script I'm going to demonstrate is an object that creates, sends and handles AJAX requests easily. You will be able to send requests with a simple line of code, and those requests can be used to load virtually unlimited content into your site. You don't need any advanced javascript knowledge to use it, as I've made it as simple as it can be. First we create the object constructor:
//The parameters passed to the function are as fallows:
//url - the url of the script that we wanna request. You can use either full or relative to your server urls.
//elmnts - this is either the id of the element that will contain the response from our request, or can also be a whole array of elements
//loadingMsg - if this parameter is set, after the request has been send, the content of the changed element(s) will be set to whatever this variable is set, i.e. "Loading! Please wait...".
function ajaxObj(url, elmnts, loadingMsg)
{
 this.obj = new Object();
 
 this.url = url;
 
 this.loadInto = elmnts;
 
 if(loadingMsg) //if we have set a loading message here it will be put into the changed elemnt(s)
 {
  if(typeof(this.loadInto) != 'object') //if we wanna change just one element, simply do it using it's id
       document.getElementById(this.loadInto).innerHTML.innerHTML = loadingMsg;
    else //or if the 'elmnts' parameter is an array - change all the elements of the array
      {
       for(i in this.loadInto)
       {
        document.getElementById(this.loadInto[i]).innerHTML = loadingMsg;
       }
      }
 }
 
 //This prototype is used to create our request, send it and handle it
 this.init();
} 
Now, the prototype that creates the XMLHttpRequest that will be used for our script.
//This function tries if different objects are available, untill it finds one that works, cause all the major browsers use different techniques to send the request
ajaxObj.prototype.create = function()
{
 try
   {
    xmlHttp = new XMLHttpRequest();
   }
   catch(e)
   {
    try
    {
     xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e)
    {
     try
       {
        xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
       }
     catch(e)
      {
       return false;
       }
  }
   } 
 
 this.obj = xmlHttp;
}
Now that we have the request object, we need to make sure it will be handled properly before sending it:
ajaxObj.prototype.handle = function()
{
 var o = this.obj;
 var into = this.loadInto;
 
 o.onreadystatechange = function() //Set an event handler that is triggered everytime the readystate of the object has changed
   {
    if(o.readyState == 4) //If the readyState is 4, the request has been completed - we can proceed with using the response
      {
       if(typeof(into) != 'object') //if we want to change just one element - set it's innerHTML equal to the response 
        document.getElementById(into).innerHTML = o.responseText;
       else //otherwise - we have more than one elements to change. We must first split the data that is returned into parts for each one of the elements and then update them
       {
        temp = o.responseText.split("@@");
        
        for(i in into)
        {
         document.getElementById(into[i]).innerHTML = temp[i];
        }
       }
      }
 }
}
The important thing about the above prototype is that if we want to change more than one element, we need to put delimeters in the response. The delimeter I've chosen is "@@", as this symbols are very rarely used in the content of a web page. We have a request, we can handle it properly, the only thing left is to send it:
//This prototype simply sends the request to the desired url
ajaxObj.prototype.send = function()
{
   this.obj.open('GET', this.url, true);
   this.obj.send(null);
}
There's just one more prototype that's left, the one that initializes the object:
//This prototype calls all the other ones in the proper order. It's not really necessary, cause we can just call 
//this prototypes from within the object constructor, but I use it, cause I'm planning to extend this object in the future. 
ajaxObj.prototype.init = function()
{
 this.obj = null;
 
 this.create();
 
 this.handle();
 
 this.send();
}
To create a new request you just need to create a new ajaxObj object. Here is an example:
new ajaxObj('myscript.php', 'myTestElement', 'Loading! Please wait...');
This line of code will send a request to "myscript.php" and will put the response into and element on the page with the id "myTestElement". While the request has been processed "myTestElement" will contain the text "Loading! Please wait...". You can have anything in the .php file that is being requested, i.e. something extracted from a database/read from a file and formatted in HTML. There are two important things to remember when using the object - to use the delimeter "@@" when you send a request for changing more than one element and change only elements that have the innerHTML property (i.e. div, span, td), cause the script will not work with, say < input> elements.
This is pretty much the simplest way of dynamically loading content within a web page, yet it can be very usefull even for big and complicated pages. However, it is far from being good enough to meet everyone's needs. I will extend it in time, while keeping things simple and understandable.
You can see an example page here and the file that contains the object can be found here.

8 comments:

Anonymous said...

Hello!

What a wonderful script! It helped
me so much!

I hope it's okay if I use part
of it in one of my projects?


Adrian

Nikoloff said...

Thanks for the feedback! Feel free to use the script, that's what it's here for :) Of course, a link will be appreciated.

Anonymous said...

Is it okay if I add som text in top off the script? Something like:

"Part of this script i written
by ??? ???. Please visit: www..."

Or anything else as you wish.


Adrian

Nikoloff said...

Yup, it is just fine. You don't need to feel obligated to do it, it's a way of saying "thank you". So, it's up to you how you will do that.

Vít said...

Man... you ROCK! I spent about an hour with a slight dissecting of your script, finding the pieces which do multiple requests. Then, after adding my parts of code (eval-ing javascripts in request, handling breaklines...), I can say that I have finally a perfect ajax function :) Wish your hands on keyboard produce more of such awesome things in the future :)

Nikoloff said...

Thanks, Vit! I'm glad you found the code usefull and hope it'll be of much aid to your future coding. Unfortunatelly, as you might've noticed, I haven't posted anything new in eons... Comments like yours make me think about finaly finding some time to post some new stuff :)

Erwin Doornbos said...

I used your great script to make a AJAX script which supports Javascript execution from the loaded page.

http://erwindoornbos.blogspot.com/2010/09/ajax-script-with-simultaneously.html

Andrew Natoli said...

This is a GREAT script. Thank you so much!