reptile7's JavaScript blog
Monday, April 22, 2013
Living in the Material World
Blog Entry #286

In today's post we will begin an analysis of the e-commerce shopping cart code of HTML Goodies' "So, You Want A Shopping Cart, Huh?" tutorial. Authored by Joe Burns, the "Shopping Cart" tutorial dates to early 1999 and was one of the first tutorials to be offered by HTML Goodies' Beyond HTML : JavaScript sector. The "Shopping Cart" code itself was crafted by Gordon Smith, who deployed it at a now-gone Scottish Gifts site. Gordon's site is still live (sort of) but it doesn't sell anything anymore.

Cart overview

The tutorial shopping cart consists of seven pages: shopcartindex.html, navigate.html, welcome.html, pageone.html, pagetwo.html, pagethree.html, and order.html.

The shopcartindex.html page hosts a two-frame frameset

<frameset cols="25%,*" resize="yes" onload="parent.get_that_cookie( );">
<frame src="navigate.html" name="navigate">
<frame src="welcome.html" name="main">
<noframes>This page requires frames.</noframes>

for displaying the other six pages.

Initially the frameset's right frame holds the welcome.html page, which welcomes the user to the shopping cart.

Throughout the shopping cart process the frameset's left frame holds the navigate.html page, which features a set of links for respectively loading the pageone.html, pagetwo.html, pagethree.html, and order.html pages into the right frame.

The pageone.html, pagetwo.html, and pagethree.html pages detail items for sale and provide controls for adding/subtracting those items to/from the shopping cart. The order.html page tallies up the user's order and provides a form for submitting the order and the user's contact/shipping information.

Frameset/frame notes

In the course of checking whether the frameset element has a resize attribute I discovered that HTML5 is obsoleting the frameset and frame elements. We will exchange the cart's frameset for an alternative structure in due course.

As it happens, the frameset element does not have a resize attribute, but it doesn't really need one - well, at least not one set to yes - in that frames are resizable by default. A frame can be resized by dragging its interframe boundaries or by dragging the viewport's resizing grippy; the frame element does have a boolean noresize attribute that will shut down the former but not the latter. To lock the cols="25%,*" frameset layout, the correct HTML syntax would be:

<frame src="navigate.html" name="navigate" noresize>
<frame src="welcome.html" name="main" noresize>
/* In practice I find it is not necessary to noresize both frames: locking one frame effectively locks the other. */

Cart download

At the tutorial's The Pages section the shopping cart's pages can be downloaded either individually or as a single shopcart/ .zip package. If you're trying this out at home, I strongly encourage you to grab the .zip package because the one-at-a-time pages all contain HTML Goodies site stuff - five meta elements, two script elements, and a noscript element - that is completely unrelated to the shopping cart and shouldn't be there. Moreover, the .zip package contains a PERL script that, unlike the order.html page's mailto: form, will directly email the user's order to you.

The shopping cart demo, then and now

In the tutorial's The Shopping Cart Program section Joe says:
As long as you do not alter the JavaScript programming, the cart should work straightaway.
The .zip package has one little flaw, specifically, it's missing the thisback.gif image that the pageone.html and order.html pages call on for a background, but apart from that its code runs smoothly; ditto for Joe's original tutorial demo.

Here's thisback.gif, which wallpapered most of the pages at the Scottish Gifts site:

The thisback.gif image, whatever it is

At some point in 2011 the aforementioned HTML Goodies site stuff was inserted into each shopping cart demo page as the result of a site overhaul. The meta elements were placed in the document head for all seven pages - so far, so normal - but for some strange reason the meta element addition also brought the document type declaration into the document head for the welcome.html, pageone.html, pagetwo.html, and pagethree.html pages (the other pages don't have a declaration), for example:

<meta name="WT.qs_dlk" content="UWHpGgrIZ2cAABwmNwIAAAAY"/>
...other four meta elements...

Misplacement of the declaration invalidates the document - without getting into the details, it will throw two errors upon running the document through the W3C's markup validator - but it doesn't prevent the browser from rendering the document body normally.

For their part, the script elements and the noscript element were harmlessly* placed at the end of the document body - i.e., just before the </body> tag - for the six frame pages but were prepended to the </body>-holding value of a global en_astr variable at the shopcartindex.html frameset page:

var en_astr = '<script language="JavaScript" type="text/javascript">
    var gDomain = "";
    <script type="text/javascript" src="/imageserver/common/webtrends.js"></script>
    <noscript> ... </noscript>

As I trust y'all know, JavaScript string literals cannot contain (unescaped) line breaks, and the line break that separates the first and second lines of the above en_astr declaration promptly throws an 'unterminated string literal' syntax error; this error has a propagative effect in that it prevents
(a) the retrieval of any cookies associated with the shopping cart,
(b) the addition/subtraction of items to/from the cart, and
(c) the loading of the order.html page into the right frame.
Commenting out the en_astr declaration (en_astr plays a small role in a not-called display_pic( ) function) solves these problems.

*At the HTML Goodies site the script elements import wtid.js and webtrends.js scripts; on my desktop the unavailability of these scripts throws 'failed to load resource' errors with some browsers but does not affect the operation of the cart.

You can go through the one-at-a-time pages and clean them up if you want, but again, you won't have to do this if you download the .zip package.

State of the order

In the tutorial's How Does This Shopping Cart Work? section Joe claims that cookies are used to store the information somewhere as the viewer moves from page to page. In actual fact, the user's running order is stored in an itemlist collection of custom JavaScript objects; it is moved from page to page via the frames and parent properties of the window object. The cart's cookie machinery can be used to remember the user's contact information upon leaving the order.html page but it has no connection with the item part of the cart.

We'll start deconstructing the shopping cart code in earnest in the following entry.

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)