
This hands-on lab takes you through the basics of using Dojo Toolkit
for
developing responsive and interactive
AJAX-based web applications. This document is designed to get you going
as quickly as possible. For more detail information on Dojo
Toolkit, see the Resources
section of Dojo Toolkit.
The technologies you will get exposed in this hands-on lab include
(1) how to use
dojo.io.bind() call to do the remoting (2) how to use
dojo.event.connect() call for handling various types of events
including function calls (3) how
to use the widgets that come with the Dojo toolkit (4) how to use JSON
data format (5) how to retrieve data from the server.
Creation of Dojo toolkit widgets will be dealt with in another
hands-on lab.
Expected duration: 120 minutes
This hands-on lab assumes you have some basic knowledge of, or programming experience with, the following technologies.
Before you begin, you need to install the following software on your
computer. The Dojo Toolkit 0.4.3 is already included in the
hands-on lab zip file so there is no need for you to download it
yourself.
In this exercise, you are going to modify
"ajax-validation"
sample program to use dojo.io.bind()
call. You will also use DOM manipulation utilities of Dojo
toolkit as well. This sample application that you are going to modify
is provided as ready-to-open
NetBeans project called ajax-validation
as part of the hands-on lab zip file (4260_ajaxdojointro.zip).
0. Start NetBeans IDE.
1. Open ajax-validation
NetBeans project.
2. Build and run ajax-validation project.

Figure-1.12: Run the project
3.
Observe that the Firefox browser gets displayed.
4. Type some characters like sa in
the User Id: field.
5. Observe that Valid
User Id
string gets displayed on the right side of the text field. (Figure-1.13
below) This is an example of AJAX usage case in which input data
is being validated by the server through AJAX.

Figure-1.13: Running "Data Validation using AJAX" sample application
You can modify the ajax-validation project
directly. But just to preserve the original project in its
current form, we will create a new project by copying the ajax-validation project into a new
project. You
will name the new project as ajax-validation-dojo.io.bind.
1. Right click ajax-validation project node and
select Copy Project. The
Copy Project dialog box appears.
2. In the Project Name: field,
type in ajax-validation-dojo.io.bind.
Click Copy button.
(Figure-1.14 below) The ajax-validation-dojo.io.bind
project appears under Projects tab window.

Figure-1.14: Copy Project dialog box
3. Change Context path of the new project. (You have to do this only for NetBeans 5.0. It will be done automatically for NetBeans 5.5.1)

Figure-1.15: Change the context path to reflect the new project's
context path
1. Select Window from the
top-level menu bar and select Favorites
(Ctrl+3). (Figure-1.16 below) This will add Favorites tab window.

Figure-1.16: Open Favorites window
2. Select Favorites tab window. (Figure-1.17
below)
3. Right click in any point inside the Favorites tab window.
Select Add to Favorites.
(Figure-1.17 below)

4. In the Add to Favorite window, select the ajaxdojointro
directory which is created when you
unzipped the hands-on lab zip
file, 4260_ajaxdojointro.zip
file. Click Add. (Figure-1.18
below)

Figure-1.18: Add ajaxdojointro directory to the Favorites window
5. Select and right click dojo-0.4.3-ajax
node under ajaxdojointro->dojo-json->web
and select Copy. (Figure-1.19
below - the figure below shows dojo-0.4.3-ajax, which will be corrected
later) You
are copying Dojo Toolkit JavaScript files from the local file system.

Figure-1.19: Copy Dojo toolkit JavaScript files

In this step, you are going to modify
index.jsp file to use dojo.io.bind() instead of directly creating
XMlHttpRequest JavaScript object and using it to perform asynchronous
communication with the server.
1. Double-click index.jsp
of the ajax-validation-dojo.io.bind
project
to open it in the source
editor window. (Figure-1.40 below)

Figure-1.40: Open index.jsp in the source editor
2. Modify the index.jsp file
as
following. The new code fragments that need to be added are
highlighted in bold
and blue colored font while the old code fragments that need to
be removed are highlighted in bold and red colored
font. The code fragments that remain the same are in
regular font. Please pay attention to the comments that explain
why some code fragments are removed and why some are added. (This
is the complete code of the index.jsp file. So you can copy and
paste the complete code.)
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-0.4.3-ajax/dojo.js"> </script> <script type="text/javascript"> //var req; // No longer needed since we don't need to deal with XMLHttpRequest var target; //var isIE; // No longer needed since wd don't need to deal with browser difference /********************* Commented out ******************* * We don't need to do the low-level XMLHttpRequest handling anymore * since it is handled by dojo.io.bind(). function initRequest(url) { if (window.XMLHttpRequest) { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { isIE = true; req = new ActiveXObject("Microsoft.XMLHTTP"); } } function validateUserId() { if (!target) target = document.getElementById("userid"); var url = "validate?id=" + escape(target.value); initRequest(url); req.onreadystatechange = processRequest; req.open("GET", url, true); req.send(null); } ******************************************************/ // This is the modified validateUserId() function function validateUserId() { if (!target) target = document.getElementById("userid"); var sampleFormNode = document.getElementById("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - destination you want to send your request url: "validate?id=" + escape(target.value), // Callback function that will be invoked asynchronously load: function(type, data, evt){ processRequest(data);}, // Error handler function that will be invoked in case of an error error: function(type, error){ alert("error"); }, // Backward and forward button handling backButton: function() { alert("back button pressed"); }, forwardButton: function() { alert("forward button pressed");}, // Type of data you want to receive mimetype: "text/xml" }); } /********************* commented out ************************************** * We don't need to check the status and readyState anymore since it is handled by dojo.io.bind() function processRequest() { if (req.readyState == 4) { if (req.status == 200) { var message = req.responseXML.getElementsByTagName("valid")[0].childNodes[0].nodeValue; setMessageUsingDOM(message); var submitBtn = document.getElementById("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } } } ***********************************************************************/ // This is the modified processRequest() function. Note that you don't need to // check if the readyState of the XMLHttpRequest is 4 or not. function processRequest(data) { var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; setMessageUsingDOM(message); var submitBtn = document.getElementById("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } function setMessageUsingInline(message) { mdiv = document.getElementById("userIdMessage"); if (message == "false") { mdiv.innerHTML = "<div style=\"color:red\">Invalid User Id</div>"; } else { mdiv.innerHTML = "<div style=\"color:green\">Valid User Id</div>"; } } function setMessageUsingDOM(message) { var userMessageElement = document.getElementById("userIdMessage"); var messageText; if (message == "false") { userMessageElement.style.color = "red"; messageText = "Invalid User Id"; } else { userMessageElement.style.color = "green"; messageText = "Valid User Id"; } /*********** commented out ****************** var messageBody = document.createTextNode(messageText); // if the messageBody element has been created simple replace it otherwise // append the new element if (userMessageElement.childNodes[0]) { userMessageElement.replaceChild(messageBody, userMessageElement.childNodes[0]); } else { userMessageElement.appendChild(messageBody); } *******************************************/ // Use innerHTML instead of raw DOM API userMessageElement.innerHTML = messageText; } function disableSubmitBtn() { var submitBtn = document.getElementById("submit_btn"); submitBtn.disabled = true; } </script> <title>Form Data Validation using AJAX</title> </head> <body onload="disableSubmitBtn()"> <h1>Form Data Validation using AJAX</h1> <hr/> <p> This example shows how you can use AJAX to do server-side form data validation without a page reload. </p> <p> In the form below enter a user id. By default the user ids "greg" and "duke" are taken. If you attempt to enter a user id that has been taken an error message will be displayed next to the form field and the "Create Account" button will be disabled. After entering a valid user id and selecting the "Create Account" button that user id will be added to the list of user ids that are taken. </p> <form name="updateAccount" action="validate" method="post"> <input type="hidden" name="action" value="create"/> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td><b>User Id:</b></td> <td> <!-- Input form field whose id is set as "userid" and "validateUserId()" function is associated with the onkeyup event --> <input type="text" size="20" id="userid" name="id" onkeyup="validateUserId()"> </td> <!-- The "userIdMessage" div element specifies the location where input validation message gets displayed. --> <td> <div id="userIdMessage"></div> </td> </tr> <tr> <td align="right" colspan="2"> <input id="submit_btn" type="Submit" value="Create Account"> </td> <td></td> </tr> </table> </form> </body> </html> |
3. Right-click ajax-validation-dojo.bo.bind project
and select Run Project.
The new project should behave in the same way ajax-validation project
behaved as you've seen above.
Trouble-shooting:
If you are experiencing a problem, for example, typing a string in the
User Id: field does not
generate Valid
User Id
message (Figure-1.42 below), open JavaScript Console and see the
debugging messages displayed (Figure-1.43 below).

Figure-1.42: Open JavaScript Console for debugging

Figure-1.43: JavaScript Console displays errors discovered in the
JavaScript. The above indicates that you have not copied dojo.js
file into your project yet or copied it into a directory that is not
specified correctly in the index.jsp page.
<!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-0.4.3-ajax/dojo.js"> </script> <script type="text/javascript"> var target; // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get url: "validate?id=" + escape(target.value), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling backButton: function() { alert("back button pressed"); }, forwardButton: function() { alert("forward button pressed");}, // Type of data that is returned mimetype: "text/xml" }); } // This is the modified processRequest() function function processRequest(data) { // var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; var message = dojo.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } function setMessageUsingInline(message) { //mdiv = document.getElementById("userIdMessage"); mdiv = dojo.byId("userIdMessage"); if (message == "false") { mdiv.innerHTML = "<div style=\"color:red\">Invalid User Id</div>"; } else { mdiv.innerHTML = "<div style=\"color:green\">Valid User Id</div>"; } } function setMessageUsingDOM(message) { //var userMessageElement = document.getElementById("userIdMessage"); var userMessageElement = dojo.byId("userIdMessage"); var messageText; if (message == "false") { userMessageElement.style.color = "red"; messageText = "Invalid User Id"; } else { userMessageElement.style.color = "green"; messageText = "Valid User Id"; } userMessageElement.innerHTML = messageText; } function disableSubmitBtn() { //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; } </script> |
| // This is the modified validateUserId()
function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), url: "validateInvalidURL?id=" + escape(target.value), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling backButton: function() { alert("back button pressed"); }, forwardButton: function() { alert("forward button pressed");}, // Type of data that is returned mimetype: "text/xml" }); } |

Please
note that you were using "text/xml" as a value of "mimetype".
What it
does is when the data is received from the server, it is parsed as an
XML document. That is the reason you could extract the data as an
DOM
object inside the proceRequest(data) function as shown below. Since it
is a DOM object you could use getElementByTagName(..) or
dojo.dom.textContent..) DOM methods.
| // This
is the modified processRequest() function function processRequest(data) { // var message = data.getElementsByTagName("valid")[0].childNodes[0].nodeValue; var message = dojo.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); //var submitBtn = document.getElementById("submit_btn"); var submitBtn = dojo.byId("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } |
| // This is the modified validateUserId()
function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get url: "validate?id=" + escape(target.value), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling backButton: function() { alert("back button pressed"); }, forwardButton: function() { alert("forward button pressed");}, // Format of the data to which the received data will be interpreted //mimetype: "text/xml" mimetype: "text/plain" }); } |

| // This is the modified validateUserId()
function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), // Since the form data is passed to the server via formNode // parameter below, no need to pass target.value here. url: "validate", // The server code in this ajax-validation // sample application expects "GET". It // uses "POST" for account creation. Probably // not a good practice but that is the way // the server side code is written for now. method: "GET", // Send form data. "myform" is the id of the input form. formNode: dojo.byId("myform"), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling backButton: function() { alert("back button pressed"); }, forwardButton: function() { alert("forward button pressed");}, // Type of data you want to receive mimetype: "text/xml" }); } |
| <form id="myform"
name="updateAccount" action="validate" method="post"> <input type="hidden" name="action" value="create"/> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td><b>User Id:</b></td> <td> <input type="text" size="20" id="userid" name="id" onkeyup="validateUserId()"> </td> <td> <div id="userIdMessage"></div> </td> </tr> <tr> <td align="right" colspan="2"> <input id="submit_btn" type="Submit" value="Create Account"> </td> <td></td> </tr> </table> </form> |

| <!-- Dojo
configuration --> <script language="JavaScript" type="text/javascript"> djConfig = { preventBackButtonFix: false }; </script> <!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-0.4.3-ajax/dojo.js"> </script> <script type="text/javascript"> dojo.require("dojo.undo.browser"); var target; |


| // This is the modified validateUserId()
function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), // Since the form data is passed to the server via formNode // parameter below, no need to pass target.value here. url: "validate", // The server code in this ajax-validation // sample application expects "GET". It // uses "POST" for account creation. Probably // not a good practice but that is the way // the server side code is written for now. method: "GET", // Send form data. "myform" is the id of the input form. formNode: dojo.byId("myform"), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling // backButton: function() { alert("back button pressed"); }, // New backward button behavior backButton: function() { // Blank out the User Id field value target.value=""; // Display a message indicating Backward button is pressed var userMessageElement = dojo.byId("userIdMessage"); userMessageElement.innerHTML = "Backward button pressed. Start again!"; // Disable the submit button var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; }, forwardButton: function() { alert("forward button pressed");}, // Type of data you want to receive mimetype: "text/xml" }); } |

In this step, you are going to move the JavaScript code into another file called, myjavascript.js. This is an optional step.
1. (Assuming you have installed
NetBeans JavaScript editor plug-in), right click Web Pages under ajax-validation-dojo.io.bind project
node and select New->JSTemplate.js.
2. Observe New JSTemplate.js
dialog box appears.
3. For the File Name field, type in myjavascript.
Click Finish. (Figure-1.100
below)

Figure-1.100: Create myjavascript.js file
Note: If you have not installed NetBeans
JavaScript editor plug-in, just create a new file called myjavacript.js under Web Pages directory.
| dojo.require("dojo.undo.browser"); var target; // This is the modified validateUserId() function function validateUserId() { //if (!target) target = document.getElementById("userid"); if (!target) target = dojo.byId("userid"); //var sampleFormNode = document.getElementById("submit_btn"); var sampleFormNode = dojo.byId("submit_btn"); // Use dojo.io.bind() for remoting dojo.io.bind({ // URL - location of the data you want to get //url: "validate?id=" + escape(target.value), // Since the form data is passed to the server via formNode // parameter below, no need to pass target.value here. url: "validate", // The server code in this ajax-validation // sample application expects "GET". It // uses "POST" for account creation. Probably // not a good practice but that is the way // the server side code is written for now. method: "GET", // Send form data. "myform" is the id of the input form. formNode: dojo.byId("myform"), // Callback function that you'd like to have called // when you actually do get the data load: function(type, data, evt){ processRequest(data);}, // Error handling error: function(type, error){ alert("error"); }, // Backward and forward button handling backButton: function() { target.value=""; var userMessageElement = dojo.byId("userIdMessage"); userMessageElement.innerHTML = "Backward button pressed. Start again!"; var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; }, forwardButton: function() { alert("forward button pressed");}, // Type of data you want to receive mimetype: "text/xml" }); } // This is the modified processRequest() function. Note that you don't need to // check if the readyState of the XMLHttpRequest is 4 or not. function processRequest(data) { var message = dojo.dom.textContent(data.getElementsByTagName("valid")[0]); setMessageUsingDOM(message); var submitBtn = dojo.byId("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } function setMessageUsingInline(message) { mdiv = dojo.byId("userIdMessage"); if (message == "false") { mdiv.innerHTML = "<div style=\"color:red\">Invalid User Id</div>"; } else { mdiv.innerHTML = "<div style=\"color:green\">Valid User Id</div>"; } } function setMessageUsingDOM(message) { var userMessageElement = document.getElementById("userIdMessage"); var messageText; if (message == "false") { userMessageElement.style.color = "red"; messageText = "Invalid User Id"; } else { userMessageElement.style.color = "green"; messageText = "Valid User Id"; } // Use innerHTML instead of raw DOM API userMessageElement.innerHTML = messageText; } function disableSubmitBtn() { var submitBtn = dojo.byId("submit_btn"); submitBtn.disabled = true; } |
| <%-- Copyright 2005 Sun
Microsystems, Inc. All rights reserved. You may not modify, use,
reproduce, or distribute this software except in compliance with the
terms of the License at: http://developer.sun.com/berkeley_license.html $Id: index.jsp,v 1.4 2005/06/15 05:39:43 gmurray71 Exp $ --%> <html> <head> <!-- Dojo configuration --> <script language="JavaScript" type="text/javascript"> djConfig = { preventBackButtonFix: false }; </script> <!-- Include Dojo toolkit library file dojo.js, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="dojo-0.4.3-ajax/dojo.js"> </script> <script language="JavaScript" type="text/javascript" src="myjavascript.js"> </script> <title>Form Data Validation using AJAX</title> </head> <body onload="disableSubmitBtn()"> <h1>Form Data Validation using AJAX and DOJO</h1> <hr/> <p> This example shows how you can use AJAX to do server-side form data validation without a page reload. </p> <p> In the form below enter a user id. By default the user ids "greg" and "duke" are taken. If you attempt to enter a user id that has been taken an error message will be displayed next to the form field and the "Create Account" button will be disabled. After entering a valid user id and selecting the "Create Account" button that user id will be added to the list of user ids that are taken. </p> <form id="myform" name="updateAccount" action="validate" method="post"> <input type="hidden" name="action" value="create"/> <table border="0" cellpadding="5" cellspacing="0"> <tr> <td><b>User Id:</b></td> <td> <input type="text" size="20" id="userid" name="id" onkeyup="validateUserId()"> </td> <td> <div id="userIdMessage"></div> </td> </tr> <tr> <td align="right" colspan="2"> <input id="submit_btn" type="Submit" value="Create Account"> </td> <td></td> </tr> </table> </form> </body> </html> |
12. Right-click ajax-validation-dojo.bo.bind
project
and select Run Project.
In this exercise, you have modified
sample applications that use XMLHttpRequest to use dojo.io.bind()
from Dojo
toolkit instead.
In this exercise, you will exercise the
various event programming models of the Dojo toolkit.
You can create a new NetBeans project
from scratch
but you can also create one that contains Dojo toolkit library file by
copying the ajax-validation-dojo.io.bind
project. We will name it as dojo-event1
project.
1. Right click ajax-validation-dojo.io.bind
project and select Copy Project.
The Copy Project dialog box
appears.
2. In the Project Name: field,
type in dojo-event1.
(Figure-2.10 below) The copying project might take a couple of minutes.
The dojo-event1
project appears under Projects
tab window.

Figure-2.10: Create dojo-event1 project by copying
3. Change Context Path of the new
project. (You have to do this only for NetBeans 5.0. It is taken
care of automatically for NetBeans 5.5)

Figure-2.11: Change the Context Path to /dojo-event1
We are now going to modify the index.jsp in which we are going to
use dojo.event.connect().
Note: If you want to leave the original
code intact, you can always create a new project by copying the current
project. Please make sure you change the Context Path: to reflect the new
project name if you decided to do so.
1. Double-click the index.jsp file of the dojo-event1 project to open it in the source editor. Please make sure you do not change the index.jsp file of the ajax-validation-dojo.io.bind project unless that is what you want to.
2. Replace the complete content of the index.jsp file with the following
code (Code-2.20 below). Please study how dojo.event.connect() call is used to
register myHandler event
handler to the onclick property
of the mylink node.
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascript" src="dojo-0.4.3-ajax/dojo.js"> </script> <script type="text/javascript"> window.onload = function () { var link = document.getElementById("mylink"); // "myHandler" event handler is registered to the // "onclick" property of the "mylink" node. dojo.event.connect(link, "onclick", myHandler); } // Define an event handler named as "myHandler" function myHandler(evt) { alert("myHandler: invoked - this is a named event handler - if you see this, that means calling dojo.event.connect() was successful."); } </script> <title>Simple Dojo Event Handler</title> </head> <body> <h1>Simple Dojo Event Handler</h1> <hr/> <p> This example shows the usage of dojo.event.connect() registering an event handler to a DOM node. When a user clicks on "Click Me" link, it should pop up an alert, which is invoked within the event handler. </p> <a href="#" id="mylink">Click Me</a> </body> </html> |
3. Right click dojo-event1 project and select Run Project. You should see
the following page. (Figure-2.21 below)

Figure-2.21: Simple Dojo Event
Handler front page

1. Modify the index.jsp to use
dojo.event.connect() call for
window loading event. (Code-2.30
below). The new code fragments that need to be added are
highlighted in bold
and blue-colored font while the old code fragments that need to
be removed are highlighted in bold and red colored
font. The code fragments that remain the same are in
regular font.
| <html> <head> <!-- Include Dojo toolkit library file dojo.js, make sure the directory is correct --> <script language="JavaScript" type="text/javascri |