Ajax Frameworks
- About the benefits of Ajax Frameworks.
- How to use the Dojo framework to make XMLHttpRequests.
- How to use the Prototype framework to make XMLHttpRequests.
- About some other popular frameworks.
The Purpose of Frameworks
JavaScript frameworks can serve several purposes:
- Abstraction. Writing JavaScript is notoriously difficult in large part because of the browser and platform differences. Although this has improved a lot since the Netscape 4 / IE 4 days, JavaScript developers still have to be aware of differences in browser object models. One purpose of frameworks is to abstract those differences.
- Widget Libraries. Many frameworks provide libraries of pre-written, customizable widgets (expandable trees, accordions, autocompletes, drag-and-drop controls, etc.).
- Development Structure. Some frameworks make it easier to create structured, object-oriented Ajax applications.
Choosing a Framework
Choosing a framework to use for your Ajax applications is a difficult task. At the time of this writing, the AjaxPatterns website (http://ajaxpatterns.org/Ajax_Frameworks) listed:
- 30 multi-purpose Ajax frameworks
- 32 Java-specific Ajax frameworks
- 27 PHP-specific Ajax frameworks
- 15 .NET-specific Ajax frameworks
Many of these frameworks are created by individuals or small groups and most are non-commercial. So how do you choose? It's a tough job, but here are some general guidelines.
- Choose a framework with staying power. The more mature frameworks like Prototype and Dojo, which we will review shortly, have built up pretty large followings, so they are more likely to persist. They are also more likely to be better documented and supported by an online community.
- Choose a framework that is either language neutral or specific to your server-side language. This is pretty obvious, but you don't want a PHP framework if you are building a Java application.
- Choose a framework that plays nicely with other frameworks. For example, script.aculo.us and Rico both require Prototype, so if you want to use some of their cool dynamic features, you will have to use Prototype as well.
- Choose a framework that fits your skillset. If your developers are very comfortable with JavaScript, you might choose a framework that is JavaScript-centric like Prototype or Dojo. If you are a team of Java or JSP developers who have not done much client-side programming, you might choose a framework like AjaxAnywhere , which autogenerates the JavaScript. Such frameworks provide less flexibility but may decrease development time.
We will look at two popular frameworks: Dojo and Prototype. Note that these frameworks have a much broader focus than Ajax, but for now, we'll be focusing on how they handle XMLHttpRequests.
Dojo
Dojo is a multi-purpose JavaScript toolkit that, according to its website, "makes professional web development better, easier, and faster." Dojo has been in development since late 2004 and is one of the most comprehensive JavaScript toolkits available. It is client-side specific so it can be used on any platform with any server-side language. The documentation for Dojo is relatively good compared with other frameworks.
Downloading Dojo
The latest version of Dojo is freely available for download at http://dojotoolkit.org as a zip file. Simply unzip the files to a folder on your webserver. For our Ajax examples, you will only need the dojo.js library, which is included with your class files (AjaxFrameworks/Demos/Dojo/dojo.js).
Using Dojo for Ajax
To make the Dojo library available, include the dojo.js file as you would any other JavaScript library:
<script language="javascript" src="dojo.js"></script>
Dojo uses an object-oriented approach with dojo being the top-level object. Ajax applications use the input/output APIs, which are included with this line of code:
dojo.require("dojo.io.*");XMLHttpRequests are made using the bind() method, which takes one parameter: a request object, which has the following properties and methods :
| Property | Description |
|---|---|
| url | String. The location of the resource being requested. |
| mimetype | String. Mimetype used to interpret the contents of the response with. Defaults to "text/plain". It is used to determine whether the response text should be evaluated with the JavaScript eval() function. |
| method | String. Method of request. Usually "get" or "post". Defaults to "get". |
| content | Object. A key/value mapping of properties to be constructed into parameters passed with the data request. For example, querystring parameters or form fields in POST requests. |
| transport | String. Explicitly specifies the transport object to use for the request. It defaults to "XMLHttp". Other options are "IFrame I/O" and "ScriptSrcIO". |
| changeUrl | Boolean. Defaults to false. Determines whether or not the request should be made "bookmarkable". |
| formNode | DOM Node that specifies a form to be serialized and submitted by this request. |
| sync | Boolean. Defaults to false. Determines whether the accepting transport should attempt to make the request synchronously. |
| bindSuccess | Boolean. Defaults to false. Indicates whether or not this Request was accepted and dispatched by any transport. |
| useCache | Boolean. Defaults to false. Indicates whether the result of the Request should be cached and whether requesting a result for this Request from the cache is acceptable. |
| Property | Description |
|---|---|
| handle(type, data, event) | Callback method used when load, error or another status-specific handler is not defined or not available. The event type may be determined via string comparision with the type parameter (e.g, if (type == "load") {...) |
| load(type, data, event) | Callback method used when data is successfully returned for this Request. The type parameter will always be "load". The data parameter passes in the data returned from the server, subject to any pre-processing the accepting transport class may have applied. For example, if a mimetype of "text/javascript" is specified then the result will be passed through JavaScript's eval() function. For XMLHttpRequests, the event parameter is a reference to the XMLHTTP object used to dispatch the network request. |
| error(type, errorObject) | Callback method used when data cannot be returned for this Request. The type parameter will always be "load". The errorObject parameter provides details about the failure. |
| abort() | Method for aborting pending Request dispatch. |
Here is the syntax of a simple call to the bind() method:
dojo.io.bind(
{
url: URL,
load: CallBackFunction,
method: "get", //or "post"
content: {
param1: value,
param2: value,
param3: value
}
});The code sample below shows how we would change part of our EmployeeAdmin.html document to use Dojo.
Code Sample: AjaxFrameworks/Demos/Dojo/EmployeeAdmin.html
<html>
<head>
<title>Employee Administration</title>
<link rel="stylesheet" type="text/css" href="../Styles/Main.css">
<script type="text/javascript" src="http://o.aolcdn.com/dojo/0.4.3/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.io.*");
var OutputDiv;
function GetEmployeeList(URL)
{
OutputDiv = document.getElementById("EmployeeList");
OutputDiv.innerHTML="<h2>Loading...</h2>";
dojo.io.bind(
{
url: URL,
load: Display,
method: "post"
});
}
function Display(TYPE, DATA, REQ)
{
OutputDiv.style.display="block";
if (DATA.indexOf("Failed") != -1)
{
OutputDiv.className="Warning";
OutputDiv.innerHTML=DATA;
}
else
{
OutputDiv.innerHTML = DATA;
}
}
window.onload = function()
{
GetEmployeeList("../EmployeeList.jsp");
}
</script>
</head> ---- Code Omitted ----
As you can see, we only need to make use of the url and method properties and the load method of the Request object that is passed to the bind() method. To pass parameters in with the XMLHttpRequest, we would need to include the content property as well.
Another thing to notice is that the callback function (Display()) no longer needs to check the status and the readyState of the xmlhttp object. This is handled by Dojo.
Prototype
Prototype is a multi-purpose JavaScript toolkit that, according to its website, "aims to ease development of dynamic web applications." Many other libraries, such as script.aculo.us and Rico are built on top of Prototype and the Ruby on Rails framework has built-in support for Prototype. These tie-ins make it likely that Prototype will be around for a long time. Like Dojo, it is client-side specific so it can be used on any platform with any server-side language. There is no good documentation on the Prototype site, but Sergio Pereira has put together some very good online documentation at http://www.sergiopereira.com/articles/prototype.js.html. Webucator has created a PDF version hosted at http://www.sergiopereira.com/articles/DeveloperNotes-Prototype-JS.pdf.
Downloading Prototype
The latest version of Prototype is freely available for download at http://prototype.conio.net as a .js file. Rename the file to "prototype.js" and save it in a folder on your webserver. We have included a copy of it with your class files (AjaxFrameworks/Demos/Prototype/prototype.js).
Using Prototype for Ajax
To make the Prototype library available, include the prototype.js file as you would any other JavaScript library:
<script language="javascript" src="prototype.js"></script>
XMLHttpRequests are made using the Ajax.Request() class, which, when instantiated, takes two parameters: a URL string and an object, which has the following properties and methods:
| Property | Description |
|---|---|
| method | String. Method of request. Usually "get" or "post". |
| parameters | String. Querystring parameters or form fields in POST requests, using the querystring syntax (e.g, "firstname=Nat&lastname=Dunn") |
| asynchronous | Boolean. Defaults to true. Determines whether the request should be made synchronously. |
| Property | Description |
|---|---|
| onComplete(xmlhttp) | Callback method used when onSuccess or onFailure is not defined or not available. The only parameter is a reference to the XMLHTTP object used to dispatch the request. |
| onSuccess(xmlhttp) | Callback method used when data is successfully returned for this Request. The only parameter is a reference to the XMLHTTP object used to dispatch the request. |
| onFailure(xmlhttp) | Callback method used when data cannot be returned for this Request. The only parameter is a reference to the XMLHTTP object used to dispatch the request. |
Here is the syntax of a simple call to the Ajax.Request() constructor:
new Ajax.Request(URL,
{
method: "get", //or "post"
onComplete: CallBackFunction,
parameters: "param1=value¶m2=value¶m3=value"
});The code sample below shows how we would change part of our EmployeeAdmin.html document to use Prototype.
Code Sample: AjaxFrameworks/Demos/Prototype/EmployeeAdmin.html
<html>
<head>
<title>Employee Administration</title>
<link rel="stylesheet" type="text/css" href="../Styles/Main.css">
<script type="text/javascript" src="../../../prototype.js"></script>
<script type="text/javascript" src="../Scripts/Effects.js"></script>
<script type="text/javascript">
var OutputDiv;
function GetEmployeeList(URL)
{
OutputDiv = document.getElementById("EmployeeList");
OutputDiv.innerHTML="<h2>Loading...</h2>";
new Ajax.Request(URL,
{
method: "post",
onComplete: Display
});
}
function Display(REQ)
{
OutputDiv.style.display="block";
if (REQ.responseText.indexOf("Failed") != -1)
{
OutputDiv.className="Warning";
OutputDiv.innerHTML=REQ.responseText;
}
else
{
OutputDiv.innerHTML = REQ.responseText;
}
}
window.onload = function()
{
GetEmployeeList("../EmployeeList.jsp");
}
</script>
</head> ---- Code Omitted ----
As you can see, we only need to make use of the url property and the second parameter's method property and the onComplete method. To pass parameters in with the XMLHttpRequest, we would need to include the parameters property as well.
Like with Dojo, the callback function (Display()) no longer needs to check the status and the readyState of the xmlhttp object as Prototype takes care of this behind the scenes.
Throughout the rest of this manual, we will be using Prototype to handle our XMLHttpRequests.
Other Popular Frameworks
Direct Web Remoting (DWR)
DWR is one of the more popular Java-specific frameworks. It makes it possible to call Java methods directly from JavaScript by blackboxing the data transfer to and from the server to make it feel to the developer as if Java objects were natively available to the browser.
AjaxAnywhere
According to its website, "AjaxAnywhere is designed to turn any set of existing JSP or JSF components into AJAX-aware components without complex JavaScript coding." The major benefit of AjaxAnywhere is that it makes it possible to create Ajax applications without writing much JavaScript. The downside is that it does not provide as much flexibility as the more JavaScript-centric solutions.
Simple Ajax (SAJAX)
Like DWR, Sajax allows you to access server-side code directly from JavaScript. It supports ASP, ColdFusion, Perl, PHP, Python, and Ruby, but not Java.
Sarissa
Sarissa is a JavaScript-centric library that isn't specific to any server-side language. It provides a simple function that emulates Mozilla's XMLHttpRequest for Internet Explorer, but that's about it when it comes to client-server communication. It does make using XSLT in the browser very easy.
Other Frameworks
As noted in the beginning of this lesson, there are many more frameworks. For a good list, see http://ajaxpatterns.org/Ajax_Frameworks.
Ajax Frameworks Conclusion
In this lesson of the Ajax tutorial, you have learned about some common Ajax frameworks and how to use a couple of the most popular to handle XMLHttpRequests.
