Archive for August, 2006

HTML_AJAX reaches beta

Wednesday, August 30th, 2006

Yesterday we released HTML_AJAX 0.5.0

It contains lots of bug fixes and a couple new features, but the biggest change is this means were commiting to a stable API. Between this release and 1.0 will be in a feature freeze, focusing on improving documentation and fixing any problems.

You can upgrade by running pear upgrade HTML_AJAX-beta

Webthumb adds login and quick submit

Tuesday, August 29th, 2006

I’ve upgraded webthumb, adding in login support and given logged in users the ability to quickly submit multiple webthumb requests. Logged in users also have a recent thumb bar on their user page, and will be getting more historical features over time.

I’m also getting close on the API front, in reality its really already there, since you can submit requests using AJAX. Mainly I need to figure out a general authorization plan, and get a the code exposed in a formal way.

To check out the new webthumb features register and then login and visit the user page.

Also also still trying to figure out what the terms of service will be on the API. I’m currently thinking about 200 thumbnails free and then $.05 per thumbnail after that. I will be rolling things out for testing purposes without any commercial options, but your feedback would be appreciated if your interested in generating a large # of thumbnails.

Update

This came up in the comments, and I responded there, but i think it makes sense to update the post as well.
AWS sells thumbnails are a much cheaper rate. My reasons for the higher rate are:

  • Thumbs of sites how it looks today
  • More thumbnail sizes
  • Thumbnails from any url

What sort of premium do people think thats worth, or are these mainly the type of features people want for low use activities.

Understanding AJAX example code now available

Wednesday, August 23rd, 2006

All the code shown in Understanding AJAX is now available from understandingajax.net. You can run the examples on my server or download them and set them up on your own. If you run into any problems leave a comment on this post.

Understanding AJAX excerpt available at computerworld.com

Tuesday, August 22nd, 2006

The lead story at ComputerWorld.com is an excerpt from my book Understanding AJAX. If you are thinking about buying the book, but needed more information to make a decision nows your chance. Head over to ComputerWorld read the chapter, check out the table of contents, and then pick up the book at Amazon or your favorite book seller.

Updates:
The computerworld excerpt has been dugg, add your diggs if your interested in helping it spread. You can also get the article in PDF format from the publishers website if you’d rather take a look at the chapter in a layout like the final product.

Webthumb Rendering Engine Released

Monday, August 21st, 2006

Webthumb uses a custom browser thats embeds the mozilla rendering engine to take its website screenshots.

We call that custom browser pageprint, and its svn repo is now available. The browser was originally written to generate PDF’s for Clearhealth so most of my recent development has centered around that. If anyone has tips on packaging or making the code work with newer embedding sources instead of mozilla 1.7.x i’d be most appreciative.

I know for certain the code won’t work with seamonkey 1.0.3

Its also pretty raw, but the binary in svn should work with centos and debian without any problems.

Understanding AJAX reviews and Table of Contents

Thursday, August 17th, 2006

I’ve added the Table of Contents to this site, so if your wondering more about the topics covered in the book, thats a good place to start.

I’ve also added a reviews section that links to reviews of the book, the first one is already out from AP Lawrence who got a copy of the pre-release manuscript.

Let me know if you review Understanding AJAX so I can add it too my list.

AJAX Answers

Thursday, August 17th, 2006

The last couple days have been a lot of fun. I was at LinuxWorld and did a book signing yesterday, my publisher had the first copies of Understanding AJAX at their booth. They should be showing up at bookstores and Amazon in the next couple weeks.

Your AJAX answers from my AJAX questions post are below, I hope everyone finds them helpful.

Dealing with broken connections

Question:

How can I find out whether a connection is broken? Should I just set a unique timeout per request after which an error message can be displayed? The timeout would be deactivated if the AJAX call succeeds. Is this a smart idea and does it work?

Answer:

Using a timeout per request does work though its not a perfect solution. HTML_AJAX uses this approach, and a default timeout of 20 seconds. The issue is that 20 seconds is a long time to wait to provide an error, but there are still cases that hit this value. Its also hard to know what to do if you’ve hit an error, is this a transient failure and you should resend your request, or can you know longer talk to the server and you’re app needs to provide and error.

HTML_AJAX vs Prototype

Question:

Why would you want to use HTML_AJAX when there are far better tools for the job, pure javascript solutions such as prototype or jquery? I don’t think you need something special on the serverside to return some data as a response to an AJAX call.

Answer:

I guess you don’t like HTML_AJAX, which is ok, but there are lots of reasons why developers want AJAX libraries that are closely tied to there server side language. Libraries like HTML_AJAX make it easy to perform RPC style AJAX, and they usually make it possible to write less JavaScript on just focus on your primary server side language. Though these libraries do this to varying degrees of success. Something like SAJAX just handles the RPC, while HTML_AJAX can be used with very limited JavaScript writing (HTML_AJAX_Action stuff), and most of the .NET AJAX libraries allow you to add AJAX with no JavaScript at all, since the .NET code behind concept make its really easy to automatically chunk up your code.
Even if there is a JavaScript library you think its great, that doesn’t mean it offers the tools that everyone wants.

Degradable AJAX sites and JavaScript behaviors

Question:

What is the best way to ‘degrade’ a website when Javascript/XMLHttpRequest support is disabled? Take f.e. yahoo.com. It’s a great website enriched with AJAX, but when JS is disabled it’s still looks the same but the rich features are not there. Would you consider CSS-style selectors as the solution? I do not want to create two different websites, one JS enabled and the other JS disabled. Thank you in advance.

Answer:

CSS-style selectors, like those you use with the Behavior library gives you a good tool to write a degradable AJAX site, but the actual implementation can be pretty hard.

In general it means fully implementing a site without AJAX, then picking forms, links, etc that you want to make AJAX and tieing the AJAX too them at runtime. This works really well if your just doing something like type-ahead search since your not changing work flows, but it doesn’t always work that great for form submissions, since they often update different parts of the page, and the code that processes them is generally designed to build the whole page.

If your using AJAX for enhancements that don’t change the actual work flow then making your site degrable is easy. If your site relies on AJAX for its basic workflow you’ll have a much harder time making a site degrade.

Attaching JavaScript using css selectors is a great approach since it keeps your HTML completly seperate

Adding JavaScript on using AJAX

Question:

When utilizing an AJAX API such as Google Maps, how do you execute embedded Javascript commands in a page generated on-the-fly? For example, you have a website which contains several ’s, one of which is an implementation of the API (i.e. a Google map). That loads when the page loads. Now, based on user interaction (clicking on links), you pull an SQL result from a database and display 10 at a time in a separate . Each time the loads, you want to execute some commands through the AJAX API. In my understanding, JS only executes at the browser page load, but I’m sure I’ve seen sites that get around this.

Answer:

While its true that you can’t directly add JavaScript too a page using script tags and innerHTML, that doesn’t mean you can’t add JavaScript to your page at any time. The simplest way is too just send your new JavaScript as text and run it through eval too add it too the page. You can also parse your strings before adding them with innerHTML and run eval as nesseccary. HTML_AJAX provides a method for doing this parsing for HTML_AJAX_Util.setInnerHTML. If you use it JavaScript in any script tags will be run. Other libraries like prototype also offer similar features.

AJAX File Upload

Question:

how can i make a file upload via ajax?

Answer:

If you think of AJAX as involving using XMLHttpRequest then you can’t (at least not without disabling the browsers security model, which i don’t even recommend for intranet apps). But you can still upload files asyncronously, its just a matter of targeting a form at a hidden iframe. You will also want to look at generating your IFrame in JS since i believe it gives you less problems with browser history.


<iframe name="upload" id="upload"></iframe>
<form target="upload">
<input type="file"/>
</form>

AJAX Form Submission

Question:

I’ve been studying AJAX for a bout a month now but I have not yet grasped the tecnique to submit a form with POST method. I’ve been trying to find an article that covered that but all I could find was the ones that included somekind of already made framework.

I want to know how to submit data to server (like form or email sending) with POST method.

Answer:

Submit a POST request using AJAX you first have to understand what a normal form POST is.
When you submit a form in your browser it makes a http request with the following options:
HTTP Verb: POST
Content-Type: application/x-www-form-urlencoded
And a body of something like:
fielda=valuea&fieldb=valueb

So to replicate a form POST in AJAX you need to run xmlhttp.open with POST set a header, xmlhttp.setRequestHeader(’Content-type’,'application/x-www-form-urlencoded’);

Then encode your content and send it.
xmlhttp.send(’fielda=valuea&fieldb=valueb’);

If you use a library most have code for handling this for you, HTML_AJAX has HTML_AJAX.formSubmit for taking a form and submitting it using AJAX and HTML_AJAX.post for doing custom POSTs.

AJAX Question updates

Monday, August 14th, 2006

I’ll be answering your AJAX questions tomorrow, so if you have any thing else, head over to my last post and ask away.

Also I’ll be at Linux World tomorrow so if you’re taking part in the healthcare day make sure to stop by and take a look at Clearhealth.

You got AJAX questions I got Answers

Friday, August 11th, 2006

Have you wondered whats the easiest way to submit a form using AJAX, what the status of HTML_AJAX development is, or what is covered in Understanding AJAX?

Well nows your chance.

Submit your questions general AJAX questions, questions about my soon to be released book Understanding AJAX, questions on HTML_AJAX, or anything else I might know the answer of, and I’ll answer them in another post a couple days from now.

Adding AJAX to a Website step by step, Part II

Thursday, August 10th, 2006
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:


HTML_AJAX.defaultServerUrl = 'ajax.php';
var inProgress = false;
var statsInterval;
var lastPoll = '< ?php echo $now; ?>';

function setupStats() {
        statusInterval = window.setInterval(statsUpdate,8000);
}
function statsUpdate() {
        if (inProgress) {
                return;
        }

        inProgress = true;

        HTML_AJAX.call('WebthumbStats','updatesSince',statsCallback,lastPoll);
}
function statsCallback(result) {
        inProgress = false;
        if (result.time) {
                // do something with updates here
                lastPoll = result.time;
        }
        else {
                lastPoll = result;
        }
}

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:


$('queue').innerHTML = result.queue;
$('lifetime').innerHTML = result.lifetime;
$('today').innerHTML = result.today;

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.


                var images = $('recent').getElementsByTagName('div');

                for(var i = 0; i < result.thumbs.length; i++) {
                        var newImg = images[0].cloneNode(true);
                        newImg.getElementsByTagName('img')[0].src = result.thumbs[i].img;
                        newImg.getElementsByTagName('a')[0].href = 'pickup.php?id='+result.thumbs[i].id;
                        newImg.getElementsByTagName('a')[1].href = result.thumbs[i].url;
                        newImg.getElementsByTagName('a')[1].innerHTML = HTML_AJAX_Util.baseURL(result.thumbs[i].url.substring(7));

                        $('recent').insertBefore(newImg,images[0]);
                        $('recent').removeChild(images[4]);
                }

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


<script type="text/javascript" src="ajax.php?client=html_ajax_lite,alias,moofx"></script>

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


var fadeIn = new fx.Opacity($('StatusBoxes'));

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


fadeIn.custom(.1,1);

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


var shrink = new fx.Height(images[3],{duration:1000,onComplete:function()
                                {
                                        $('recent').removeChild(images[3]);
                                        $('recent').insertBefore(newImg,images[0]);
                                }
                        });
shrink.custom(160,0);

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.


Adding AJAX to a website step by step

Tuesday, August 8th, 2006

Update: The next article in this series is now complete.

Webthumb is a small project of mine that takes a snapshot of a website and gives you thumbnails in 4 different sizes. Currently the site is rather boring and has a couple of usability problems especially on the pickup page. Over the next couple of days I'll be using various AJAX techniques to upgrade Webthumb, writing about the process as things happen.

When looking at a adding AJAX you have a couple decisions you'll want to make up front. One is what tools your going to use. In the webthumb case thats pretty easy. Webthumb is a simple PHP app and doesn't use a framework, so I need a nice general PHP/AJAX framework that is easy to use, HTML_AJAX fits that need. I may also need so animations or other effects, since im not planning on doing anything really fancy i'll use the extremly small but powerful moo.fx. I'll also keep scriptaculous in mind if I end up needing something fancier, but I think its overkill for this project.

After picking my tools I need to decide what my goals are. My main focus will be to improve usability, but I also want to use AJAX to make the site seem a bit flashier, so its a bit of a technology demo too.

Updating Thumbnail Pickup

The first page im targeting is the thumbnail pickup page. Thumbnail generation is an asyncronous process, you make a request which is added to a queue and the thumbnail processor walks the queue generating thumbnails updating the status when its done. The current way this is handle is by letting the user reload the page a bunch of times, but the speed of thumbnail generation isn't consistent so if things run slow its easy to thing something is broken. I'll be fixing this by using AJAX to poll the server on a 1 or 2 second interval, and use that information to make some sort of a progress bar.

HTML_AJAX and PHP remoting

HTML_AJAX supports a number of different ways to add AJAX to your pages, in this case I've chosen to use its PHP remoting supporting. This works registering a PHP class to be used by JavaScript, and then using a proxy object from JavaScript to make calls or making calls with the classname and methodname specified. Since im only going to be making a few calls im not going to be using a proxy object, if you want some examples on how that works checkout my Hello World with HTML_AJAX post.

The RequestStatus PHP class

The class i'll be exporting too JavaScript is call RequestStatus it currently has a single method, getStatus. If you were using it in PHP a call would look something like:

<?php

$status = new RequestStatus();
$jobStatus = $status->getStatus($jobId);

// job is in queue
if ($jobStatus['status'] == 'queue') {
  echo 'Job is in Queue, there are '.$jobStatus['wait'].' jobs in front of it';
}
else if ($jobStatus['status'] == 'processing') {
  echo 'Job is being processed, it started at'.$jobStatus['start'];
}
else if ($jobStatus['status'] == 'complete') {
  echo 'Job is complete';
}

?>

Exporting a PHP Class

The easiest way to make a PHP class available to JavaScript is too use the HTML_AJAX_Server class. If your using a framework you can either integrate this class into your front controller to handle AJAX dispatch or you can use the HTML_AJAX class directly and write your own equivalent of HTML_AJAX_Server to handle call dispatch. I run HTML_AJAX_Server inside of a file called ajax.php, an example of which is shown below. The only item of note is that im specify the methods on that class to export, doing this is always a good idea, and its the only way to keep method case in php4.

<?php

require_once 'lib/RequestStatus.class.php';
require_once 'HTML/AJAX/Server.php';

$server = new HTML_AJAX_Server();

$server->registerClass(new RequestStatus(),'RequestStatus',array('getStatus'));

$server->handleRequest();

?>

At this point a good thing is test that the class has been registered correctly and isn't thowing any PHP errors. To do this load the generated JavaScript stub up in your browser, ajax.php?stub=RequestStatus. For any class the result should look something like below:


// Client stub for the RequestStatus PHP Class
function RequestStatus(callback) {
	mode = 'sync';
	if (callback) { mode = 'async'; }
	this.className = 'RequestStatus';
	this.dispatcher = new HTML_AJAX_Dispatcher(this.className,mode,callback,'/webthumb/ajax.php?','JSON');
}
RequestStatus.prototype  = {
	Sync: function() { this.dispatcher.Sync(); },
	Async: function(callback) { this.dispatcher.Async(callback); },
	getStatus: function() { return this.dispatcher.doCall('getStatus',arguments); }
}

Making AJAX calls to RequestStatus

Now that the backend is setup its just a matter of making some AJAX calls on the thumbnail pickup page.

To do this we'll create a new JavaScript function will be run by the pages onload handler. It will start a timer that makes a call to getStatus every 2 seconds, as long as another request isn't currently being waited on. Will be using HTML_AJAX.call to make the requests.

To get the needed JavaScript libraries I specify a client parameter too ajax.php. Im grabbing all the default libraries and the optional alias library. Alias lets me type $('id) instead of document.getElementById.


<script type="text/javascript" src="ajax.php?client=all,alias"></script>

My status code check code is pretty simple, if the status is complete is reload the page, and let the PHP code display the images. If not I display a new status message, either the items ahead of this thumbnail job in the queue, or the time that processing started on the thumbnail. I also added a simple animated loading gif. The status check JavaScript is below, followed by the HTML it updates.


HTML_AJAX.defaultServerUrl = 'ajax.php';
var inProgress = false;
var jobId = '< ?php echo $jobId; ?>';
var statusInterval;

function setupStatusCheck() {
        statusInterval = window.setInterval(statusCheck,2000);
}
function statusCheck() {
        if (inProgress) {
                return;
        }

        inProgress = true;

        HTML_AJAX.call('RequestStatus','getStatus',statusCheckCallback,jobId);
}
function statusCheckCallback(result) {
        inProgress = false;

        if (result.status == 'complete') {
                window.clearInterval(statusInterval);
                window.location = '< ?php echo $_SERVER['PHP_SELF']; ?>?id='+jobId+'&reload=true';
        }
        else if (result.status == 'processing') {
                $('statusMessage').innerHTML = 'Thumbnail generation started at '+result.start;
        }
        else if (result.status == 'queue') {
                $('statusMessage').innerHTML = 'Your thumbnail is in the processing queue, there are '+result.wait+' items ahead of it';
        }
}

               <div id="statusBlock">
                        <p id="statusMessage">Your thumbnail is in the processing queue, there are < ?php echo $waiting; ?> items ahead of it.

This page will automatically update when the thumbnail is complete.

<img src="loading.gif"/>
                </div>

There are a number of other enhancements we could make to this page. First it could use some CSS cleanups to look nicer. You could also skip the last reload by adding the images using JavaScript. And finally I could make a nicer way to show the 4 thumbnails. These enhancements and some some fun project on the front page will be covered in future articles.

Oh and these changes are live, so you can check them out by visting webthumb and putting in a url.


I’ll be at LinuxWorld

Friday, August 4th, 2006

I’ll be at LinuxWorld on the 15 and the 16. On the 15th i’ll be demoing Clearhealth as part of Healthcare Day, and on the 16th I’ll be talking to people about my book.

Let me know if your going to be there, maybe we can meet up.

Understanding AJAX Digital Shortcut Available

Thursday, August 3rd, 2006

A chapter from my book, Understanding AJAX has been made available as a digital shortcut. This chapter covers the different ways you can use the data you transfer using XMLHttpRequest.

Document centric approaches based on HTML and XML are described as well as various RPC approaches are shown.

Personally i tend to use JSON based RPC approaches or HTML document based approaches. Document based HTML approaches let you add AJAX support without radically changing your development model, since its just a matter of breaking your pages into small chunks and generating HTML just like normal. RPC approaches allow you to develop JavaScript driven apps, which is great for quick prototyping and small apps, since you can write a backend in PHP and have it made immediatly accessible (at least if you use a library like HTML_AJAX to do the work for you) to your HTML and JavaScript frontend.

In Clearhealth we use both approaches. JavaScript widgets like our patient selector make RPC requests. While screens like the claim editor make standard HTTP POSTs treating each form section like it is its own page.

I don’t do much work with AJAX and XML, but client side XSLT can be a good solution if you need to move lots of data since it tends to scale better to extremly large datasets (especially in IE).

If your interested in the details of these various approaches grab the digital shortcut or pickup Understanding AJAX.

I’m Married

Thursday, August 3rd, 2006


Megan and I tied the knot on the 29th, and then spent a couple of days relaxing in sedona.

We have a couple hundred pictures from the wedding and reception online. I ended up writing a simple picture viewer to show them all.

This circle expands additional navigation
You should really buy my AJAX book.
You'll learn not only the technology you need for implementation but also an understanding that will help you get the most from AJAX.
You'll also have my eternal thanks :-)