《AJAX In Action》
Code Down: http://www.manning.com/crane.
Ajax (Asynchronous JavaScript + XML)
For example DOM
window.οnlοad=function(){
var hello=document.getElementById('hello');
hello.className='declared';
var empty=document.getElementById('empty');
addNode(empty,"reader of");
addNode(empty," Ajax in Action!");
var children=empty.childNodes;
for (var i=0;i<children.length;i++){
children[i].className='programmed';
}
empty.style.border='solid green 2px';
empty.style.width="200px";
}
function addNode(el,text){
var childEl=document.createElement("div");
el.appendChild(childEl);
var txtNode=document.createTextNode(text);
childEl.appendChild(txtNode);
}
For example
document.getElementsByTagName("UL")
For example
function addListItemUsingInnerHTML(el,text){
el.innerHTML+="<div class='programmed'>"+text+"</div>";
}
Create XmlhttpRequest
function getXMLHTTPRequest() {
var xRequest=null;
if (window.XMLHttpRequest) {
xRequest=new XMLHttpRequest();
}else if (typeof ActiveXObject != "undefined"){
xRequest=new ActiveXObject
("Microsoft.XMLHTTP");
}
return xRequest;
}
var READY_STATE_UNINITIALIZED=0;
var READY_STATE_LOADING=1;
var READY_STATE_LOADED=2;
var READY_STATE_INTERACTIVE=3;
var READY_STATE_COMPLETE=4;
var req;
function sendRequest(url,params,HttpMethod){
if (!HttpMethod){
HttpMethod="GET";
}
req=getXMLHTTPRequest();
if (req){
req.onreadystatechange=onReadyStateChange;
req.open(HttpMethod,url,true);
req.setRequestHeader
("Content-Type", "application/x-www-form-urlencoded");
req.send(params);
}
}
function onReadyStateChange(){
var ready=req.readyState;
var data=null;
if (ready==READY_STATE_COMPLETE){
data=req.responseText;
}else{
data="loading...["+ready+"]";
}
//... do something with the data...
}
For Example
<html>
<head>
<script type='text/javascript'>
var req=null;
var console=null;
var READY_STATE_UNINITIALIZED=0;
var READY_STATE_LOADING=1;
var READY_STATE_LOADED=2;
var READY_STATE_INTERACTIVE=3;
var READY_STATE_COMPLETE=4;
function sendRequest(url,params,HttpMethod){
if (!HttpMethod){
HttpMethod="GET";
}
req=initXMLHTTPRequest();
if (req){
req.onreadystatechange=onReadyState;
req.open(HttpMethod,url,true);
req.setRequestHeader
("Content-Type", "application/x-www-form-urlencoded");
req.send(params);
}
}
function initXMLHTTPRequest(){
var xRequest=null;
if (window.XMLHttpRequest){
xRequest=new XMLHttpRequest();
} else if (window.ActiveXObject){
xRequest=new ActiveXObject
("Microsoft.XMLHTTP");
}
return xRequest;
}
function onReadyState(){
var ready=req.readyState;
var data=null;
if (ready==READY_STATE_COMPLETE){
data=req.responseText;
}else{
data="loading...["+ready+"]";
}
toConsole(data);
}
function toConsole(data){
if (console!=null){
var newline=document.createElement("div");
console.appendChild(newline);
var txt=document.createTextNode(data);
newline.appendChild(txt);
}
}
window.οnlοad=function(){
console=document.getElementById('console');
sendRequest("data.txt");
}
</script>
</head>
<body>
<div id='console'></div>
</body>
</html>
Early Ajax solutions using IFrames are described at http://developer.apple.com/internet/webcontent/iframe.html.
The AJAX Flow
Figure 1
The following items represent the setups of an AJAX interaction as they appear in Figure 1.
1. A client event occurs.
2. An XMLHttpRequest object is created and configured.
3. The XMLHttpRequest object makes a call.
4. The request is processed by the ValidateServlet.
5. The ValidateServlet returns an XML document containing the result.
6. The XMLHttpRequest object calls the callback() function and processes the result.
7. The HTML DOM is updated.
Example
<script type="text/javascript">
function AJAXInteraction(url, callback) {
var req = init();
req.onreadystatechange = processRequest;
function init() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
function processRequest () {
// readyState of 4 signifies request is complete
if (req.readyState == 4) {
// status of 200 signifies sucessful HTTP call
if (req.status == 200) {
if (callback) callback(req.responseXML);
}
}
}
this.doGet = function() {
req.open("GET", url, true);
req.send(null);
}
}
function validateUserId() {
var target = document.getElementById("userid");
var url = "validate?id=" + encodeURIComponent(target.value);
var target = document.getElementById("userid");
var ajax = new AJAXInteraction(url, validateCallback);
ajax.doGet();
}
function validateCallback(responseXML) {
var msg = responseXML.getElementsByTagName("valid")[0].firstChild.nodeValue;
if (msg == "false"){
var mdiv = document.getElementById("userIdMessage");
// set the style on the div to invalid
mdiv.className = "bp_invalid";
mdiv.innerHTML = "Invalid User Id";
var submitBtn = document.getElementById("submit_btn");
submitBtn.disabled = true;
} else {
var mdiv = document.getElementById("userIdMessage");
// set the style on the div to valid
mdiv.className = "bp_valid";
mdiv.innerHTML = "Valid User Id";
var submitBtn = document.getElementById("submit_btn");
submitBtn.disabled = false;
}
}
</script>
How to call
<input type="text" size="20" id="userid" name="id" autocomplete="off" οnkeyup="validateUserId()">
AJAX Use Scene
Autocomplete
Autocomplete provides a simplified means of data navigation as the user enters a request in an HTML form. When faced with a large set of data, the user can be presented with a list of potential completions as the data is entered. Selecting one of the completions ensures that the user is entering data that exists on the server.
Consider a name finder web application inside a large corporation. Details about an individual can be obtained just from entering the first few characters of the first or last name, as in Figure 2. The user can then navigate to the user in question with one click.
|
Figure 2: Autocompletion of a Name |
Progress Bar
In web applications, a server-side task may take some time to complete. This time may extend longer than the time out of an HTTP interaction. Frustrated users may resubmit a form or quit a session when they do not know how long the task will take. Typically, web applications use page refreshes to track the progress of a server-side operation, which can be distracting and not accurate. AJAX can be used to track the progress of a server-side operation in an HTML page without refreshing the HTML page. The user will see the progress of the server-side operation graphically in Figure 3.
|
Figure 3: Progress Bar |
Refreshing Data
Providing up-to-date data or server notifications to an HTML page is important in the web world, where data is constantly changing. Although this is not push technology in a literal sense, it is simulated by polling from the client using AJAX interactions. When data needs to be updated or notifications need to be made, the HTML page is dynamically changed. Figure 4 shows a server-side counter being displayed in an HTML page. The counter will update in the background of the page.
|
Figure 4: Server-side Counter Shows Refreshing Data |
Real-Time Validation
Not all form fields can be validated on the client using JavaScript technology alone. Some types of form data require server-side validation logic. Conventional web applications have used page refreshes to do this type of validation, but it can be a little distracting.
Consider a web application that requires a unique user ID. Using AJAX interactions, the user can know while typing whether or not the ID is valid (Figure 5).
|
Figure 5: Invalidating the ID as User Types |
When a user enters an invalid user ID, the application disables the submit button and presents a message to the user (Figure 6).
|
Figure 6: Validating the ID as User Types |
The user knows right away that the user ID is available and valid.