There and Back Again

Adding AJAX to a Website step by step, Part II

I have a lot more change's i'd like to make to webthumb so the last article (Adding AJAX to a website step by step) is now the start of the series. In this article will be taking front page of webthumb and making it live. The the stats and recent thumbnails will update in real time, making for a nice slick presentation. Webthumb Frontpage

I hope to release and article for each improvement I make to webthumb, giving everyone idea of whats involved in AJAXing a real website. But a series of articles won't cover everything you want to know about AJAX. If your interested in learning more you should take a look at my book, Understanding AJAX (should be shipping september 1st), it covers everything from basic AJAX implementations to usability and debugging.

Getting realtime data with AJAX

The frontpage of webthumb could be updated with each new thumbnail that is created. In straight HTML you might handle updating things by using a meta refresh. The problem with this, is your loading a lot of repetitive content, and the full page refresh makes for a clunkly look.

With AJAX you can poll the server on a regular interval and just update things when data has changed. Polling approaches can cause scalability problems since they can create a large number of requests to your server. Hopefully this won't be a problem in this case since i'll be making small requests and returning a large amount of data, and I don't need to make them that often. There is also an alternate approach that you can use called comet, that works by each client keeping a connection open to your server and pushing data to them. But a push approach brings about a whole new set of scaling problems, so will stick with tried and true polling, and i'll cover comet some time in the future.

Exporting the PHP Class

Like the last upgrade will be using HTML_AJAX for our AJAX communications. On the server side I created a new class called WebthumbStats, it has a single method named "updatesSince", that takes a timestamp as its parameter. If you were using it in php you'd get something that looks like:

<?php

$stats = new WebthumbStats();
$update = $stats->updatesSince($lastPoll);

?>

If nothing had changed since my last poll i'll get a timestamp back. If something has changed I'll get an array of data back containing the basics stats, a timestamp, and the new image ids. Will use the timestamps from the server when making the next poll request that way we don't have to worry about problems with the client's time settings messing things up. A result might look something like:

<?php

array(
  'queue' => 1,
  'lifetime' => 1324,
  'today' => 329,
  'time' => '2006-08-07 16:45:01',
  thumbs => array(
    array (
      'img' => '/webthumb/data/ba86/wt44dac13bcba86-thumb_medium.jpg',
      'url' => 'http://bluga.net',
    ),
    array (
      'img' => '/webthumb/data/46d6/wt44dac3c4546d6-thumb_medium.jpg',
      'url' => 'http://blog.joshuaeichorn.com',
    )
  )
);

?>

After writing the PHP class I wrote a small test script in PHP and made sure it was working right, then I registered it in ajax.php.

<?php

require_once 'HTML/AJAX/Server.php';

class WebthumbServer extends HTML_AJAX_Server {
        var $initMethods = true;

        function initRequestStatus() {
                require_once 'lib/RequestStatus.class.php';
                $this->ajax->registerClass(new RequestStatus(),'RequestStatus',array('getStatus'));
        }

        function initWebthumbStats() {
                require_once 'lib/WebthumbStats.class.php';
                $this->ajax->registerClass(new WebthumbStats(),'WebthumbStats',array('updatesSince'));
        }
}

$server = new WebthumbServer();

$server->handleRequest();

?>

You'll notice the basic registration is the same style as we used for RequestStatus but now its enclosed in a class. The init method functionality in HTML_AJAX_Server gives you a way to organize how the PHP class are setup for AJAX access. It also means that when a request is made to RequestStatus WebthumbStats code won't be loaded. With just two classes this doesn't save a ton of overhead, but every lit bit helps, and when you get too 20 or 30 AJAX classes it can make a huge difference.

Polling with HTML_AJAX

The JavaScript side is really simple. We poll on a set interval, with a check to make sure we aren't waiting on another poll to finish. Other then that its just a matter of getting a starting timestamp from the server when we generate the page. The polling code looks like:

Updating contents on new data

Lets start with updating the basic stats since thats the easy part. We just give the div containing each of the statistics an ID and then replace there innerHTML with the new content. This code looks looks like:

Updating the thumbnails is a little harder since we want to add new thumbs on the left of the list and drop the old ones off the right. The thumbs array we have returned is shown oldest first, so we can just append to the begining of the list and delete from the end. Using a little getElementsByTagName, insertBefore and remove child lets us make the image updaes a reality.

The line using HTML_AJAX_Util.baseURL is updating the domain below the image, were using baseURL just like you would use basename in PHP. This domain chopping keeps long urls from making the list look bad.

Using HTML_AJAX to manage JavaScript library delivery

HTML_AJAX delivers its JavaScript libraries through HTML_AJAX_Server. This code can also be used to deliver any other JavaScript library you want. Its main features are, setting headers for client side caching, and allowing you to easily combine multiple files together so clients don't have to open as many connections to your server.

To finish this update, I'm going to need moo.fx so my first task is too register it with my server.

<?php

$server->registerJsLibrary('moofx',array('prototype.lite.js','moo.fx.js'),'/home/htdocs/javascript/');

?>

This registration makes the keyword moofx delivery the prototype lite depenency and the moo.fx library. These files are grabbed from /home/htdocs/javascript on my server.

Then i just update my include to pull in moo.fx

Adding some Effects

The auto updating stats are neat, but the change is so subtle people might not notice its happening. To make it clear an AJAX update is happening I'll add a couple effects.

I'm going to animate the height down to zero on a thumbnail before I delete, and fade in the next text on my stats boxes.

To do a fade you create a new Opacity animation

Then you call its custom method giving it the starting and ending opacity.

The same approach is used to shrink the thumbnail out, only this time will set some options.

I use the onComplete event handler to remove the element when im done shrinking it and too add the new one.

Thats all for now

We covered a lot of ground in this article, some old some new. If you have any suggestions, or requests for further explanation please leave a comment.


8 thoughts on “Adding AJAX to a Website step by step, Part II

  1. Pingback: There and Back Again » Blog Archive » Adding AJAX to a website step by step

  2. Pingback: Ajaxian » Adding AJAX to a Website step by step, Part II

  3. Pingback: PHPDeveloper.org

  4. Pingback: Adding AJAX to a Website step by step, Part II > Archives > Web 2.0 Stores

  5. wesley

    Btw, You haven’t said anywhere (or I missed it) what browser is being used to render the screenshot, that information is quite valuable to know though.

  6. Peter

    Hi, I came across your blog posting after searching for and your post on Adding AJAX to a Website step by step, Part II makes an interesting read. Thanks for sharing. I will research more next Tuesday when I have the day off.

  7. Peter

    Hi there, Nice blog posting about Adding AJAX to a Website step by step, Part II. I would have to agree with you on this one. I am going to look more into . This Wednesday I have time.