Previous Page
Next Page

Hack 51. Update an HTML Element's Content from the Server

Use Prototype's Ajax.Updater object to easily update web page content with server information.

Prototype comes with its own object that uses a few lines of code to update a subset of a web page with server data. This hack presents the user with the web page that Figure 6-1 shows, plus a new Go Updater! button. It is similar to "Use Prototype's Ajax Tools with Your Application" [Hack #50], except that it uses a different type of Prototype Ajax object to update an HTML element's content in the web page.

When the user clicks the Go Updater! button, the code uses the Ajax.Updater object to specify that the textarea should be updated with the text from the server response. Figure 6-3 shows what the web page looks like after the user clicks the button.

Figure 6-3. Updated content with little programming


The first order of business for this hack is to make sure that the web page imports the prototype.js library, which you can download from http://prototype.conio.net. Place this file in a common directory for JavaScript, then use a script tag to import the file into the web page:

<script src="/javascripts/prototype.js" type="text/javascript"></script>
<script src="/javascripts/mylib.js" type="text/javascript"></script>

The second imported library, mylib.js, is where the hack uses the objects and extensions from the Prototype package.

Here's the web page code that shows the various user interface controls that this hack depends on, including the Go Updater! button and the textarea that receives server data:

<html>
<head>
    <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>Using Prototype Ajax</title>
</head>
<body>
<h3>Please enter your name</h3>
<form action="javascript:void%200" method="get">
<p>
Your first & last name: <input type="text" name="name_info" id=
"name_info" size="20" maxlength="25" value="anonymous user">
</p>
<p>
Age group: <select name="ag" id="ag">
<!options part snipped...-->
</select>
</p>
<p>
<span id="msg" style="font-size:1.2em; color: green"></span>
</p>
<button type="button" id="but1" name="but1">Go Updater!</button>
<p>
<textarea name="display_area" id="display_area" rows="30" cols="30">
</textarea>
</p>
</form>
</body>
</html>

The purpose of the hack is to automatically fill the textarea with backend data at the user's urging, using just a handful of code lines:

window.onload=function(  ){
    if($("but1")) {
        $("but1").onclick=function(  ){
            if($F("name_info")){
                _url="http://localhost:8080/hacks/proto";
                showUpInfo(_url);
            }
        }
    }
};
function showUpInfo(go_url){
    if($("display_area") && go_url){
        var xmlHttp= new Ajax.Updater("display_area",go_url, {
            parameters:Form.serialize(document.forms[0]),
                  onComplete:function(request){
                if(xmlHttp.responseIsFailure(  )) {
                    var sts =  xmlHttp.transport.status ? xmlHttp.
                    transport.status : "undefined";
                    $("display_area").value=
                    "XMlHttpRequest returned response status "+sts;
                    document.getElementById("msg").innerHTML=
                    "HTTP response and server information; "+
                    "response status="+
                    request.status;
                } else {
                    $("display_area").value=request.responseText;
                    document.getElementById("msg").innerHTML=
                    "Server information fetched with Ajax.Updater:"+
                    "status="+request.status;
                }
            }
        });
    }
}

When the browser loads the web page (window.onload), the button's onclick event handler points to the showUpInfo( ) function. This is the techie way of explaining that when the web page loads, the JavaScript will define the button's behavior. This behavior includes checking whether the button with id but1 actually exists (a web page designer could have mistakenly left it out).

The code uses two Prototype extensions: $("but1") is a shortcut for document.getElementById("but1"), and $F("name_info") returns the value of a form element with the specified id.


On the Server Side

showUpInfo( ) creates a new Ajax.Updater object, passes some information into its constructor, and that's it: the request is on its way. The code didn't have to fuss with XMlHttpRequest because this object was wrapped and tucked away in the prototype.js file. The Ajax.Updater object is different from Ajax.Request, which the previous hack deals with, because its first parameter is the id of the page element that is updated with server data. In this case, the code passes in the id of the textarea.

Now let's look at what's happening at the server end. This application is running on Ruby on Rails. The URL http://localhost:8080/hacks/proto (the second parameter inside of Ajax.Updater) posts the web page's data to an action called proto.

Chapter 7 summarizes Ruby on Rails and describes what an action is.


Here is how the action is defined in Ruby code:

def proto
    if @request.xml_http_request?(  )
        #en is a hash type in Ruby
        #en["SERVER_SOFTWARE"]returns the vlaue of the
        #SERVER_SOFTWARE environment variable
        en=@request.env(  )
        str="Server: "
        str+=en["SERVER_SOFTWARE"].to_s+"\\n"
        str+="Query string: "+en["QUERY_STRING"].to_s+"\\n"
        str+="Raw post data: "+en["RAW_POST_DATA"].to_s+"\\n"
        str+="Prototype version: "+en["HTTP_X_PROTOTYPE_VERSION"].to_s+"\\n"
        str+="X_REQUESTED_WITH header: "+
        en["HTTP_X_REQUESTED_WITH"].to_s +"\\n\\n"
        render :text => str
    end
end

This is a method that gathers environment variable information related to the request, then sends it back to the requester. An action in Ruby on Rails assumes the same role as a servlet or JSP in Java (see "Dynamically View Request Information for XMLHttpRequest" [Hack #62]). The proto action is designed to send this information only if the request originates from XMLHttpRequest, as discussed in "Find Out Whether Ajax Is Calling in the Request" [Hack #59]. It does not make sense to make this action available to a typical browser request because its return value is meant only for fine-grained web page updates.

Prototype requests using Ajax include a request header, X_Requested_With, with the value XMLHttpRequest.


Checking for Errors

The code displays an error message if the HTTP response involves status codes such as 404 (Not Found), 500 (Server Error), or 503 (Service Unavailable):

onComplete:function(request){
    if(xmlHttp.responseIsFailure(  )) {
        var sts =  xmlHttp.transport.status ? xmlHttp.
              transport.status : "undefined";
        $("display_area").value=
              "XMlHttpRequest returned response status "+sts;
        document.getElementById("msg").innerHTML=
              "HTTP response and server information; response status="+
              request.status;
    } else {//...continued
               
            


Previous Page
Next Page