Previous Page
Next Page

Hack 52. Create Observers for Web Page Fields

Launch code that monitors changes in a web page field.

This hack sets up a textarea to receive a steady supply of timestamps from a server. The web page displays these dates one after another, every 10 seconds. Nothing else changes on the web page as the responses come in, because a Prototype object makes the requests in the background without disrupting the user's view of the page.

Another piece of code monitors that textarea at a slightly longer interval. If the code detects a change in the textarea's value, it displays a message that acts as a kind of log on the screen. To stop the monitoringa good idea before getting up from the computer and embarking on a world tourthe user can press the Pause Monitor button. Figure 6-4 shows what this hack's web page looks like in Firefox 1.5.

Figure 6-4. Observing Ajax responses from code

The hack automates the entire sequence of updating a field's value from a server and using an object to monitor and report on a field, without any page refreshes. However, it does not really matter how the field's value is changing; it could be a scientist periodically entering the readings from her instruments. The nice aspect is that we have a continuous monitor that can report changing information on a live basis without refreshing or resubmitting the whole web page.

How It Works

Here is the web page code, which is a view template within Ruby on Rails (see Chapter 7):

    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="/javascripts/prototype.js" type="text/javascript"></script>
    <script src="/javascripts/mylib.js" type="text/javascript"></script>
    <title>Observe a text field</title>
<h3>Trackable and observable data</h3>
<form action="javascript:void%200">
<span style="vertical-align: top"><strong>Updated Time from server: </strong>
</span> <textarea style="border: thin solid black;" name="time_info" id=
"time_info" rows="15" cols="25">
<span id="msg" style="font-size:1.2em; color: green"></span>
<h4>Data Log</h4>
<p><button id="pause">Pause Monitor</button></p>
<textarea name="display_area" id="display_area" style=
"border: thin solid black;" rows="15" cols="25">

The code imports the prototype.js file, in order to use its Ajax capabilities, and mylib.js, which contains the custom code for our hack. When the browser loads the web page, this action creates a Prototype object that then makes backend requests to a server and displaying the return value in the time_info textarea. Every 10 seconds, another object observes this textarea for any changes to its value. If it detects a change, the observer displays a message in the display_area textarea.

Here is the hack's mylib.js code:

window.onload=function(  ){
        $("pause").onclick=function(  ){
    var _uurl='/hacks/increment';
    var executer;
    var counter=0;
    if($("time_info") && $("display_area")) {
        executer=new PeriodicalExecuter(function(  ) {
        new Ajax.Updater('time_info',_uurl,
        {insertion: function(obj,txt){$("time_info").
          value+= txt + "\\n"},
    onComplete: function(request){$("msg").style.
    color="green"; counter++;
    $("msg").innerHTML="Update #"+
    counter+"; request status="+
    request.status}})}, 10);
    new Form.Element.Observer("time_info",15,function(  ){
    value+=("Change detected on: "+new Date(  ) + "\\n\\n");


First, the code defines the onclick event handler for the Pause Monitor button. The button interacts with the Prototype Form.Element.Observer object to induce it to stop observing.

The Form.Element.Observer object has a currentlyExecuting property, a boolean. If you set this property to true, the Observer stops monitoring.

What's a Prototype Object?

Prototype objects are objects that Prototype defines in prototype.js. This hack uses a PeriodicalExecuter, which, as its name suggests, repeatedly executes the function or code that you pass into its constructor. The hack specifies the interval in seconds as the second parameter.

The new Ajax.Updater part represents the code that the hack periodically executes. Recall that the Ajax.Updater object was introducted in the previous hack. This object removes the necessity for developers to explicitly program XMLHttpRequest when they want to send Ajax-style requests to a backend server. The Ajax.Updater object updates an HTML element with id time_info with data from the relative URL /hacks/increment. It automatically takes the server response and updates the specified field by inserting the new content before any existing content.

When the request processing has reached a stage called "complete" (onComplete), a callback function updates a text message with the sequential number of the request and the response status code.

The $("msg") syntax represents a Prototype shortcut for document.getElementById('msg'). The $("msg").style part dynamically changes the visual style of an element (see "Generate a Styled User Message on the Fly" [Hack #11]).

Passive Observer

The Observer object uses Prototype's Form.Element.Observer. The object parameters represent the id of the form field that the object observes, the interval in seconds, and a callback function that executes if the field's value has changed. Here, the code adds a date string to a textarea:

new Form.Element.Observer("time_info",15,function(  ){
    $("display_area").value+=("Change detected on: "+new Date(  ) + "\\n\\n");

"Use Prototype's Ajax Tools with Your Application" [Hack #50] shows an example of the code that handles any request errors involving the Ajax.Updater object. As with the other objects this chapter discusses, the prototype.js library makes it very easy to add advanced JavaScript code such as Observer objects to your Ajax applications.

Previous Page
Next Page