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.

Comments: Post a Comment

<< Home

Powered by Blogger

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