<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>Browse Book Inventory</TITLE>
<LINK rel="stylesheet" type="text/css" href="global.css">
<STYLE>
.userData { behavior: url(#default#userData) }
</STYLE>
<SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript>
<!--
function AddToShoppingCart(isbn)
{
if (window.confirm("Are you sure you wish to add ISBN #" + isbn +
" to your shopping cart?"))
{
var pattern = "//Book[@ISBN='" + isbn + "']";
var oNode = divInventory.XMLDocument.selectSingleNode(pattern);
// if the book is already in the shopping cart, increment the number
// of copies to purchase
if (oNode)
{
numCopies = new Number(oNode.getAttribute("NumberOfCopies"));
oNode.setAttribute("NumberOfCopies", numCopies + 1);
}
else
{
// clone the selected node, add the NumberOfCopies attribute,
// add to cart
oNode = xmlBookInventory.selectSingleNode(pattern);
var oClone = oNode.cloneNode(true);
oClone.setAttribute("NumberOfCopies", 1);
divInventory.XMLDocument.documentElement.appendChild(oClone);
}
// save the shopping cart to disk
divInventory.save("ShoppingCart");
}
}
function window_onload() {
// load the shopping cart from disk
divInventory.load("ShoppingCart");
// transform the XML inventory to HTML
divInventory.innerHTML =
xmlBookInventory.transformNode(xslBookInventory.documentElement);
}
//-->
</SCRIPT>
</HEAD>
<BODY LANGUAGE=javascript onload="return window_onload()">
<!-- XML files for book inventory & transform -->
<XML ID=xmlBookInventory SRC="books.xml"></XML>
<XML ID=xslBookInventory SRC="books.xsl"></XML>
<H1>Browse Book Inventory</H1>
<DIV class=header>
<A HREF="default.htm">[Home]</A>
<A HREF="shopping-cart.htm">[View Shopping Cart]</A>
<A HREF="browse-inventory.htm">[Browse Book Inventory]</A>
</DIV>
<HR>
<DIV CLASS=userData ID=divInventory></DIV>
<HR>
<DIV CLASS=footer>
© Copyright 1999, Microsoft Interactive Developer and Aaron Skonnard
<A HREF="http://www.skonnard.com">http://www.skonnard.com</A>
</DIV>
</BODY>
</HTML>
Figure 5 Shopping-cart.htm
<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0">
<TITLE>View Shopping Cart</TITLE>
<LINK rel="stylesheet" type="text/css" href="global.css">
<STYLE>
.userData { behavior: url(#default#userData) }
</STYLE>
<SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript>
<!--
function updateTotal() {
// get all price nodes
var books = divShoppingCart.XMLDocument.selectNodes("//Book");
var total = 0.0;
// calculate the total price of the order
for (i=0; i<books.length; i++)
{
var bookNode = books[i];
copies = new Number(bookNode.getAttribute("NumberOfCopies"));
var priceNode = bookNode.selectSingleNode("Price");
price = new Number(priceNode.getAttribute("Retail"));
total += copies*price;
}
// update the total DIV element
spanTotal.innerHTML = "Total Price: $" + total;
}
function deleteItem(isbn)
{
if (window.confirm("Are you sure you wish to delete ISBN #" + isbn +
" from your shopping cart?"))
{
// get the node reference and delete
var pattern = "//Book[@ISBN='" + isbn + "']";
var oNode = divShoppingCart.XMLDocument.selectSingleNode(pattern);
oNode.parentNode.removeChild(oNode);
// save the shopping cart to disk
divShoppingCart.save("ShoppingCart");
refresh();
}
}
function refresh() {
// update all UI
divShoppingCart.innerHTML =
divShoppingCart.XMLDocument.transformNode(xslShoppingCart.documentElement);
updateTotal();
}
function window_onload() {
// load the shopping cart from disk
divShoppingCart.load("ShoppingCart");
refresh();
}
function checkout() {
// post the shopping cart data to the web server
var xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
xmlRequest.open("POST", "checkout.asp", false, null, null);
xmlRequest.send(divShoppingCart.XMLDocument);
// update HTML with response data
divShoppingCart.innerHTML = xmlRequest.responseText;
divTotal.innerHTML = spanTotal.innerHTML;
// clear shopping cart
divShoppingCart.XMLDocument.removeChild(divShoppingCart.XMLDocument.documentElement);
divShoppingCart.save("ShoppingCart");
}
//-->
</SCRIPT>
</HEAD>
<BODY LANGUAGE=javascript onload="return window_onload()">
<!-- XSL file for shopping cart transform -->
<XML ID=xslShoppingCart SRC="shopping-cart.xsl"></XML>
<H1>View Shopping Cart</H1>
<DIV class=header>
<A HREF="default.htm">[Home]</A>
<A HREF="shopping-cart.htm">[View Shopping Cart]</A>
<A HREF="browse-inventory.htm">[Browse Book Inventory]</A>
</DIV>
<HR>
<DIV CLASS=userData ID=divShoppingCart></DIV>
<HR>
<DIV ID=divTotal CLASS=total><SPAN ID=spanTotal></SPAN>
<A HREF="javascript:checkout()">Purchase All Items</A></DIV>
<HR>
<DIV CLASS=footer>
© Copyright 1999, Microsoft Internet Developer and Aaron Skonnard
<A HREF="http://www.skonnard.com">http://www.skonnard.com</A>
</DIV>
</BODY>
</HTML>
Figure 6 Checkout.asp
<%@ Language=VBScript %>
<%
set xmlRequest = Server.CreateObject("MSXML.DOMDocument")
if (xmlRequest.load(Request)) then
set xslResults = Server.CreateObject("MSXML.DOMDocument")
xslPath = Server.MapPath("results.xsl")
if (xslResults.load(xslPath)) then
Response.Write xmlRequest.transformNode(xslResults.documentElement)
else
Response.Write "<H2>Error processing shopping cart</H2>"
end if
else
Response.Write "<H2>Error processing shopping cart</H2>"
end if
%>
Figure 7 Persistence Behaviors
Behavior |
Description |
saveFavorite |
Persists an object across sessions when the page has been saved as a favorite. This behavior is ideal for persisting user-selected styles within a favorite or shortcut. The persisted information is stored within each favorite, allowing multiple favorites with different persisted information to exist. |
saveHistory |
Persists an object in memory during the current session. Ideal for storing information only while the browser is open, such as page state for collapsible content or dynamic styles. |
saveSnapshot |
Persists an object across sessions when a page has been saved as Web Page, HTML Only. Form elements will persist automatically. Script blocks that contain only variables can also persist. The saveSnapshot behavior is ideal for persisting Web application information to the client's disk for later retrieval. |
userData |
Persists an object across sessions in a userData store (an arbitrary storage facility) when the object has been explicitly saved. Ideal for persisting information across sessions and storing information in a hierarchical structure. It provides a good alternative to using cookies. The capacity of the userData store is 64KB per page, with a limit of 640KB per domain. For security reasons, a userData store is available only in the same directory and with the same protocol used to persist the store. |
Figure 8 Behavior Members
Member |
Description |
getAttribute |
Retrieves the value of the specified attribute. |
onload |
Fires from a persistent element when the page is reloaded. |
onsave |
Fires from a persisted element when the Web page is saved or bookmarked, or when the user navigates away from the page. |
removeAttribute |
Removes the given attribute from the object. |
setAttribute |
Sets the value of the specified attribute. If the attribute is not already present, the method adds the attribute to the object and sets the value. |
XMLDocument |
Returns a reference to the XML Document Object Model (DOM) exposed by the object. |
Figure 9 SaveFavorite Implementation
<HTML>
<HEAD>
<META NAME="save" CONTENT="favorite">
<STYLE>
.saveFavorite {behavior:url(#default#saveFavorite);}
</STYLE>
<SCRIPT>
function fnSaveInput(){
oPersist.setAttribute("myValue",oPersist.value);
}
function fnLoadInput(){
oPersist.value=oPersist.getAttribute("myValue");
}
</SCRIPT>
</HEAD>
<BODY>
<INPUT class=saveFavorite onsave="fnSaveInput()"
onload="fnLoadInput()" type=text id=oPersist>
</BODY>
</HTML>
Figure 10 Using XMLDocument
<HTML>
<HEAD>
<META NAME="save" CONTENT="history">
<STYLE>
.saveHistory {behavior:url(#default#savehistory);}
</STYLE>
<SCRIPT>
function fnSave(){
var oXMLDoc=oPersistObject.XMLDocument;
var oNode=oXMLDoc.createNode(1,"Book", "");
oNode.setAttribute("Title", "Essential WinInet");
oNode.setAttribute("NumberOfCopies", "1");
oNode.setAttribute("ISBN", "0201379368");
oXMLDoc.documentElement.appendChild(oNode);
var oChild=oXMLDoc.createNode(1,"Author", "");
oChild.text="Aaron Skonnard";
oChild.setAttribute("authid", "aarons");
oNode.appendChild(oChild);
// add more child elements, more attributes, etc...
}
function fnLoad(){
var oXMLDoc=oPersistObject.XMLDocument;
var oItem=oXMLDoc.documentElement.childNodes.item(1);
var numberOfCopies = oItem.getAttribute("NumberOfCopies");
var isbn = oItem.getAttribute("ISBN");
// do something with the data...
}
</SCRIPT>
</HEAD>
<BODY>
<A HREF="navigate-away.htm">
Leave The Page
</A>
<DIV ID="oPersist" CLASS="saveHistory" ONSAVE="fnSave()"
ONLOAD="fnLoad()">
</DIV>
</BODY>
</HTML>
Figure 11 userData Members
Member |
Description |
expires |
Sets or retrieves the expiration date of data persisted with the userData behavior. |
getAttribute |
Retrieves the value of the specified attribute. |
load |
Loads an object participating in userData persistence from a userData store. |
removeAttribute |
Removes the given attribute from the object. |
save |
Saves an object participating in userData persistence to a userData store. |
setAttribute |
Sets the value of the specified attribute. If the attribute is not already present, the method adds the attribute to the object and sets the value. |
XMLDocument |
Returns a reference to the XML Document Object Model (DOM) exposed by the object. |
Figure 12 Shopping Cart Data
<ROOTSTUB>
<Book ISBN="0201379368" NumberOfCopies="3">
<Title>
<Main>Essential WinInet</Main>
<Sub>Developing Applications Using the Windows Internet API With RAS,
ISAPI, ASP, and COM</Sub>
</Title>
<Quotes>
<Quote From="Richard Firth">If you are developing Internet-enabled applications
using Internet Explorer components, you need this book.</Quote>
</Quotes>
<Authors>
<Author ID="aarons" Name="Aaron Skonnard"/>
</Authors>
<Price Retail="44.00" Wholesale="24.95"/>
<Abstract>A guide to Microsoft's software package designed to simplify the
process of creating Internet-enabled applications using its Windows platform.
Describes the basics, the protocol-specific functions for Internet tasks, and
more advanced topics such as other Internet tools and client/server
technologies.</Abstract>
</Book>
<Book ISBN="0201634465" NumberOfCopies="2">
<Title>
<Main>Essential COM</Main>
<Sub>The Addison-Wesley Object Technology Series</Sub>
</Title>
<Quotes>
<Quote From="Charlie Kindel">Nobody explains COM better than Don Box.</Quote>
</Quotes>
<Authors>
<Author ID="dbox" Name="Don Box"/>
</Authors>
<Price Retail="37.00" Wholesale="20.95"/>
<Abstract>Endorsed by object-orientation guru Grady Booch and Microsoft
COM expert Charlie Kindel, Box's book takes the reader from an elucidating
discussion of why a demand exists for COM and how it fits into the progression
of C++ technology to a cool exhibition of some COM programs he's written. Along
the way, Box covers the four corners of COM interfaces, classes, apartments, and
security--all explained in developer's detail.</Abstract>
</Book>
</ROOTSTUB>