Professional Documents
Culture Documents
Getting Started With: by Dave Crane
Getting Started With: by Dave Crane
Getting Started With: by Dave Crane
com
CONTENTS INCLUDE:
n
Ajax User Interfaces
Hot Tips and more...
By Dave Crane
The standard way to do Ajax is to use the XMLHttpRequest object, To make use of the XHR to its fullest, we recommend you
known as XHR by its friends. Use XHR directly, or via one of the become familiar with the workings of the HTTP protocol. Using
helpful Ajax libraries such as Prototype or jQuery. How do we use Ajax, you have much more control over HTTP than with classic
XHR “by hand”? To start with, we need to get a reference to it: web app development.
if (window.XMLHttpRequest) {
request
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject(“Microsoft.XMLHTTP”);
headers
}
We can then open a connection to a URL:
browser body
xhr.open(
“GET”,
“my-dynamic-content.jsp?id=”
+encodeURI(myId), server
true
);
body
xhr.onreadystatechange = function(){
response
processReqChange(req);
}
HTTP is a stateless request-response protocol.
and then send the request:
xhr.send(null); n
Both request and response contain headers and an optional
The server may be busy, or the network may be slow. We don’t want body, which is free text.
to sit around doing nothing until the response arrives, and because n
Only a POST request contains a body.
we’ve assigned the callback function, we don’t have to. That’s the
five-minute guide for the impatient. For those who like to know
n
A request defines a verb or method.
the details, we’ve listed the fuller details of the XHR object below. n
The Mime type of request and response can be set by the
header Content-type
Method Name Parameters and Descriptions
responseText body of response as a JavaScript string (only set after n Hot tips & examples
response reaches the interactive readyState)
n Bonus content online
responseXML body of the response as a XML document object (only
set after response reaches the interactive readyState) n New issue every 1-2 weeks
GET Strictly speaking, should be used only to fetch data, not to effect xhr.onreadystatechange=function(){
changes on the server. GET requests contain no body. Parameters are if (xhr.readyState==4){
passed in the querystring of the URL. if (xhr.status==200){
POST Should be used to update data on the server. Parameters/data passed parseResponse(xhr);
in the body. }else{
//handle the HTTP error...
HEAD Will fetch the headers of the response only, not the body. Useful for
finding out how large a resource is (read the Content-length header) }
or how old it is (read the Last-modified header), for example. };
};
If you’re using the increasingly popular REST approach to web
services, the HTTP verb is used to indicate the type of operation XHR ReadyState Values
being performed. The most commonly used HTTP verbs in REST State Value Comments
map onto the CRUD (create, read, update, delete) approach:
0 Uninitialized The request hasn’t yet been sent
HTTP Verb CRUD Notes 1 Loading The response hasn’t yet arrived
operation
2 Loaded Response headers can be read
PUT Create Add a new object instance to the domain model.
3 Interactive Response body is incomplete, but can be read
GET Read Get an existing domain object from the server.
4 Complete Response body is complete
POST Update Modify an existing domain object.
DELETE Delete Remove an existing object from the domain model. So, what might the parseResponse() method look like? We have
a lot of freedom in the types of response we send. Let’s look at
Common Mime Types some of the common ones.
Setting the right mime type for your request and response is
good manners—it’s also vital to get the app to behave correctly! Handling a HTML Response
The server can send pre-assembled HTML content, which we
Mime Type Meaning Usage
just stitch into the web page.
application/x-www- Body is an encoded Sending request from HTML
form-urlencoded querystring of form or Ajax. Required in order <table class=’item selected’> function parseResponse(xhr){
key-value pairs for server to decode parameters <tr> var div=document
into $_GET, servlet parameters, or <td rowspan=’3’ valign=’top’><div .getElementById(“myDiv”);
HttpRequest.Form. class=’itemIcon’><img div.innerHTML=xhr.responseText;
src=’../images/kmoon.png’></div></td> }
text/xml, Body is an XML Can be used anywhere – request <td class=’itemTitle’>The Moon on a
application/xml document or response. Must set response to Stick</td>
</tr>
one of these in order to use XHR.
<tr>
responseXML property.
<td valign=’top’>What every project
manager wants - and they want it
text/plain Body is plain
yesterday!<br/><br/><i>NB: Stick not
unformatted text included.</i></td>
</tr>
text/html, text/xhtml Body is (X)HTML Standard web pages sent from
<tr>
content server, or content fragments sent to <td><div class=’price’>$365.00</div></td>
Ajax apps. </tr>
</tr>
text/javascript Body is a piece of Standard .js files, JavaScript </table>
JavaScript code fragments sent to Ajax apps.
→
form-urlencoded
n
Set the response mime type to application/xml or text/xml if
you want to use the responseXML property
Handling an XML Response Does Ajax only affect the client-side? Certainly not! Particularly
XML is a more natural fit for most server technologies. XHR sup- if your server is responding with data rather than HTML frag-
ports XML by giving us the responseXML property, but parsing ments, you’ll want to refactor to some extent.
this using the DOM is hard work.
dumb client thin client thick client
<item imgSrc=”kmoon.png” function parseResponse(xhr){
price=”365.00”> var xmlDoc=xhr.responseXML;
browser browser browser
<title>The Moon on a var item=xmlDoc.getElementsByTagName
Stick</title> (‘item’)[0]; display display display
<description><![CDATA[What var imgSrc=item.getAttribute
presentation presentation
every project manager wants - (‘imgSrc’);
and they want it var title=item.getElementsByTagName business objects
yesterday!<br/><br/><i>NB: Stick (‘title’)[0]
data transfer
not .firstChild.data;
included.</i>]]></description> setImgSrc(imgSrc);
</item> setTitle(title);
} presentation
presentation data transfer
business objects business objects business objects
Some browsers also support XPath as a more pleasant way to
parse XML. Sarissa and mozXPath.js both provide cross-browser
XPath support.
persistence persistence persistence
Toolkits and frameworks will make your life easier in Client-side versus Server-side
several ways: Some toolkits are JavaScript-only, others include a back-end
Providing tried-and-tested solutions to common
n system too. Client-side toolkits will give more flexibility, but may
problems require more work on the server-side too.
Abstracting away cross-browser incompatibilities and
n
High-level versus Low-level
annoyances JavaScript is a flexible language, and some toolkits are geared
Providing higher level abstractions such as ready-made
n
towards enhancing the language itself in a variety of ways. Oth-
UI widgets and networking stacks ers are more concerned with higher-level issues such as simplify-
However, it’s a jungle out there, with many different types of ing XHR, or providing drop-in widgets such as trees, tables and
toolkits on the market. Let’s divide them into broad families. drag-and-drop.
Some popular Ajax Toolkits Loading HTML Content into a DOM Node
Name Client/ High/ Comments Prototype jQuery
Server Low-level
new Ajax.Updater( $(“#myDomNode”).load(
Prototype Client Low Remodels and extends $(“myDomNode”), “my-dynamic-content.jsp”,
“my-dynamic-content.jsp”, { id: myId }
(http://prototypejs.org) JavaScript following the Ruby
{ method: “post”, );
scripting language. Many
params: { id: myId }
features for arrays, functions, }
XHR, DOM and forms. );
Scriptaculous Client High Special effects, drag and
(http://script.aculo.us) drop, and widgets built on
n
No need to provide a callback function at all
top of prototype.
Working wth JSON Responses
dojo Client Low-high Comprehensive set of
(http://dojotoolkit.org) libraries covering everything Prototype jQuery
from packaging & language
features through Ajax to UI new Ajax.Request( $.getJSON(
“my-dynamic-content.jsp”, “my-dynamic-content.jsp?id=”+myId,
widgets.
{ method: “post”, function(json){
Yahoo User Interface (YUI) Client Low-high Another comprehensive set params: { id: myId }, alert(json.someProperty);
(http://developer.yahoo.com/ of libraries covering many onComplete: }
yui/) aspects of Ajax development. function(response,json){ );
alert(json.someProperty);
Ext Client High Widget-based set of user }
(http://extjs.com) interface components with }
Ajax support. );
Ruby on Rails Server Low-high Primarily a server-side toolkit, Think of Javascript objects as associative arrays.
(http://www.rubyonrails.org) but has first-rate support
for Ajax, using Prototype
n
Functions are first-class objects, and can be passed as
and Scriptaculous. Allows arguments into other functions (see the numerous callback
large parts of the client tier functions earlier).
to be written on the server,
in Ruby. n
JavaScript functions support closures. That is, variables that
GWT Client High Java framework that allows are in scope when a function is defined can still be referenced
(http://code.google.com/ Ajax client tier to be written inside the function, even if it is invoked later.
webtoolkit) in Java.
may need to locate becomes tedious, and clutters the markup. Tag element. n/a n/a use the browser’s built-in HTML
names, on the other hand, are not specific enough to be useful in innerHTML parser to shortcut the creation
many cases. The most common solution is to use CSS classes to lo- of new content
cate elements. We can make these as specific or general as we need. element. DOM null add a DOM node as child of
appendChild() element another node
Finding DOM elements using Prototype element. DOM null remove a child DOM node from
removeChild() element the parent
Function arguments returns notes
element. DOM null add a DOM node in relation to
$() string, DOM powerful and
insertBefore() element other siblings, not just at the end
many element, concise superset of
strings, or or array of getElementById()
elements elements Modifying the DOM with Prototype
document. string (a array of version 1.5+ Prototype favors the use of innerHTML to modify the DOM. It
getElementsByClassName() CSS class) DOM simple analogue to enhances this with the Insertion namespace, and, more recently,
element. elements getElementsByTagName()
getElementsByClassName() an insert method on the DOM element class itself.
$$() string array of version 1.5+
Function arguments notes
(selector DOM accepts CSS selector
rule) elements rules, and xpath queries
Insertion.Top DOM element, version 1.5: Object that inserts
element.select() string array of version 1.6 Insertion.Bottom string (HTML content) HTML content into element
(selector DOM analogue to $$(), Insertion.Before alongside existing content.
rule) elements syntactically neater Insertion.After
element.up() selector DOM powerful positional Element.update() string (HTML content) version 1.6: overwrites content in
element.down() rules, Element navigation methods, element
counts that can work with
element.next()
(both selectors Element.insert() HTML content or hash version 1.6: Can insert a single
element.previous() optional) of content piece of content, or multiple
pieces in one go
Examples
Element.remove() none all versions: removes the calling
$(“myList”) selects the element with id=myList element (and its children) from
.select (“li.new”) selects all DOM elements of type the page
<LI> with CSS class new within
subtree beneath myList Prototype provides no support for building DOM elements
$(“widget”) selects element with id=”widget” programmatically, but the Scriptaculous library adds a DOMBuilder
.down(“img div.handle”,2) internally returns list of all <IMG> object to the mix.
tags that are children of a DIV with
CSS class handle, and returns the Modifying the DOM with jQuery
second one jQuery is based around selecting sets of DOM elements, and it
provides methods for manipulating sets of DOM elements in bulk.
Finding DOM elements using jQuery (These can be used on sets of one element too!) The methods here
Function arguments returns notes all operate on a set of DOM nodes returned from a selector.
$() string jQuery although only one method is listed here,
(selector object jQuery is exceptionally powerful in this Function arguments notes
rule) wrapping regard. The selector rules encompass CSS3, $.html() string (HTML simple wrapper around innerHTML, will
array of xpath (optional) and a range of custom content) duplicate content for each element in the set
elements selectors too!
$.append() string (HTML insert content into node(s) alongside existing
Examples $.prepend() content) content
$.before()
$(“div”) select all nodes by tag type $.after()
$(“#myList”) select by unique id
$.appendTo() string argument is the target element or elements,
$(“ul#myList li.new”) complex CSS selector $.prependTo() (selector rule) to which the current node will be moved to. If
$.insertBefore() or DOM multiple targets are present, the nodes being
$.insertAfter() element appended will be copied to each one
DOM elements can be assigned to multiple CSS classes. $.remove() none remove all elements in set from the page
Hot When finding elements using a selector mechanism, you
Tip $.empty() none empty all elements in the set of their content
may use the same CSS classes that determine the look of $.wrap() string (HTML) or wrap each element in set individually with a
your page, or you may assign separate marker classes, DOM element copy of the content provided in argument
i.e. CSS classes that have no visual effect on the page. $.wrapAll() string (HTML) or wrap all elements in the set as a single unit with
DOM element the content provided in argument
tive approach to developing Ajax UIs, much more akin to desktop Fiddler IE/any www.fiddlertool.com Powerful network monitor with
programmable interface for
application development, in which the DOM elements are created modifying requests in many
programmatically by javascript components, which the designer ways. Tight integration with IE,
but can work with any browser.
then wires together using layouts and containers. Qooxdoo and
LiveHTTP FF livehttpheaders.mozdev.org Network monitor extension for
Ext2 are both examples of this style of UI development. Headers Firefox.
DZone, Inc.
ISBN-13: 978-1-934238-02-8
1251 NW Maynard
ISBN-10: 1-934238-02-3
Cary, NC 27513
50795
888.678.0399
DZone communities deliver over 4 million pages each month to
919.678.0300
more than 1.7 million software developers, architects and decision
Refcardz Feedback Welcome
makers. DZone offers something for everyone, including news, refcardz@dzone.com
$7.95
tutorials, cheatsheets, blogs, feature articles, source code and more. Sponsorship Opportunities 9 781934 238028
“DZone is a developer’s dream,” says PC Magazine. sales@dzone.com
Copyright © 2008 DZone, Inc. All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by means electronic, Version 1.1
mechanical, photocopying, or otherwise, without prior written permission of the publisher.