reptile7's JavaScript blog
Monday, May 27, 2013
Subtract, Other Items, Update
Blog Entry #290

In the previous post we went through the mechanics of adding the pageone.html item to the "So, You Want A Shopping Cart, Huh?" shopping cart. Now, what if we change our minds and decide that we don't want the pageone.html item after all?

Subtract it

(The pageone.html Loc_additem( ) function, the shopcartindex.html check_if_in( ) function, the shopcartindex.html additem( ) function, the shopcartindex.html remove_nil_items( ) function, the pageone.html write_to_field( ) function, and the shopcartindex.html item_quan( ) function were detailed in the previous post.)

Just below the pageone.html button is a button

<input type="button" name="subbox" value="Subtract This Item From My Total"
onclick="Loc_subitem('p1i1', '1.11', 'page_1_item_1', 'pageone.html');">

for subtracting the pageone.html item from the shopping cart. Clicking the button calls the pageone.html Loc_subitem( ) function and passes it the same four strings that the button passes to the Loc_additem( ) function. Here's the Loc_subitem( ) function:

function Loc_subitem(code, price, desc) {
    self.parent.subitem(code, price, desc);
    write_to_field(code); }

The p1i1 argument is given a code identifier; the 1.11 argument is given a price identifier; the page_1_item_1 argument (sic, it begins with a capital letter when passed to the Loc_additem( ) function) is given a desc identifier; the pageone.html argument isn't given an identifier at all. The Loc_subitem( ) function first calls the shopcartindex.html subitem( ) function and passes it the code, price, and desc arguments; the pageone.html argument does not tag along but is left behind. Here's the subitem( ) function:

function subitem(codes, prices, descrip, url) {
    loc = check_if_in(codes);
    if ((loc != -1) && (itemlist[loc].quan > 0)) { // Update existing item
        olditem = itemlist[loc].quan;
        itemlist[loc] = new product(codes, prices, descrip, olditem - 1, url); } }

(1) The p1i1, 1.11, and page_1_item_1 arguments are respectively given codes, prices, and descrip identifiers by the subitem( ) function. The url subitem( ) parameter evaluates to undefined.

(2) The check_if_in( ) function is called and passed the codes argument. The check_if_in( ) if clause is operative: loc = 1 is returned to the subitem( ) function.

(3) Back at the subitem( ) function, the (loc != -1) && (itemlist[loc].quan > 0) if condition returns true, and therefore:
(a) itemlist[1].quan, 1, is assigned to an olditem variable;
(b) the itemlist[1] product( ) object is replaced by a new product( ) object with the same code (p1i1) and price (1.11) values but whose desc, quan, and url values are now page_1_item_1, 0 (olditem - 1), and undefined, respectively.

Unlike the corresponding additem( ) function, the subitem( ) function does not call the remove_nil_items( ) function nor does it adjust the item_num and items_ordered variables.

"Creating a new product( ) object shouldn't be necessary here: decrementing the itemlist[1].quan value is all we really need to do." You're right about that, but we actually don't need to create a new product( ) object in the additem( ) function either; we will revamp the additem( ) and subitem( ) functionality in due course.

The Loc_subitem( ) function next calls the write_to_field( ) function and passes it the code argument. The write_to_field( ) function locates the p1i1 quantifier field in the form1 form

You Have Ordered This Many Of This Item:<input type="text" name="p1i1" size="2">

and then calls the item_quan( ) function and passes it the code argument. The item_quan( ) function gets itemlist[1].quan, now 0, and returns it to the write_to_field( ) function, which finally assigns the item_quan( ) return to the value of the p1i1 field.


The pagetwo.html and pagethree.html item pages are variations on the pageone.html page.

• The pagetwo.html and pagethree.html pages each offer three items for sale: the pagetwo.html items are respectively priced at $2.22, $3.33, and $4.44; the pagethree.html items are respectively priced at $5.55, $6.66, and $7.77.

• Each pagetwo.html/pagethree.html item has its own Loc_additem( )-triggering button, Loc_subitem( )-triggering button, and You Have Ordered This Many: quantifier field.

• Each pagetwo.html/pagethree.html item has an identifier and description analogous to that of the pageone.html item, for example, the identifier and description for the first ($5.55) pagethree.html item are p3i1 and Page_3_Item_1, respectively; each item's identifier matches the name of the item's quantifier field.

Like pageone.html, pagetwo.html and pagethree.html each sport a Review updated Order Form link for loading the order.html page into the right frame of the shopcartindex.html frameset. (Each page actually sports two such links, one at the top of the page and one at the bottom of the page.)

The update_this_page( ) function

The pagetwo.html/pagethree.html document heads hold a script element with write_to_field( ), Loc_additem( ), and Loc_subitem( ) functions: these are the same functions that appear in the pageone.html document head. The script element also contains an update_thiselem_page( ) function that is called when the pagetwo.html or pagethree.html page loads.

<body bgcolor="white" alink="red" onload="update_thiselem_page( );">

The update_thiselem_page( ) function calls the shopcartindex.html update_this_page( ) function if the pagetwo.html/pagethree.html window has a frameset parent.

function update_thiselem_page( ) { if (self != parent) parent.update_this_page( ); }

Suppose we go to pagetwo.html by clicking the navigate.html Order Page Two link. At pagetwo.html we add, in order, one p2i2 ($3.33) item and one p2i3 ($4.44) item to the shopping cart. Next, we go to pagethree.html by clicking the navigate.html Order Page Three link. We decide we don't want anything at pagethree.html and go back to pagetwo.html to review our cart selections.

The update_this_page( ) function doesn't do anything for our initial visit to pagetwo.html (see the Before getting started section of the previous post) but it does load a 1 into the p2i2 and p2i3 quantifier fields for our return visit. Here's the complete update_this_page( ) function:

function update_this_page( ) {
    var i = 0, k = 0;
    for (i = 0; i < parent.main.document.form1.elements.length; i++) {
        for (k = 1; k <= items_ordered; k++) {
            if ((itemlist[k].code == parent.main.document.form1.elements[i].name) &&
            (k <= items_ordered) && (i <= parent.main.document.form1.elements.length))
                parent.main.document.form1.elements[i].value = itemlist[k].quan; } } }

The outer for loop iterates over the inputs of the form1 form. The inner for loop iterates over the items of our order string, which can be expressed in terms of object literals as follows:

itemlist[1] = {code: "p2i2", price: "3.33", desc: "Page_2_Item_2", quan: 1, url: "pagetwo.html"}
itemlist[2] = {code: "p2i3", price: "4.44", desc: "Page_2_Item_3", quan: 1, url: "pagetwo.html"}

The outer loop runs for nine iterations; for each outer loop iteration, the inner loop runs for two iterations as (per the number of shopping cart items) items_ordered is 2.*
(1) In the sixth iteration of the outer loop and the first iteration of the inner loop, the p2i2 input name matches itemlist[1].code and therefore 1 (itemlist[1].quan) is written to the p2i2 field.
(2) In the ninth iteration of the outer loop and the second iteration of the inner loop, the p2i3 input name matches itemlist[2].code and therefore 1 (itemlist[2].quan) is written to the p2i3 field.

parent.main accesses the name="main" frame object; window.frames["main"] is my preferred way to reference this object, but to each his own.

• The second and third subconditions of the if clause of the inner loop are redundant and can be thrown out: k <= items_ordered is already deployed as the condition of the inner loop and i <= parent.main.document.form1.elements.length is already deployed as the condition of the outer loop. (OK, there's a slight operator difference in the latter case, but the two comparisons are equivalent in the present context.)

*A parallel set of update_this_page( ) loop iterations runs at the beginning of our pagethree.html visit, but no name/code matches are found and consequently nothing happens.

The pageone.html page does not call the update_thiselem_page( ) function; instead, it unconditionally calls the update_this_page( ) function directly when it loads, which would throw a parent.update_this_page is not a function error if pageone.html were accessed outside of the shopcartindex.html frameset.

We will put forward an alternate structure and corresponding update_this_page( ) function for the item pages (e.g., note that the quantifier field values can be changed without clicking the Add/Subtract buttons, not good) at a later point. For now, however, we will move on to the shopping cart's order.html page. Some of the order.html page pertains to the running order part of the cart and some of it pertains to the customer/shipping part of the cart; we'll take on the running order part in the following entry.

Sunday, May 19, 2013
There's Action in Addition
Blog Entry #289

Let's get back now to the pageone.html page of the e-commerce shopping cart offered by HTML Goodies' "So, You Want A Shopping Cart, Huh?" tutorial. In today's post, we'll go behind the scenes and see what happens when the user adds the pageone.html item to the shopping cart by clicking the button on the pageone.html page.

Joe addresses the pageone.html form control HTML in the Altering pageone.html section of the tutorial but doesn't say anything about the JavaScript associated with that HTML - that's where we come in.

Before getting started

Loading the pageone.html page calls the update_this_page( ) function in the shopcartindex.html script element.

<body ... onload="parent.update_this_page( );"> ... </body>

We don't have anything to update and consequently the update_this_page( ) function

function update_this_page( ) {
    for (var i = 0; i < parent.main.document.form1.elements.length; i++) {
        for (var k = 1; k <= items_ordered; k++) { ... } ... } ... }

doesn't do anything at this point. The items_ordered variable was initialized to 0, and is still 0; as a result, the k <= items_ordered condition of the inner for loop returns false from the get-go ⇒ nothing happens. We'll discuss the update_this_page( ) function in more detail later when we have some actual updating to do.

A new product( )

The pageone.html document head holds a script element comprising three functions: write_to_field( ), Loc_additem( ), and Loc_subitem( ). Clicking the button calls the Loc_additem( ) function and passes it four strings: p1i1, 1.11, Page_1_item_1, and pageone.html.

<form name="form1"> ... <center>
<font color="blue">One Item On This Page</font> ...
<input type="button" name="addbox" value="Add This Item To My Total" onclick="Loc_additem('p1i1', '1.11', 'Page_1_item_1', 'pageone.html');"> ...
<input type="button" name="subbox" value="Subtract This Item From My Total" onclick="Loc_subitem('p1i1', '1.11', 'page_1_item_1', 'pageone.html');"> ...
You Have Ordered This Many Of This Item:<input type="text" name="p1i1" size="2"> ...

The Loc_additem( ) arguments are given code, price, desc, and url identifiers, respectively. The Loc_additem( ) function first calls and passes its arguments to the additem( ) function in the shopcartindex.html script element; the self reference is unnecessary but it doesn't hurt to have it there.

function Loc_additem(code, price, desc, url) {
    self.parent.additem(code, price, desc, url);
    write_to_field(code); }

The additem( ) arguments are given codes, prices, descrip, and url identifiers, respectively.

function additem(codes, prices, descrip, url) { ... }

The additem( ) function first calls the shopcartindex.html check_if_in( ) function and passes it the codes argument.

loc = check_if_in(codes);

Here's the check_if_in( ) function:

function check_if_in(code_check) {
    var i = 1; loc = 0;
    while ((i < item_num) && (itemlist[i].code != code_check)) i = i + 1;
    if (itemlist[i].code == code_check) loc = i;
    else loc = -1;
    return loc; }

The check_if_in( ) function closely parallels the indexOf( ) method of the String object. The check_if_in( ) function runs through the itemlist members of the user's order string to see if the code value of any of those members matches the codes/code_check argument: if a match is found, then check_if_in( ) returns the 'index' of the relevant itemlist member; if no match is found, then check_if_in( ) returns -1.

At the present time:
• The item_num variable was initialized to 1, and is still 1. The check_if_in( ) while loop doesn't run for any iterations because its i < item_num subcondition returns false from the get-go.
itemlist[1].code was initially set to an empty string; itemlist[1].code and code_check (p1i1) are not equal and therefore the check_if_in( ) if condition returns false.
• The check_if_in( ) else clause is operative: -1 is assigned to a loc variable, which is subsequently returned to the additem( ) function.

Back at the additem( ) function, the check_if_in( ) check is followed by the following if...else statement:

if (loc != -1) { // Update existing item
    olditem = itemlist[loc].quan;
    itemlist[loc] = new product(codes, prices, descrip, olditem + 1, url); }
else { // New item
    olditem = itemlist[item_num].quan;
    itemlist[item_num] = new product(codes, prices, descrip, olditem + 1, url);
    items_ordered = item_num;
    item_num = item_num + 1; }

As loc is -1, the else clause is operative. The itemlist[1].quan value, initially set to 0, is assigned to an olditem variable. Next, the original itemlist[1] product( ) object is replaced by a new product( ) object whose property values are:
(1) itemlist[1].code = p1i1 (codes);
(2) itemlist[1].price = 1.11 (prices);
(3) itemlist[1].desc = Page_1_item_1 (descrip);
(4) itemlist[1].quan = 1 (olditem + 1);
(5) itemlist[1].url = pageone.html (url).
Lastly, the item_num value (1) is assigned to items_ordered and then item_num is incremented to 2.

The additem( ) function concludes with a call to the shopcartindex.html remove_nil_items( ) function, to which the entire itemlist structure is passed.


Here's the remove_nil_items( ) function:

function remove_nil_items(inputlist) {
    var i = 0, j = 1;
    for (i = 1; i < item_num; i++) {
        if (itemlist[i].quan != 0) {
            temp_array[j] = itemlist[i];
            items_ordered = j;
            j = j + 1; } }
    itemlist = temp_array;
    item_num = items_ordered + 1; }

We'll discuss the remove_nil_items( ) function in more detail later; at this point in our deconstruction, remove_nil_items( ) doesn't actually remove anything, although it does load our new itemlist[1] product( ) object into the temp_array structure, more specifically, its for loop, which runs for one iteration, assigns itemlist[1] to temp_array[1]. When remove_nil_items( ) has finished executing, item_num and items_ordered are still at 2 and 1, respectively.

Quantify it

The pageone.html Loc_additem( ) function next calls the pageone.html write_to_field( ) function and passes it the code argument.

function write_to_field(code) {
    var found = false;
    var i = 0;
    while ((found == false) && (i < document.form1.elements.length)) {
        i = i + 1;
        if (document.form1.elements[i].name == code) {
            found = true;
            document.form1.elements[i].value = parent.item_quan(code); } } }

Beginning with the second-in-source-order form1.elements[1], the write_to_field( ) function's while loop runs through the controls of the form1 form to see if the name of any of those controls matches the code argument. The loop runs for two iterations; in the second iteration document.form1.elements[2].name does equal p1i1, so write_to_field( ) calls the shopcartindex.html item_quan( ) function and passes it the code argument.

function item_quan(code) {
    var loc = check_if_in(code);
    if (loc > 0) var quantities = itemlist[loc].quan;
    else var quantities = 0;
    return quantities; }

The item_quan( ) function first calls the check_if_in( ) function (vide supra) and passes it the code argument. The itemlist[1].code != code_check subcondition of the check_if_in( ) while loop returns false, so control passes to the subsequent if clause. The itemlist[1].code == code_check if condition returns true, and therefore 1 is assigned to loc and returned to the item_quan( ) function.

Back at the item_quan( ) function, the loc > 0 if condition returns true, and therefore itemlist[1].quan, 1, is assigned to a quantities variable, which is returned to the write_to_field( ) function. Back at the write_to_field( ) function, 1 is loaded into the form1.elements[2]/p1i1 text field.

In sum, we have now added the pageone.html item to the shopping cart. Per the properties of the itemlist[1] object:
(1) the item's identifier is p1i1 (itemlist[1].code);
(2) the item's price is $1.11 (itemlist[1].price);
(3) the item's description is Page_1_item_1 (itemlist[1].desc);
(4) quantity-wise we have added 1 item to the cart (itemlist[1].quan); and
(5) we have ordered the item at the pageone.html page (itemlist[1].url).

In the following entry, we'll briefly run through the item subtraction process, take a quick look at the other item pages, and perhaps begin discussing the order.html page.

Friday, May 10, 2013
Welcome to My Menu
Blog Entry #288

We continue today our analysis of the shopping cart code of HTML Goodies' "So, You Want A Shopping Cart, Huh?" tutorial.

So, a user goes to the shopcartindex.html frameset page and is greeted by the welcome.html and navigate.html pages in the frameset's right and left frames, respectively. There's not much to the welcome.html and navigate.html pages, but let's look at them anyway, shall we?


The welcome.html page bears a brief welcome message for the user:
This page is titled welcome.html. It contains no Shopping Cart functions. It simply acts as your welcoming page. The frames page ([shopcart]index.html) contains the majority of the shopping cart commands.
It's true that welcome.html doesn't contain any shopping cart functions, although its document body does begin with a JavaScript snippet

<script language="javascript"><!-- hide
if (self == parent) {
    document.write("<font color='red'><b>THIS IS A FRAME ELEMENT : GO TO <a href='[shopcart]index.htm[l]'>Start Page</a> TO LOAD MAIN PAGE</b></font><br>"); }
<!-- end hide --></script>

that prints out a


warning at the top of the page if the user has somehow landed on the isolated welcome.html page outside of the shopcartindex.html frameset. The above snippet appears at or near the beginning of the document body for all of the other frame pages (navigate.html, pageone.html, pagetwo.html, pagethree.html, and order.html) as well.

(The customary formulation for the script's last line would be // end hide --></script>, and you'd think that the <!-- at the beginning of the line would throw an error, but it doesn't.)

For the welcome.html page of the package, the Start Page warning link points to index.htm and the frames page URL in the welcome message is specified as index.html: index is a hangover of Gordon's original shopping cart, whose frameset page had an index.htm file name. For the one-at-a-time welcome.html page (cf. the link in the post's introductory paragraph), both URLs are correctly specified as shopcartindex.html.

The welcome.html body element

<body text="#000000" bgcolor="#ffffff" link="#8000ff" vlink="#ff8000" alink="#ff0000"> ... </body>

has five attributes, all of which are deprecated.
(1) The text attribute maps onto the CSS color property.
(2) The bgcolor attribute maps onto the CSS background-color property.
As a means of imparting color to unvisited, visited, and active links:
(3-4) The link and vlink attributes respectively map onto the CSS :link and :visited link pseudo-classes.
(5) The alink attribute maps onto the CSS :active dynamic pseudo-class.

#8000ff is a purplish color; #ff8000 is an orangish color; #ff0000 is of course red. The only link on the welcome.html page is the Start Page warning link, whose link="#8000ff" color is OK but whose vlink="#ff8000" and alink="#ff0000" colors should be changed given that the link is flanked by red text.

Modernize it

The structure, presentation, and behavior of the welcome.html body element and frame warning can be cleanly separated as follows:

body { color: black; background-color: white; }
a:link { color: blue; }
a:visited { color: purple; }
a:active { color: lime; }
#div0 { color: red; font-weight: bold; display: none; }

window.onload = function ( ) {
    if (self == parent) document.getElementById("div0").style.display = "block"; }

<div id="div0">This is a frame page: click <a href="shopcartindex.html">here</a> for its frameset.</div> ... </body>
<!-- A p element container for the frame warning would also be semantically acceptable, but either way you should lose the original font element. -->

The a:active color setting must be placed after the a:link and a:visited color settings or it will be overwritten by them.

Historical note: At the time Gordon built the shopping cart the current versions of IE and Netscape were IE 4.x and Netscape 4.x, respectively. Interestingly, I find that the preceding code works very nicely with IE 4.5 upon merely changing document.getElementById("div0").style.display to document.all("div0").style.display, whereas Netscape 4.61 will read but not write a corresponding document.ids["div0"].display expression; moreover, Netscape 4.61 does not support the :active dynamic pseudo-class.

Automatic redirect

Alternatively, you don't have to print out a frame warning at all; you can choose to automatically send the user to the shopcartindex.html page:

window.onload = function ( ) { if (self == parent) self.location = "shopcartindex.html"; }


The navigate.html page begins with its own meta-statement - This page is titled navigate.html and will remain the whole way through the process - and subsequently provides links for loading the pageone.html, pagetwo.html, pagethree.html, and order.html pages into the name="main" right frame of the shopcartindex.html frameset.

<p>These are your three order pages:</p>
<p><a href="pageone.html" target="main">Order Page One</a></p>
<p><a href="pagetwo.html" target="main">Order Page Two</a></p>
<p><a href="pagethree.html" target="main">Order Page Three</a></p>
<p>This allows you to check your order. It's the Shopping Cart page.</p>
<p><font color="#ff000"><b>[ <a href="javascript:parent.updatemain_order( );">Review Order</a> ]</p>

Clicking the Review Order link calls the updatemain_order( ) function in the shopcartindex.html script element.

function updatemain_order( ) {
    parent.frames[1].document.close( );
    parent.frames[1].location = "order.html";
    parent.frames[1].document.close( ); }

Is there any need whatsoever for the updatemain_order( ) function? Nope: the last link's href can be set to order.html à la the other links. Also regarding the last navigate.html line, I suppose I should mention that the font element and the b element both require an end-tag, but we don't really want to be holding onto that markup anyway.

pageone.html intro

We're ready to check out the shopping cart's item pages. Accordingly, we click the Order Page One link on the navigate.html page and load pageone.html into the right frame of the frameset.

The pageone.html document body comprises a form1 form that contains:
(1) a One Item On This Page legend (the price for that one item is not specified);
(2) an push button;
(3) a push button;
(4) a small text field preceded by a You Have Ordered This Many Of This Item: label; and
(5) a Review updated Order Form link that, via the parent.updatemain_order( ) function discussed earlier, loads the order.html page into the right frame.

Markup notes
• The pageone.html body element has a background="/images/thisback.gif" attribute plus the same five attributes that the welcome.html body element has. Here's the thisback.gif image if you want to make use of it.
• The form1 form element's end-tag is missing; the form element requires an end-tag.
• The form1 form's contents are centered via three center elements, which can and should be replaced by a single style="text-align:center;" div wrapper.

Clicking the button adds the Page_1_item_1 item to the shopping cart: we'll crunch through the details of this process in the following entry.

Thursday, May 02, 2013
Cart Vessels
Blog Entry #287

We're ready to get our deconstruction of the shopping cart code of HTML Goodies' "So, You Want A Shopping Cart, Huh?" tutorial under way: our point of departure will be the shopcartindex.html frameset document.

The shopcartindex.html document holds the lion's share of the shopping cart's JavaScript: indeed, shopcartindex.html largely consists of one big script element that contains 25 functions punctuated by a small amount of top-level code. Some of the shopcartindex.html functions pertain to the running order part of the cart; some of the functions pertain to the customer/shipping part of the cart; not all of the functions are called. We will discuss the functions as we call them - I won't burden you with them all at once.

As the shopcartindex.html page loads, the shopcartindex.html JavaScript carries out some important groundwork for the cart: we'll go through that groundwork in today's post.

The order string

Upon adding items to the shopping cart the user builds up an 'order string' that is analogous to a string literal. The order string is composed of (its 'characters' are) custom objects that are organized as an itemlist array-like collection. The itemlist structure is set up by the following code:

function createArray(n) {
    this.length = n;
    var i = 0;
    for (i = 1; i < n; i++)
        this[i] = null;
    return this; }

var itemlist = new createArray(50);

The var itemlist = new createArray(50); statement calls and passes 50 to a createArray( ) constructor function. The createArray( ) function creates an object with 50 properties:
(1-49) 1, 2, ... 49, which are all set to null; and
(50) length, which is set to 50.
The object is returned to the calling statement and given an itemlist identifier.

• The itemlist object is an array in the sense that it associates a set of values with a common identifier, but it is not an Array object (it would automatically have a length property if it were); itemlist is actually an Object object.

• Type-wise, the names of the 1, 2, ... 49 properties are in fact strings: JavaScript property names cannot be numbers. These properties must be accessed by the [ ] operator (bracket notation) and not by the . operator (dot notation), e.g., itemlist[1] is a valid reference but itemlist.1 is not. See the Property accessors section of the Mozilla JavaScript Reference for more on this.

• 49 itemlist 'boxes' are overkill in the present case as the tutorial shopping cart only offers seven items for sale, but let's go with them for the time being.

• In case you were wondering, itemlist[0] evaluates to undefined.

Subsequently the itemlist object is fed to an initialize_arrays( ) function that replaces all those null values with custom objects created by a product( ) constructor function.

var maxarray = 50;

function product(code, price, desc, quan, url) {
    this.price = 0; /* This line is redundant and can be removed. */
    this.code = code;
    this.price = price;
    this.desc = desc;
    this.quan = quan;
    this.url = url;
    return this; }

function initialize_arrays(arraysa) {
    for (i = 1; i < maxarray; i++) {
        arraysa[i] = new product("", 0, "", 0, ""); } }


Each non-length itemlist member is now an Object object with five properties (over and above the constructor and prototype properties that all Object objects have):
(1) code, which is initialized to an empty string;
(2) price, which is initialized to 0;
(3) desc, which is initialized to an empty string;
(4) quan, which is initialized to 0; and
(5) url, which is initialized to an empty string.
These properties will hold the user's order information and can be referenced in the usual (dot-notation) way, e.g., itemlist[1].code.

In practice, the length of the order string is bounded by an item_num variable, which is initialized to 1 and roughly corresponds to the indexB parameter of the substring( ) method of the String object.

var item_num = 1;

The script relatedly defines a self-explanatory items_ordered variable:

var items_ordered = 0;

However, the items_ordered variable is unnecessary in that it doesn't do anything that couldn't be done with the item_num variable.

Alongside itemlist a parallel temp_array structure is created:

var temp_array = new createArray(50);

The temp_array structure plays a central role in a remove_nil_items( ) function that under certain circumstances will remove itemlist members from the order string.

The customer contact

The shopcartindex.html script creates a ship_details Object object for holding the values (in two cases, checked statuses) of the various order.html information fields, specifically, the fields in the Customer Information / Details and Shipping Address: tables plus the preceding Comments & Additional Information field.

var ship_details = new shipp_details( );
function shipp_details( ) {
    this.comments = "";
    this.f_namea = "";
    this.l_namea = ""; = "";
    this.ad_onea = "";
    this.ad_twoa = "";
    this.citya = "";
    this.statea = "";
    this.zipa = "";
    this.countrya = "";
    this.phonea = "";
    this.faxa = "";
    this.mailon = false;
    this.sameflag = false;
    this.shipname = "";
    this.ad_oneb = "";
    this.ad_twob = "";
    this.shipb = "";
    this.stateb = "";
    this.zipb = "";
    this.countryb = "";
    this.phoneb = "";
    this.faxb = ""; }

In general, the ship_details members that end in an a pertain to the Customer Information / Details table and the members that end in a b pertain to the Shipping Address: table. The final this.faxb = ""; statement can be removed as there is no Fax: field in the Shipping Address: table. The mailon and sameflag members are for the Check here to be included on our mailing list and Same as above checkboxes, respectively, and are both initialized to false; the remaining members map onto text inputs and are respectively initialized to empty strings. The ship_details object will be charged with data at the order.html page.

The cookie jar

As noted at the end of Blog Entry #285, the tutorial code does not set any cookies. However, the shopcartindex.html script contains go_with_cookie( ), setCookieArray( ), and setCookie( ) functions that can be used to store the values of the first nine fields of the order.html Customer Information / Details table in the shopcartindex.html document.cookie string, and it also contains get_that_cookie( ), getCookieArray( ), and getCookie( ) functions that can extract the cookie values and load them into the ship_details object via the intermediacy of a shiparray object.

var shiparray = new parent.createArray(10);

As the shiparray object is created in the shopcartindex.html document the parent reference is unnecessary (we would need it if we were calling createArray( ) from one of the frame documents).

The aforementioned get_that_cookie( ) function, which sets the cookie extraction process in motion, is called when the frames of the shopcartindex.html frameset have loaded:

<frameset cols="25%,*" onload="parent.get_that_cookie( );"> ... </frameset>
<!-- The parent reference is again unnecessary. -->

We'll go through the shopcartindex.html cookie functions in a subsequent post.


The top-level part of the shopcartindex.html script also defines
(1) order_total and total_item_price variables that are used to add up the user's order at the order.html page,
(2) a never-used present_item variable,
(3) st_astr and en_astr variables for a display_pic( ) function that can be used to write a new document in the frameset's left frame, and
(4) expiration date code for the shopping cart's cookies.

var order_total = 0;
var present_item = 1;
var total_item_price = 0;
var st_astr = "<html><body bgcolor='#ffffff'>";
var en_astr = "</body></html>";

var expdate = new Date( );
expdate.setTime(expdate.getTime( ) + (24 * 60 * 60 * 1000 * 365));

We'll start interacting with the shopping cart in the following entry.

Powered by Blogger

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