reptile7's JavaScript blog
Monday, September 02, 2013
 
shopcartindex.html Flotsam and Jetsam
Blog Entry #301

In today's post, we'll go through the orphaned parts of the shopcartindex.html document that coordinates the "So, You Want A Shopping Cart, Huh?" shopping cart. Over and above the set-cookies part of the cart's cookie machinery, there are four other never-called functions in the shopcartindex.html source:
(1) check_window( )
(2-3) display_pic( ) and updatenav_nav( )
(4) delCookie( )
In the name of completeness, let's look at these functions, shall we?

Automatic redirect, part 2

The check_window( ) function is the last (25th) function in the shopcartindex.html script element.

function check_window( ) {
    if (self == mainbody) {
        document.write("<head><meta http-equiv='refresh' content='15; url=index.html'></head>");
        document.write("<body><center><h1>Warning!</h1><br>");
        document.write("<font color='#ff0000'><b>This is inside a multiple frame window.<br>");
        document.write("The scripts may not work correctly!!!!</font><br>");
        document.write("We are jumping you directly to our <a href='index.htm' target='_top'>Main page</a> in 15 seconds.</center>");
        self.location = "index.html";
        parent.document.close( ); } }

/* In the original check_window( ) function, the five document.write( ) commands are written as a single command, which I have broken up for the sake of clarity. */

Evidently, the check_window( ) function is a forerunner of the JavaScript snippet that prints out the THIS IS A FRAME ... warning at the top of the various frame src pages if those pages are accessed outside of the shopcartindex.html frameset and that we discussed in the welcome.html section of Blog Entry #288. If the browser gets through the if (self == mainbody) { ... } gate (and it won't, as mainbody is an undefined variable), then check_window( ) writes out
(1) a head element containing a meta refresh that, if supported by the browser, sends the user to the index.html page after a 15-second delay, and then
(2) a body element that displays
(a) a somewhat-incoherent frame warning plus
(b) a redirection notification that includes a link to the index.htm (sic) page.
Strangely, the document.write( ) action is followed by a self.location = "index.html"; statement that immediately takes the user to index.html anyway.

Upon cleaning up the check_window( ) function - upon changing the if condition to self == parent and throwing out the post-document.write( ) commands - I find that the meta refresh operation works with Mozilla's browsers (Firefox, Camino, Netscape 9) and only with Mozilla's browsers. If you like the 15-second meta refresh idea, a much better approach is to just go with the self.location assignment and delay it via a window.setTimeout( ) command:

window.setTimeout("self.location = 'shopcartindex.html';", 15000);

Show me the goods

In the "Shopping Cart" tutorial's Altering The Pages section, Joe notes, You can go into these template pages and add text and images to your heart's delight. The display_pic( ) function provides a mechanism for displaying an image of an item in the left-hand navigate frame.

var st_astr = "<html><body bgcolor='white'>";
var en_astr = "</body></html>";


function display_pic(graphic, price) {
    parent.frames[0].document.close( );
    parent.frames[0].document.write(st_astr);
    parent.frames[0].document.write("<img src='images/" + graphic + "'><br>" + price);
    parent.frames[0].document.write("<p><a href='javascript:parent.updatenav_nav( );'>Navigation Table</a>");
    parent.frames[0].document.write(en_astr);
    parent.frames[0].document.close( ); }


I use the word "mechanism" above because the display_pic( ) function doesn't just display an image but completely overwrites the navigate.html document with a new document whose bodyObject.firstChild is the image we want to display. Situated below the graphic image for the item is the item's price and also a Navigation Table link, which when clicked calls an updatenav_nav( ) function that returns navigate.html to the navigate frame.

function updatenav_nav( ) {
    parent.frames[0].document.close( );
    parent.frames[0].location = "navigate.html";
    parent.frames[0].document.close( ); }


Presumably the display_pic( ) function would be called by buttons on the item pages, for example:

<p>This Item Costs $2.22</p>
<button type="button" onclick="parent.display_pic('p2i1_photo.jpeg', '$2.22');">Show This Item In The Left Frame</button>


We can easily adapt the display_pic( )/updatenav_nav( ) functionality to the navigation parent + iframe structure described in the Frame retool section of Blog Entry #299:

(1) In the parent document,
(a) wrap the navigation content in a linksDiv div and
(b) put an empty pictureDiv div right after the linksDiv div.

<div id="navigateDiv">
<div id="linksDiv">
<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>
<div id="pictureDiv"></div>
</div>


(2) Code the display_pic( ) function as:

function display_pic(graphic, price) {
    document.getElementById("linksDiv").style.display = "none";
    document.getElementById("pictureDiv").innerHTML =
    "<img src='" + graphic + "'><br>" + price + "<p><a href='javascript:updatenav_nav( );'>Navigation Table</a></p>"; }


(3) Code the updatenav_nav( ) function as:

function updatenav_nav( ) {
    document.getElementById("linksDiv").style.display = "block";
    document.getElementById("pictureDiv").innerHTML = ""; }


Alternatively, you might prefer to display thumbnail images of the items on the item pages themselves:

.pictureDiv { display: none; }
...

function display_pic(show, itemID) {
    document.getElementById(itemID).style.display = show ? "block" : "none"; }

...
<p>This Item Costs $2.22</p>
<div id="p2i1" class="pictureDiv"><img width=imageWidth height=imageHeight src=imageURL alt="The p2i1 item"></div>
<button type="button" onclick="display_pic(true, 'p2i1');">Show Item</button>
<button type="button" onclick="display_pic(false, 'p2i1');">Hide Item</button><br> ...


The cookies are all gone

The delCookie( ) function provides a template for deleting the gifttails cookies associated with the shopcartindex.html document.

function delCookie(name) {
    var expireNow = new Date( );
    document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT" + "; path=/"; }


• The Thu, 01-Jan-70 00:00:01 GMT expires value may look deprecated, although it does exactly match the expires date string format given in the "Netscape Cookies" appendix of the JavaScript 1.3 Client-Side Reference.

• No use is made of the expireNow Date object, and its constructor statement can be thrown out. But you could make use of expireNow if you wanted to, for example, you could push it one millisecond into the past
expireNow.setTime(expireNow.getTime( ) - 1);
and then use its toUTCString( ) return for the expires value.
... expires=" + expireNow.toUTCString( ) + ...

• Note that the value of the name cookie is set to an empty string. It is not necessary to retrieve the original value of the cookie; in the Saving Cookies section of the aforecited "Netscape Cookies" resource, Netscape states, Saving a cookie with the same path and name values as an existing cookie overwrites the existing cookie.

Now, we could supplement the delCookie( ) function with a delCookieArray( ) function that iteratively feeds gifttails+i strings to delCookie( ), but I'm not sure I see the point of doing so given that we can put the requisite loop action in delCookie( ) itself:

function delCookie( ) {
    if (document.cookie.indexOf("gifttails") != -1) {
        for (i = 0; i < textInputValues.length; i++)
            document.cookie = "gifttails" + i + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT" + "; path=/"; } }


We can call delCookie( ) via a button on the navigation parent page:

<button type="button" onclick="delCookie( );">Clear All Cart Cookies</button>

N.B. After clearing the cookies, the user may (depending on the user's interaction with the cart, depending on the browser) end up resetting the cookies if the cookie-setting process is triggered by unloading the order.html page - this is one of the reasons I prefer to set cookies when the order form is submitted.

In the course of putting together my own demo for the shopping cart, I ran through the source of the shopcart.zip package's thanku.htm 'thank you' page, and realized: "I really should write a post on this code." So in the following entry, I'll discuss the thanku.htm document, and after that roll out my shopping cart demo, and then we'll finally be ready to move on to something else.

Comments: Post a Comment

<< Home

Powered by Blogger

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