AJAX Chat Tutorial Part 5: The Javascript, Sending Chat Messages, Screen Name Changes

Sending Chat Messages

One aspect of writing AJAX enabled applications is that one can no longer pass off Javascript as an afterthought. If you’re intent on creating dynamic web applications using AJAX, visual effects, and funky new age interfaces then you’ll just have to start recognising that Javascript is going to be a primary development language.

An introduction to Javascript is out of this tutorial’s scope, but I’ll hit the high points as I move along.

Initiating an XHR Request

XMLHttpRequest (hereafter dubbed “XHR”) is a native browser object in most modern browsers with the exception of Internet Explorer 6 where it is an ActiveX object. It allows a scripting language like Javascript to create background connections to the server which do not reload the current web page. Because accessing the XHR is a complicated process, I’ll skip the fine details and introduce Prototype’s Ajax.Request class which buries the detail behind a simple interface.

Using AJAX with Prototype is covered in detail at http://www.sergiopereira.com/articles/prototype.js.html#UsingAjax.

Before we return to our chat application’s HTML, Ajax.Request makes using XHR a simple procedure. You create an instance of the object, set the url, parameter and option values and finally define a function to handle the response (in our case, a JSON encoded array of new messages to be appended to the chat pane in our HTML.

An example usage is:

In this simple example, we are issuing a request using the GET method with a message parameter (i.e. PHP will pick it up as $_GET[‘message’]). When a response from the server is received, the Ajax.Request object will pass an instance of itself as a parameter to the handler function – alertResponse() – which we have named “reply”. The instance has several properties, but the main one we’ll use is responseText which contains the plain text equivalant of the reponse body, i.e. our JSON encoded data (assume we used Zend_Json to encode the response).

Triggering an AJAX Request for New Chat Messages

We’re about ready to return to the client side!

In order to trigger an AJAX request to submit a new chat message, we will add an onclick event to the “Say It!” button in our HTML template. The onclick event will be set up to call a javascript function called sendMessage().

The updated HTML section is:

Adding saveMessage()

The saveMessage() function will be saved in our ./javascript/chat.js file.

Let’s look at this function in more detail.

sendMessage() first sets up two local variables. requestUrl holds the url to which the AJAX request will be sent. In our case, it points to index/message, i.e. the MessageAction method on the IndexController class we completed earlier.

The message variable is set to the value of the chat message we intend sending. Since the user has typed this into an input element with id “textmessage”, we use Prototype’s shortcut $F() method to grab the value. Since we’re just using input elements to hold input, but using Javascript and XHR to submit it, we don’t require a parent form element.

We then initiate the AJAX request using Prototype’s Ajax.Request class. We’ve put this section within a try/catch block so any errors are caught and alerted to the user. The error handling is not very detailed – just enough to tell us if something goes wrong. A full application would implement far superior error handling.

The Ajax.Request class works just as we covered in our XMLHttpRequest introduction. We’re using the GET method for simplicity (to allow us to test the server side PHP from a browser), adding the new message as a parameter, and setting the onComplete handler function to handleRefresh(). Normally the completed application would use POST (it’s slightly more difficult to tamper with).

Adding handleRefresh()

The handleRefresh function is also saved in our chat.js file.

The first line simple clears the input element of the user’s typed message. The second evaluates the JSON encoded reponse into a Javascript Array. With our array available, we then iterate through all its elements. On each iteration, we add a new paragraph element to the divider with id “chatpane” in our HTML. Prototype’s $() function is a simple shortcut to using:


Finally, we ensure that the chat pane scrolls to the bottom of the updated list of messages by setting the scrollTop value to the current scrollHeight.

In the above I directly evaluated the JSON response. As a matter of good practice, it’s generally recommended to use a specialised JSON parser to reduce the risk of the response containing tainted user input which could play havok with a client when eval’d. See: http://www.json.org/js.html.

Does It Work?

If you reload the Chat Application in the browser, you should now be able to send messages as NewUser. Of course we can’t always be NewUser! Our next task is allowing the user to change their Screen Name.

Changing Screen Names

If the Javascript for sending new chat messages was not too daunting then what follows will pose no problems. Our first step is to add an additional onclick event to the “Change!” button. The updated HTML follows.

Adding changeName()

The new onclick event calls a javascript function called changeName(). Again, this will be stored in our chat.js file.

The function is almost identical to sendMessage() with a few differences. We’ve changed the requestUrl variable to index/name, i.e. we will need to add a NameAction method to the IndexController class. Let’s do that now. A little later we’ll look at the new handler function handleChangeName().

Adding NameAction() to IndexController.php

Our quick pitstop back on IndexController.php adds the following method.

As we noted in the earlier MessageAction() method, the user’s screen name is stored in the user session. In this method, we introduce a new Zend Framework class called Zend_Filter_Input. This class offers methods for filtering and validating input data from GET parameters or forms. We’re going to assume that a screen name must only contain alphanumeric characters, ie. upper and lower case a-Z and the 0-9 numerals.

Instantiating a new Zend_Filter_Input object passing $_GET as the parameter has one major impact. The object will overwrite the $_GET superglobal forcing all access to the GET values to be through the new object. This ensures we’re more likely to properly filter/validate values before use.

In addition we’ll escape the output with htmlentities() just in case the Zend Framework fails for unknown reasons. Highly unlikely, but let’s cover our rear ends anyway ;).

The testAlnum() method will return the “name” value to our script unless it is not alphanumeric, in which case it will return the error message. Assuming the value is valid, we simply store it on the user session as “chat_screenname”. This session value is used to populate the “Your current name is:” area in our HTML.

Updating the HTML for new Screen Names

Back to the client side. Our new handleChangeName() javascript function in chat.js is very simple.