Section 2.1. Creating the Application


2.1. Creating the Application

We'll begin with the complete HTML and JavaScript code for our first application, a simple web page that displays the decimal value of any character. Then we'll break apart the JavaScript and examine it.

The HTML is presented in Example 2-1.

Example 2-1. index.html

 <html> <head>     <link rel="stylesheet" type="text/css" href="style.css">     <SCRIPT language="JavaScript" src="/books/4/163/1/html/2/ajax.js"></SCRIPT>     <title>Ajax On Java, Chapter 2 Example</title> </head> <body onload="focusIn( );">     <h1> AJAX CHARACTER DECODER </h1>     <h2> Press a key to find its value. </h2>     <table>         <tr>             <td>                 Enter Key Here ->                 <input type="text"  name="key"                        onkeyup="convertToDecimal( );">             </td>         </tr>     </table>     <br />     <table>         <tr>             <td colspan="5" style="border-bottom:solid black 1px;">                 Key Pressed:                 <input type="text" readonly >             </td>         </tr>         <tr>             <td> Decimal </td>         </tr>         <tr>             <td><input type="text" readonly ></td>         </tr>     </table> </body> </html> 

For the most part, this is standard HTML. There are only two JavaScript references: focusIn( ) and convertToDecimal( ). The focusIn( ) function merely puts the cursor in the right input field when the page loads, so the user doesn't have to move it there with the mouse.

The convertToDecimal( ) function will be our entry into the Ajax world. Example 2-2 lays out the JavaScript code that supports our web page, ajax.js.

Example 2-2. ajax.js

 var req; function convertToDecimal( ) {     var key = document.getElementById("key");     var keypressed = document.getElementById("keypressed");     keypressed.value = key.value;     var url = "/ajaxdecimalcodeconverter/response?key=" + escape(key.value);     if (window.XMLHttpRequest) {         req = new XMLHttpRequest( );     }     else if (window.ActiveXObject) {         req = new ActiveXObject("Microsoft.XMLHTTP");     }     req.open("Get",url,true);     req.onreadystatechange = callback;     req.send(null); } function callback( ) {     if (req.readyState==4) {         if (req.status == 200) {             var decimal = document.getElementById('decimal');             decimal.value = req.responseText;         }     }     clear( ); } function clear( ) {     var key = document.getElementById("key");     key.value=""; } function focusIn( ) {     document.getElementById("key").focus( ); } 

Let's take a look at convertToDecimal( ), which is our entry point from index.html. The main JavaScript object we'll use is XMLHttpRequest. Unfortunately, one problem with JavaScript is that the code isn't the same on all browsers. In Mozilla, Firefox, and Safari, we get an XMLHttpRequest object like this:

 new XMLHttpRequest( ); 

In Internet Explorer, we use an ActiveX object:

 new ActiveXObject("Microsoft.XMLHTTP"); 

Because we can't tell in advance which browsers users will view our web page with, we have to write code that will work on any of the likely candidates. First, we must determine whether the user is using Internet Explorer or some other browser, such as Firefox or Mozilla. This task is handled by the following code:

 if (window.XMLHttpRequest) {     req = new XMLHttpRequest( ); } else if (window.ActiveXObject) {     req = new ActiveXObject("Microsoft.XMLHTTP"); } 

That's basically it: req is now an object that we can use to build our Ajax page.

Now let's look at some code that does some real work. We will be using the code from axax.js in the next chapter, so examine it closely and pay special attention to the mechanism that talks to the server. Since we're Java developers, the backend will be a servlet, but the web page doesn't care.

The convertToDecimal( ) function first gets a String from the form and then sets the url variable to "/ajaxdecimalcodeconverter/response?key=...". Eventually, we'll send this URL to the server (in our case, a servlet) and expect a response (the decimal value of the key), but we're not going to send it in response to a Submit button press; we're going to send it asynchronously (that is, as soon as we have the keystroke that we want to convert).

After the if/else block, where we figure out which browser is being used and get an appropriate req object, we open a connection to the servlet with the call:

 req.open("Get",url,true); 

Let's look at the three parameters in the req.open( ) function:


"Get"

The first parameter tells JavaScript whether to submit the request to the server using HTTPPost( ) or HTTPGet( ). The HTTPPost( ) method hides the parameters in the request; the HTTPGet( ) method puts the parameters in the URL for everyone to see. For this example, I chose HTTPGet( ) because it is easier to see what parameters are being passed, and the number of parameters is relatively small. If I were sending a complex set of parameters, I'd use "Post" instead.[*]

[*] I'm getting quite a ways ahead of the story, but it's a good idea to use Get only when the request doesn't make any changes to the data on the server. That's clearly the case here. Conversely, it's a bad idea to use Get when you are changing data on the server (for example, if you're sending new data, or deleting existing data); in this case, use Post instead.


url

The second parameter is the URL we're passing to the server. We created that URL earlier in the method.


true

The last parameter determines whether or not the call is asynchronous. When this parameter is TRue, the request is sent asynchronously. When designing Ajax applications, you always want to set the asynchronous flag to TRue; basically, it means "don't stop anything, just notify me when the data comes back."

The alternative is to pass false for the third parameter to req.open( ). That will make the browser freeze until the server comes backif it comes back (there's no guarantee). This never leads to a positive user experience, so you should always set the third parameter to TRue.


Now, notice the next statement:

 req.onreadystatechange=callback; 

This line allows us to use the call asynchronously. We're telling the req object to call the callback( ) function whenever a state transition occurs. Therefore, we can process data coming back from the server as soon as it arrives; whenever something happens, we'll be notified.

What Is a Callback?

A callback is executable code that is passed as a parameter to another function. In our example, we pass code to the XMLHTTPRequest object, which tells us what function to call when it is ready.

The JavaScript code generates a request that is sent to a servlet. When the servlet returns with the information, the callback function is invoked; in turn, the callback function can display the new information to the user. We specified which function to call with the following JavaScript code:

 req.onreadystatechange = callback; 

This is really powerful. There's no more waiting on the page; when the data returns, the user will see it without having to wait for a page reload.


The last statement of convertToDecimal( ) sends the request:

 req.send(null); 

Now, let's look at the callback( ) function:

 function callback( ) {     if (req.readyState==4) {         if (req.status == 200) {             if (window.XMLHttpRequest) {                 nonMSPopulate( );             }             else if (window.ActiveXObject) {                 msPopulate( );             }         }     }     clear( ); } 

This function checks the readyState and the status returned by the server. The readyState can have one of five values, listed in Table 2-1.

Table 2-1. readyState values

Value

State

0

Uninitialized

1

Loading

2

Loaded

3

Interactive

4

Complete


The callback( ) function is called on every state change, but that's not exactly what we want. We don't want to do anything until our request has completed, so we wait until req.readyState == 4.

The next check, req.status == 200, ensures that the HTTPRequest returned a status of OK (200). If the page is not found, status will equal 404. In this example, the code should be activated only when the request has been completed. Note that a readyState of 4 doesn't tell us that the request completed correctly; all we know is that it completed. We still have to check the req.status code.

For a complete list of HTTP status codes, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.


2.1.1. How Is Our JavaScript Function Called?

We've written a nice JavaScript function, convertToDecimal( ), that does some interesting things: it sends a request to the server without intervention by the user, and it arranges for the server's response to be added to the web page. But how does convertToDecimal( ) get called? The browser calls it when it detects the keyup event on the "Enter Key Here ->" input field. Here is the complete HTML for the input field:

 <input type="text"  name="key" onkeyup="convertToDecimal( );"> 

onkeyup="convertToDecimal( );" tells the browser to call the JavaScript function convertToDecimal( ) whenever the user presses and releases a key in the input field.

Why are we using the onkeyup trigger as opposed to onkeypress? This is a "gotcha" that you must understand. The onkeypress event seems like it should work for this application, but it doesn't. onkeypress and onkeydown TRigger their actions before the character makes it into the field, sending whatever is in the field prior to the key press. Since we want to read the actual character, we need to use the onkeyup TRigger instead.


2.1.2. How Do We Get the Value of the Key Pressed?

Once control is passed to convertToXML( ), we make this call:

 var key = document.getElementById("key"); 

At this point, the object with the id of key contains the decimal value of the key that was pressed. All that's left for us to do is retrieve the value that the object named key contains. This value is kept in the value parameter of the key element, so key.value contains the value of the key that was pressed.

Once we've retrieved it, we want to place this value in a field for display. That allows us to clear the field used to enter the key. We've named the field for displaying the key keypressed. Here's how to retrieve the keypressed field:

 var keypressed = document.getElementById("keypressed"); 

The next step is to put the value of key into the value of keypressed:

 keypressed.value = key.value; 

2.1.3. Formatting the Page

The final step in developing our application is to create a CSS file to give the page some formatting. This file is presented in Example 2-3.

Example 2-3. style.css

 body {     font-family: Arial, Helvetica, sans-serif;     font-size: small;     text-align:center;     background:#cbdada; } #keypressed{     width:30;     border:none; } #key {     width:20px;     padding:0;     margin:0;     border:none;     text-align:left } h1, h2 {     font-size:120%;     text-align:center; } h2 {     font-size:110% } table, input {     margin-left:auto;     margin-right:auto;     padding:0px 10px;     text-align:center;     color:black;     text-align:center;     background: #a0f6f5;     border:solid black 1px; } td {     margin:10px 10px;     padding: 0px 5px;     border: none; } input {     width: 80;     border: none;     border-top:solid #999999 1px;     font-size: 80%;     color: #555555; } 




Ajax on Java
Ajax on Java
ISBN: 0596101872
EAN: 2147483647
Year: 2007
Pages: 78

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net