
This hands-on lab takes you through the basics of using Prototype
JavaScript library. First, you will explore various utitlity
functions. Second, you will modify ajax-validation project to use
Ajax.Request function of the Prototype.
Expected duration: 60 minutes
Before you begin, you need to install the following software on your
computer.
This hands-on lab is based on Developer
Notes for prototype.js JavaScript tutorial written by Sergio
Pereira with the permission from the author. We thank Sergio
for his generosity.
In this exercise, you are going to learn
how to use various utility functions of the Prototype JavaScript
library.
Read description
of $() function before you proceed.
0. Start NetBeans IDE.
1. Open prototypesamplescripts
NetBeans project.
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function test1() { // Get element whose id is 'myDiv' via $() var d = $('myDiv'); alert(d.innerHTML); } function test2() { // Get elements into an array via $() var divs = $('myDiv','myOtherDiv'); // Display child node of the each item in the array for(i=0; i<divs.length; i++) { alert(divs[i].innerHTML); } } </script> </HEAD> <BODY> <h3> The $() function </h3> <hr/> <p> The $() function is a handy shortcut to the all-too-frequent document.getElementById() function of the DOM. Like the DOM function, this one returns the element that has the id passed as an argument. Unlike the DOM function, though, this one goes further. You can pass more than one id and $() will return an Array object with all the requested elements. </p> <hr/> <div id="myDiv"> <p>This is the first paragraph</p> </div> <div id="myOtherDiv"> <p>This is the second paragraph</p> </div> <input type="button" value=Test1 onclick="test1();"><br><br> <input type="button" value=Test2 onclick="test2();"><br><br> </BODY> </HTML> |





| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function test1() { // Get element whose id is 'myDiv' via $() var d = $('myDiv'); alert(d.innerHTML); } function test2() { // Get elements into an array via $() var divs = $('myDiv','myOtherDiv','my3rdDiv'); // Display child node of the each item in the array for(i=0; i<divs.length; i++) { alert(divs[i].innerHTML); } } </script> </HEAD> <BODY> <h3> The $() function </h3> <hr/> <p> The $() function is a handy shortcut to the all-too-frequent document.getElementById() function of the DOM. Like the DOM function, this one returns the element that has the id passed as an argument. Unlike the DOM function, though, this one goes further. You can pass more than one id and $() will return an Array object with all the requested elements. </p> <hr/> <div id="myDiv"> <p>This is the first paragraph</p> </div> <div id="myOtherDiv"> <p>This is the second paragraph</p> </div> <div id="my3rdDiv"> <p>This is the third paragraph</p> </div> <input type="button" value=Test1 onclick="test1();"><br><br> <input type="button" value=Test2 onclick="test2();"><br><br> </BODY> </HTML> |
Figure-1.17: Save the change
before viewing it| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function test3() { // Display the value of the input form field whose id // is "userName" alert( $F('userName') ); } </script> </HEAD> <BODY> <h3> The $F() function </h3> <hr/> <p> The $F() function is a another welcome shortcut. It returns the value of any field input control, like text boxes or drop-down lists. The function can take as argument either the element id or the element object itself. </p> // Input form field whose value is set to Joe Doe <input type="text" id="userName" value="Joe Doe"><br> <input type="button" value=Test3 onclick="test3();"><br> </BODY> </HTML> |

| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function test3() { // Display the value of the input form field whose id // is "userName" alert( $F('userName') ); alert( $F('myOwnInputField') ); } </script> </HEAD> <BODY> <h3> The $F() function </h3> <hr/> <p> The $F() function is a another welcome shortcut. It returns the value of any field input control, like text boxes or drop-down lists. The function can take as argument either the element id or the element object itself. </p> <!--Input form field whose value is set to Joe Doe--> <input type="text" id="userName" value="Joe Doe"><br> <input type="text" id="myOwnInputField" value="Sang Shin"><br> <input type="button" value=Test3 onclick="test3();"><br> </BODY> </HTML> |
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function showOptions(){ // Get all nodes whose tag name is 'option' var someNodeList = $('lstEmployees').getElementsByTagName('option'); // Create an array from the node list var nodes = $A(someNodeList); // Display name of the node and innerHTML value from the array nodes.each(function(node){ alert(node.nodeName + ': ' + node.innerHTML); }); } </script> </HEAD> <BODY> <h3> The $A() function </h3> <hr/> <p> The $A() function converts the single argument it receives into an Array object. This function, combined with the extensions for the Array class, makes it easier to convert or copy any enumerable list into an Array object. One suggested use is to convert DOM NodeLists into regular arrays, which can be traversed more efficiently. </p> <select id="lstEmployees" size="10" > <option value="5">Buchanan, Steven</option> <option value="8">Callahan, Laura</option> <option value="1">Davolio, Nancy</option> </select> <input type="button" value="Show the options" onclick="showOptions();" > </BODY> </HTML> |
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function showOptions(){ // Get all nodes whose tag name is 'option' var someNodeList = $('lstEmployees').getElementsByTagName('option'); // Create an array from the node list var nodes = $A(someNodeList); // Display name of the node and innerHTML value from the array nodes.each(function(node){ alert(node.nodeName + ': ' + node.innerHTML); }); } </script> </HEAD> <BODY> <h3> The $A() function </h3> <hr/> <p> The $A() function converts the single argument it receives into an Array object. This function, combined with the extensions for the Array class, makes it easier to convert or copy any enumerable list into an Array object. One suggested use is to convert DOM NodeLists into regular arrays, which can be traversed more efficiently. </p> <select id="lstEmployees" size="10" > <option value="5">Buchanan, Steven</option> <option value="8">Callahan, Laura</option> <option value="1">Davolio, Nancy</option> <option value="3">Shin, Sang</option> </select> <input type="button" value="Show the options" onclick="showOptions();" > </BODY> </HTML> |
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function testHash() { //let's create the object var a = { first: 10, second: 20, third: 30 }; //now transform it into a hash var h = $H(a); alert(h.toQueryString()); //displays: first=10&second=20&third=30 } </script> </HEAD> <BODY> <h3> The $H() function </h3> <hr/> <p> The $H() function converts objects into enumerable Hash objects that resemble associative arrays. </p> <input type="button" value="Generate hash" onclick="testHash();" > </BODY> </HTML> |

| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function testHash() { //let's create the object var a = { first: 10, second: 20, third: 30, fourth: 40 }; //now transform it into a hash var h = $H(a); alert(h.toQueryString()); //displays: first=10&second=20&third=30 } </script> </HEAD> <BODY> <h3> The $H() function </h3> <hr/> <p> The $H() function converts objects into enumerable Hash objects that resemble associative arrays. </p> <input type="button" value="Generate hash" onclick="testHash();" > </BODY> </HTML> |

| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function demoDollar_R(){ var range = $R(10, 15, false); range.each(function(value, index){ alert(value); }); } </script> </HEAD> <BODY> <h3> The $R() function </h3> <hr/> <p> The $R() function is simply a short hand to writing new ObjectRange(lowerBound, upperBound, excludeBounds). Jump to the ObjectRange class documentation for a complete explanation of this class. In the meantime, let's take a look at a simple example that also shows the usage of iterators through the each method. </p> <input type="button" value="Sample Count" onclick="demoDollar_R();" > </BODY> </HTML> |
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function demoDollar_R(){ var range = $R(10, 16, false); range.each(function(value, index){ alert("value=" + value + " index=" + index); }); } </script> </HEAD> <BODY> <h3> The $R() function </h3> <hr/> <p> The $R() function is simply a short hand to writing new ObjectRange(lowerBound, upperBound, excludeBounds). Jump to the ObjectRange class documentation for a complete explanation of this class. In the meantime, let's take a look at a simple example that also shows the usage of iterators through the each method. </p> <input type="button" value="Sample Count" onclick="demoDollar_R();" > </BODY> </HTML> |
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function getXmlNodeValue(){ var value = Try.these( function() { return 1; }, function() { return 2;} ); alert("value returned = " + value); } </script> </HEAD> <BODY> <h3> Try.these </h3> <hr/> <p> The Try.these() function makes it easy when you want to, ahem, try different function calls until one of them works. It takes a number of functions as arguments and calls them one by one, in sequence, until one of them works, returning the result of that successful function call. In the example, the function xmlNode.text works in some browsers, and xmlNode.textContent works in the other browsers. Using the Try.these() function we can return the one that works. </p> <input type="button" value="Try.these" onclick="getXmlNodeValue();" > </BODY> </HTML> |
| <HTML> <HEAD> <TITLE> Test Page </TITLE> <script src="prototype-1.4.0.js"></script> <script> function getXmlNodeValue(){ var value = Try.these( function() { intentionalerror; // intentional error return 1; }, function() { return 2;} ); alert("value returned = " + value); } </script> </HEAD> <BODY> <h3> Try.these </h3> <hr/> <p> The Try.these() function makes it easy when you want to, ahem, try different function calls until one of them works. It takes a number of functions as arguments and calls them one by one, in sequence, until one of them works, returning the result of that successful function call. In the example, the function xmlNode.text works in some browsers, and xmlNode.textContent works in the other browsers. Using the Try.these() function we can return the one that works. </p> <input type="button" value="Try.these" onclick="getXmlNodeValue();" > </BODY> </HTML> |
In this exercise, you have
exercises various utility functions of Prototype JavaScript library.
2 Build and run ajax-validation-p project.
In this step, you are going to modify
index.jsp file to use
Prototype's Ajax.Request
instead of directly creating
XMLHttpRequest JavaScript
object and using it to perform asynchronous
communication with the server.
| <%-- 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> <!-- Include Prototype library, make sure the directory path is set correctly --> <script language="JavaScript" type="text/javascript" src="prototype-1.4.0.js"> </script> <script type="text/javascript"> var req; var target; var isIE; /********************* Commented out ******************* // (3) JavaScript function in which XMLHttpRequest JavaScript object is created. // Please note that depending on a browser type, you create // XMLHttpRequest JavaScript object differently. Also the "url" parameter is not // used in this code (just in case you are wondering why it is // passed as a parameter). // function initRequest(url) { if (window.XMLHttpRequest) { req = new XMLHttpRequest(); } else if (window.ActiveXObject) { isIE = true; req = new ActiveXObject("Microsoft.XMLHTTP"); } } // (2) Event handler that gets invoked whenever a user types a character // in the input form field whose id is set as "userid". This event // handler invokes "initRequest(url)" function above to create XMLHttpRequest // JavaScript object. // * We don't need to do the low-level XMLHttpRequest handling anymore * since it is handled by dojo.io.bind(). function validateUserId() { if (!target) target = document.getElementById("userid"); var url = "validate?id=" + escape(target.value); // Invoke initRequest(url) to create XMLHttpRequest object initRequest(url); // The "processRequest" function is set as a callback function. // (Please note that, in JavaScript, functions are first-class objects: they // can be passed around as objects. This is different from the way // methods are treated in Java programming language.) req.onreadystatechange = processRequest; req.open("GET", url, true); req.send(null); } **********************************************************/ // This is the modified validateUserId() function function validateUserId() { if (!target) target = $("userid"); var sampleFormNode = $("submit_btn"); // Use Prototype's Ajax.Request for remoting var url = 'validate'; var pars = "action=create&"+ "id=" + escape(target.value); var myAjax = new Ajax.Request( url, { method: 'get', parameters: pars, onComplete: processRequest } ); } // (4) Callback function that gets invoked asynchronously by the browser // when the data has been successfully returned from the server. // (Actually this callback function gets called every time the value // of "readyState" field of the XMLHttpRequest object gets changed.) // This callback function needs to be set to the "onreadystatechange" // field of the XMLHttpRequest. // /********************* commented out ************************************** function processRequest() { if (req.readyState == 4) { if (req.status == 200) { // Extract "true" or "false" from the returned data from the server. // The req.responseXML should contain either <valid>true</valid> or <valid>false</valid> var message = req.responseXML.getElementsByTagName("valid")[0].childNodes[0].nodeValue; // Call "setMessageUsingDOM(message)" function to display // "Valid User Id" or "Invalid User Id" message. setMessageUsingDOM(message); // If the user entered value is not valid, do not allow the user to // click submit button. var submitBtn = document.getElementById("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } } } *******************************************************************/ // Modified processRequest(req) function. Notice we do not have to check the readyState // and status fields of the XMLHttpRequest object. function processRequest(req) { var message = req.responseXML.getElementsByTagName("valid")[0].childNodes[0].nodeValue; setMessageUsingDOM(message); var submitBtn = $("submit_btn"); if (message == "false") { submitBtn.disabled = true; } else { submitBtn.disabled = false; } } // This function is not used for now. You will use this later. // 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>"; } } // (5) Function in which message indicating the validity of the data gets displayed // through the "userIdMessage" <div> element. // function setMessageUsingDOM(message) { // var userMessageElement = document.getElementById("userIdMessage"); var userMessageElement = $("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"); var submitBtn = $("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> <!-- (1) 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> |
In this exercise, you have modified
sample applications that use XMLHttpRequest to use Ajax.Request
from Prototype.