reptile7's JavaScript blog
Sunday, August 18, 2013
 
Frameset Items Zero
Blog Entry #299

The denouement of our "So, You Want A Shopping Cart, Huh?" discourse will begin with discussions of
(1) the obsolete shopcartindex.html structure and
(2) the shopcartindex.html remove_nil_items( ) function.

Frame retool

In the Frameset/frame notes subsection of Blog Entry #286, we noted that HTML5 is obsoleting the frameset and frame elements - These elements are entirely obsolete, and must not be used by authors, the W3C declares - so it behooves us to come up with an alternate structure for the shopcartindex.html document.

However, we don't have to discard the frame concept completely. HTML5 is holding on to the iframe element, and it is simple enough to recast the right-hand main frame as an iframe. As for the left-hand navigate frame, its navigate.html content stays in place during the shopping cart process and can therefore be brought into a non-frameset parent document. The window.frames collection includes iframes, so we can continue to use the windowObject.frameObject mechanism to pass information between the iframe's documents and the parent document.

As set by the original frameset's cols="25%,*" attribute, the navigate frame's width spans 25% of the viewport width; we can mimic this effect by wrapping the navigate.html content in a div and then setting the div's CSS width to 25%.

#navigateDiv { width: 25%; display: inline-block; }
...
<div id="navigateDiv">
<p>This is the navigation div, and here are links to the order pages:</p>
<p><a href="pageone.html" target="main">Order Page One</a></p>
...
</div>


Normally the div element has a block-level rendering. We want the main iframe to horizontally flank the navigateDiv div and not be below it, which is easily arranged by setting the div's CSS display to inline-block (but not inline, as the div contains <p>s, whose own block-level renderings would then push the iframe below the div).

I find that giving the main iframe a full width="75%" pushes it below the navigateDiv div: a width setting that affords a bit of horizontal breathing room solves this problem. Regarding its height, the main iframe should vertically span the entire height of the viewport and provide a vertical scrollbar for at least the order.html page, whose height exceeds the viewport height. To vertically align the tops of the navigateDiv div and the main iframe, give the iframe a vertical-align:top; styling (otherwise the div will sit at the baseline of the iframe).

#orderIframe { vertical-align: top; }
...
<iframe id="orderIframe" name="main" width="70%" height="100%" src="welcome.html" frameborder="1" scrolling="auto">Your browser does not support iframes. Please call us at 123-456-7890 for a mail-order catalog.</iframe>


Cleaning up the order string, or not

This section will provide an overview of what the remove_nil_items( ) function will and will not do, as a complete treatment would take up more space than it's worth.

A visitor goes to the pagetwo.html page and adds, in order, one p2i1 ($2.22) item, one p2i2 ($3.33) item, and one p2i3 ($4.44) item to the shopping cart. Per the shopcartindex.html additem( ) function

function additem(codes, prices, descrip, url) {
    loc = check_if_in(codes);
    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; }
    remove_nil_items(itemlist); }


and the shopcartindex.html 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; }


the visitor's cart additions create the following order string:

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


At this point, the itemlist[1]-itemlist[3] and temp_array[1]-temp_array[3] members are identical, the items_ordered counter is 3, and the item_num index is 4.

Suppose the visitor subtracts the p2i2 item and adds a second p2i1 item.

(1) The remove_nil_items( ) for loop runs for three iterations.
(a) In the first iteration, itemlist[1] is assigned to temp_array[1].
(b) In the second iteration, itemlist[2].quan is 0 and therefore itemlist[2] is not assigned to temp_array[2].
(c) In the third iteration, itemlist[3] is assigned to temp_array[2] (j was not incremented in the loop's second iteration because the if condition was false).

(2) After the loop, the itemlist = temp_array; statement copies the temp_array object to the itemlist object, i.e., each itemlist member is overwritten by its corresponding temp_array member: temp_array[1] is assigned to itemlist[1], temp_array[2] is assigned to itemlist[2], etc. Subsequently item_num is reset (effectively decremented) to 3 by the item_num = items_ordered + 1; statement.

When remove_nil_items( ) has finished executing, the order string is:

itemlist[1] = temp_array[1] =
    {code: "p2i1", price: "2.22", desc: "Page_2_Item_1", quan: 2, url: "pagetwo.html"}
itemlist[2] = temp_array[2] =
    {code: "p2i3", price: "4.44", desc: "Page_2_Item_3", quan: 1, url: "pagetwo.html"}
itemlist[3] = temp_array[3] =
    {code: "p2i3", price: "4.44", desc: "Page_2_Item_3", quan: 1, url: "pagetwo.html"}


Net effect: The original p2i2 item has been removed but now we have a duplicate p2i3 item in the order string.

Suppose the visitor subtracts the p2i3 item and adds a second p2i1 item. In this case, nothing is removed from the order string: the p2i3 item would seem to be left behind by the third iteration of the remove_nil_items( ) for loop but it reappears when temp_array[3] is assigned to itemlist[3] after the loop.

As noted in the Subtract it section of Blog Entry #290, the shopcartindex.html subitem( ) function does not call the remove_nil_items( ) function; consequently, subtracting the p2i1 or p2i2 item without adding another item has no effect on the order string (other than decrementing the quan value of the p2i1 or p2i2 item).

Fortunately, the aforedescribed remove_nil_items( ) problems do not interfere with the normal operation of the shopping cart. At the order.html page, the visitor's order is tallied and displayed via script code with itemlist[i].quan operations that directly or indirectly weed out nil items anyway, more specifically:
(1) the shopcartindex.html all_order_totals( ) function doesn't add anything to the order_total if itemlist[i].quan is 0; and
(2) writing the visitor's itemlist data to the order.html page requires us to go through an if (parent.itemlist[i].quan > 0) { ... } gate.
It follows that the remove_nil_items( ) function is excess baggage, and should be thrown out.

We'll overhaul the item addition/subtraction process in the next entry.

Comments: Post a Comment

<< Home

Powered by Blogger

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