Search


Change Language


AJAX Chat Tutorial Part 7 : Usability Improvements
Tuesday, 03 April 2007

Usability Improvements

At this point we have the core functionality of our chat application completed. However, we can add a few additional features to polish up our implementation. To start we need to make the chat messages automatically refresh at fixed intervals without requiring user input. We will also add a small message to let the user know when a background request is active. To finish up we remove the necessity of using the "Say It!" button to submit new chat messages.

Refreshing at Intervals

Adding periodical refreshes is quite a simple addition. We already know that the user can refresh the chat messages by clicking the "Say It!" button without entering a message to send. This button implements an onclick event which calls the javascript sendMessage() function.

To create our periodical refresh, we'll use Prototype's PeriodicalUpdater object. You can find the documentation for this object at: http://www.sergiopereira.com/articles/prototype.js.html#Reference.PeriodicalExecuter.

The javascript is relatively simple:

var periodicalExecuter = new PeriodicalExecuter(sendMessage, 30);

I'm afraid that's as complicated as it gets ;). The new instance of the PeriodicalExecuter class will call the sendMessage() function every 30 seconds. Our sendMessage() function will then perform its assigned tasks as described earlier - which includes updating the current list of chat messages via the handleRefresh() handler function.

Improved interval refreshing: Although not documented here, the downloadable source code in chat.js contains additional code to ensure interval refreshes do not also attempt message submissions (i.e. while user is typing).

User Feedback

One other touch is adding some visible feedback whenever the chat application is performing an AJAX request. The simplest feedback is to display a "Loading..." message between the time a new request is started and the time it successfully completes.

A span element is already present in the HTML for the chat application for this purpose. To display the "Loading..." message, we will use two additional classes. The first is the Prototype Ajax.Responders class documented at: http://www.sergiopereira.com/articles/prototype.js.html#Ajax.Responders

The second is the Scriptaculous Effects class documented at: http://wiki.script.aculo.us/scriptaculous/tags/effects.

Ajax.Responders is a class which allows developers call object methods and functions based on the occurance of Ajax events. For example, most of our current javascript functions utilizing the Prototype Ajax.Request class have an onComplete event to bind callback functions to. In a similar fashion, the Ajax.Responders class allows us to bind functions to similar events but this time for all such Ajax events regardless of how or when they are called.

Since our user feedback message should be displayed for all Ajax requests in progress, we can prevent adding it to all our individual Ajax.Request calls and just use a single Ajax.Responders register() call. This avoids a lot of potential javascript code duplication on our parts.

The javascript...

Ajax.Responders.register(
{
onCreate: function()
{
if($('loading') && Ajax.activeRequestCount>0)
{
Effect.Appear('loading',{duration: .2, queue: 'end'});
}
},

onComplete: function()
{
if($('loading') && Ajax.activeRequestCount==0)
{
Effect.Fade('loading',{duration: .2, queue: 'end'});
}
}
}
);

In the javascript above we've defined two function prototypes, one for each event we're interested in: onCreate and onComplete. On creation of a new request, the first function prototype will check that an element with id "loading" exists and that an Ajax request is active. Once this has been confirmed, it uses the Scriptaculous Effects class to make the "Loading..." message appear.

Because Effect.Appear only alters an element's style attribute, we need to make sure the "loading" span element is not initially displayed upon loading the page by setting its style attribute to "display:none;". We cannot put this style in our CSS external file - it must be added to a style attribute for the Effects class to manipulate.

On completion of the request, the second function prototype is called. This causes the message to fade into invisibility once more. If you add the new javascript into the chat.js file in our ./javascript directory you can reload the chat application and see the effect this has. Every time the user submits a new chat message, changes their screen name, or does nothing and waits for the periodical refresh we set up using the Prototype PeriodicalExecuter class, the "Loading..." message will appear and then fade once the current request successfully completes.

Adding a Keypress Event

We have one final usability improvement to add. In time, the user will inevitably get tired of typing a message and then using the mouse to click the "Say It!" button. An acceptable convention in most chat applications and instant messengers is to submit new messages when the user presses the Return key.

We can easily emulate this behavior using a Prototype Event.

window.onload = function()
{
Event.observe(
'textmessage',
'keypress',
function(event)
{
if(event.keyCode == Event.KEY_RETURN)
{
sendMessage();
}
}
)
};

Because we can't add a new Event like onclick, onkeypress to an element until the entire HTML for the page has loaded, we put our Prototype Event.observe() call into a function prototype which is only called when the page has loaded.

The Event observer itself is simple enough. We are observing the element with id "textmessage" (i.e. our chat message input field) for all keypress events. The function handler continually check each keypress until a Return press is detected. Once the user has pressed Return, the Event calls sendMessage() which submits the new chat message, and eventually updates the chat message list.

Conclusion

This concludes the tutorial :).

Hopefully it has proven to be of some benefit to you, the reader. Over the course of building our new chat application we have encountered the Zend Framework and delved into several of its classes. We have met Prototype and how it simplifies using Ajax, as well as helps us with non-AJAX specific tasks like interval function calls and event handlers. We introduced the PHP5 SimpleXML extension when using XML as a storage medium for our lightweight application. Although we only touched it very briefly we also used Scriptaculous' Effect class.

In meeting these many libraries, we've bound them all into a relatively simple application demonstrating how each can be used in combination with our own self sourced code. The final code, which you can download from chat.tar.gz or chat.zip, should be easy to follow - most of its size comes from the comments :).

A final note. There are any number of improvements that could be made to the current source code. The XML storage solution could be replaced with a database if necessary. Screen names could be replaced with proper user accounts. Private messaging could be implemented and icons could be added to spruce up the UI. These were all out of the scope of the tutorial but are easily added with a little work.

 
< Prev   Next >
Loans Flights Car Insurance Loans Credit Card
There are 220 free ajax scripts and 31 categories in our directory





Lost Password?
No account yet? Register
We have 2 guests online