asynchronous JavaScript and XML
HTML and CSS for pages
DOM accesed with JavaSctript to show the page content dynamically
XMLHttpRequest (XHR) is a DOM api to send and receive http requests, responces or <iframe></iframe> to place another HTML in a frame or <script></script> just JavaScript.
XML, preformated HTML, plain text, JavaScript Object Notation (JSON – lightweight text based data interchange format {'name':'John','address':{'street':'Wall Street'},'phone':'01454545'})
JavaScripts: ajax1.js, cart.js
var lastCartUpdate = 0;
/*
* Adds the specified item to the shopping cart, via Ajax call
* itemCode - product code of the item to add
*/
function addToCart(itemCode) {
var req = new XMLHttpRequest();
req.onreadystatechange = getReadyStateHandler(req, updateCart);
req.open("POST", "cart.do", true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
req.send("action=add&item="+itemCode);
}
/*
* Update shopping-cart area of page to reflect contents of cart
* described in XML document.
*/
function updateCart(cartXML) {
var cart = cartXML.getElementsByTagName("cart")[0];
var generated = cart.getAttribute("generated");
if (generated > lastCartUpdate) {
lastCartUpdate = generated;
var contents = document.getElementById("contents");
contents.innerHTML = "";
var items = cart.getElementsByTagName("item");
for (var I = 0 ; I < items.length ; I++) {
var item = items[I];
var name = item.getElementsByTagName("name")[0].firstChild.nodeValue;
var quantity = item.getElementsByTagName("quantity")[0].firstChild.nodeValue;
var listItem = document.createElement("li");
listItem.appendChild(document.createTextNode(name+" x "+quantity));
contents.appendChild(listItem);
}
}
document.getElementById("total").innerHTML = cart.getAttribute("total");
}
/*
* Returns a function that waits for the specified XMLHttpRequest
* to complete, then passes it XML response to the given handler function.
* req - The XMLHttpRequest whose state is changing
* responseXmlHandler - Function to pass the XML response to
*/
function getReadyStateHandler(req, responseXmlHandler) {
// Return an anonymous function that listens to the XMLHttpRequest instance
return function () {
// If the request's status is "complete"
if (req.readyState == 4) {
// Check that we received a successful response from the server
if (req.status == 200) {
// Pass the XML payload of the response to the handler function.
responseXmlHandler(req.responseXML);
} else {
// An HTTP problem has occurred
alert("HTTP error "+req.status+": "+req.statusText);
}
}
}
}
index.jsp
<%@ page import="java.util.*" %>
<%@ page import="developerworks.ajax.store.*" %>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" language="javascript" src="ajax1.js"></script>
<script type="text/javascript" language="javascript" src="cart.js"></script>
</head>
<body>
<div style="float: left; width: 500px">
<h2>Catalog</h2>
<table border="1">
<thead><th>Name</th><th>Description</th><th>Price</th><th></th></thead>
<tbody>
<%
for (Iterator<Item> I = new Catalog().getAllItems().iterator() ; I.hasNext() ; ) {
Item item = I.next();
%>
<tr><td><%= item.getName() %></td><td><%= item.getDescription() %></td><td><%= item.getFormattedPrice() %></td><td><button onclick="addToCart('<%= item.getCode() %>')">Add to Cart</button></td></tr>
<% } %>
</tbody>
</table>
<div style="position: absolute; top: 0px; right: 0px; width: 250px">
<h2>Cart Contents</h2>
<ul id="contents">
</ul>
Total cost: <span id="total">$0.00</span>
</div>
</body>
</html>
CartServlet.java
public class CartServlet extends HttpServlet {
/**
* Updates Cart, and outputs XML representation of contents
*/
public void doPost(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException {
Enumeration headers = req.getHeaderNames();
while (headers.hasMoreElements()) {
String header =(String) headers.nextElement();
System.out.println(header+": "+req.getHeader(header));
}
Cart cart = getCartFromSession(req);
String action = req.getParameter("action");
String item = req.getParameter("item");
if ((action != null)&&(item != null)) {
if ("add".equals(action)) {
cart.addItem(item);
} else if ("remove".equals(action)) {
cart.removeItems(item);
}
}
String cartXml = cart.toXml();
res.setContentType("text/xml");
res.getWriter().write(cartXml);
}
public void doGet(HttpServletRequest req, HttpServletResponse res) throws java.io.IOException {
// Bounce to post, for debugging use
// Hit this servlet directly from the browser to see XML
doPost(req,res);
}
private Cart getCartFromSession(HttpServletRequest req) {
HttpSession session = req.getSession(true);
Cart cart = (Cart)session.getAttribute("cart");
if (cart == null) {
cart = new Cart();
session.setAttribute("cart", cart);
}
return cart;
}
}
Item.java
public class Catalog {
private static Map<String,Item> items;
static {
items = new HashMap<String,Item>();
items.put("hat001",new Item("hat001","Hat","Stylish bowler hat (SALE!)",1999));
items.put("dog001",new Item("dog001","Dog","Chocolate labrador puppy",7999));
items.put("sou001",new Item("sou001","Soup","Can of tasty tomato soup",199));
items.put("cha001",new Item("cha001","Chair","Swivelling office chair", 4999));
items.put("str001",new Item("str001","String","Metric tonne of bailing twine", 1999));
items.put("qua001",new Item("qua001","Quark","Everyone's favorite sub-atomic particle", 49));
}
public Collection<Item> getAllItems() {
return items.values();
}
public boolean containsItem(String itemCode) {
return items.containsKey(itemCode);
}
public Item getItem(String itemCode) {
return items.get(itemCode);
}
}