The Car Model List Page

With all our data available, we can now create a list of cars models. This is the page

carmodels.htm
that we loaded at the end of the frameset page's
window_onload()
event. As all the data is cached on the client in our arrays, we need to use client-side script code to build the page dynamically.

Building Pages Dynamically

The main part of the model list page is a table containing the name and description of each car, and a small image. To make it look attractive we alternated the image alignment between left and right. This means that we can't just loop through the array using the same code for each model, we have to do two in each pass. Here's the complete script section that creates the table—the second row is just a mirror of the first:

<TABLE ID="tblModels" STYLE="border-style:none" CELLPADDING=10>

<SCRIPT LANGUAGE="VBScript">

'build the table of car models

BS = Chr(47)   'slash character '/'

QUOT= Chr(34)  'double quote

intNumCars = UBound(top.arrCars, 2)

intThisCar = 0

Do While intThisCar <= intNumCars

'table row with picture on left

Document.Write "<TR><TD ALIGN=RIGHT STYLE=" & QUOT & "cursor:hand" _

& QUOT & "><IMG ID=" & QUOT & "Img" & top.arrCars(0, intThisCar) _

& QUOT & " SRC=" & QUOT & "images/150" & top.arrCars(6, intThisCar) _

& QUOT & " BORDER=0 HSPACE=15><P><" & BS & "TD>"

Document.Write "<TD ALIGN=LEFT><SPAN ID=" & QUOT & "Car" _

& top.arrCars(0, intThisCar) & QUOT & " CLASS=" & QUOT 

If top.arrCars(0, intThisCar) = top.selectedModel Then

Document.Write "SELNAME"  'selected model 

Else

Document.Write "MODNAME"  'not selected model

End If

Document.Write QUOT & ">The Wrox " & top.arrCars(1, intThisCar) _

& "<" & BS & "SPAN><BR>" & top.arrCars(7, intThisCar) _

& "<P><" & BS & "TD><" & BS & "TR>"

'move to the next car (if there is one)

intThisCar = intThisCar + 1

If intThisCar <= intNumCars Then

    'table row with picture on right

'{repeat of code above but with image and text swapped over}

End If

intThisCar = intThisCar + 1

Loop

</SCRIPT>

</TABLE>

The result for one row of the table is shown here. A couple of things to notice are that there are no

<A>
tags in the code, because we're going to detect mouse clicks with script code, and that we use a different style for the car name if it's the currently selected one (i.e. its
CarID
is the same as the value stored in the global variable
top.selectedModel
).

You'll also see we use a string variable

BS
to write the slash character '
/
' into the page. HTML 4.0 says that when using client-side script to write HTML code into a page, any combination of '
</
' followed by a letter should be treated as the end of a script section. This would mean that the browser would stop writing the HTML at that point, and you'd get a syntax error caused by the 'real'
</SCRIPT>
tag. IE4 doesn’t actually do this, but we're sticking to the rules here.

The Problem With Document.Write

Using client-side script to create the page's HTML code dynamically can be a real pain. It's easy to omit a closing '

>
' or double-quote and get a page that looks nothing like you expected. Unlike a page created with ASP, you can’t 'view the source' and see what your code actually produced—all you see is the client-side script code.

To make life easier, we developed a very simple tool that allows you to see the actual HTML that is created in IE4 or better. It uses the fact that we can read the

innerHTML
property of an element to get a string containing the 'virtual' HTML that the browser uses to create the page. If we write this string back to the
innerText
(rather than
innerHTML
) property of another element, it isn’t parsed by the browser but just displayed as text.

What we do is place a temporary

<DIV>
(document division) section around the entire contents of the
<BODY>
of the page, positioning it so that it doesn't change the layout of the existing elements:

</HEAD>

<DIV ID="ToBeRead" STYLE="position:absolute; left:0; top:0>

<BODY STYLE="background-color:white; text-align:center">

...

... page content here including <SCRIPT> sections with Document.Write

...

</BODY>

</DIV>

</HTML>

Then, in the script code in the page, we add a

window_onload
event (or add the code to an existing event) to open our special page
read_doc.htm
page in a new browser window, and place the content of the page into it:

Sub window_onload()

Set objNewWin = window.open("read_doc.htm")

objNewWin.document.all("Output").innerText _

= document.all("ToBeRead").innerHTML

End Sub

The

read_doc.htm
page contains a heading and some instruction on use. However the main part is the
<DIV>
named
Output
into which we are placing the page content:

<DIV ID="Output">

... default text and insrtructions here

</DIV>

You can run this page from our Web site at http://rapid.wrox.co.uk/books/1460/

Here's the result from the first two rows of the car models page table. The last few lines of the script code we saw earlier, which creates the table, are highlighted. The remainder is the HTML that is created dynamically by that script code:

It's interesting to note how the browser has changed the code we wrote to the page. (IE4 does this with all pages, including plain HTML ones, as it converts them from the text HTML source into the 'virtual' page it displays). For example, it sorts the attributes for each element into alphabetical order, and changes their case—all the style property names come out in capital letters, for example.

Caching Images

The car models list displays small images, named

150car1.gif
,
150car2.gif
, etc. However the details page uses a larger image, named
300car1.gif
,
300car2.gif
, etc instead. When the user selects a model we want to display the details as quickly as possible, and we can do this by downloading and caching the larger images while they are viewing the model list. At the end of model list page we create a set of hidden image tags:

...

<SCRIPT LANGUAGE="VBScript">

'preload the main car pictures for use later

For intLoop = 0 To intNumCars

Document.Write "<IMG WIDTH=1 HEIGHT=1 SRC=" & QUOT & "images/300" _

& top.arrCars(6, intLoop) & QUOT _

& " STYLE=" & QUOT & "visibility:hidden" & QUOT & ">"

Next

</SCRIPT>

</BODY>

</HTML>

The resulting virtual HTML code looks like this—again IE4 has changed the case and ordering of some of the attributes:

<IMG height=1 src="images/300car1.gif" style="VISIBILITY: hidden" width=1>

<IMG height=1 src="images/300car3.gif" style="VISIBILITY: hidden" width=1>

<IMG height=1 src="images/300car4.gif" style="VISIBILITY: hidden" width=1>

<IMG height=1 src="images/300car2.gif" style="VISIBILITY: hidden" width=1>

<IMG height=1 src="images/300van1.gif" style="VISIBILITY: hidden" width=1> 

Indicating The Selected Model

The final task in the main page is to allow the user to select a car model, and indicate to them which model is currently selected. The small car images and the car model names are not actually hyperlinks, although we used the

STYLE="cursor:hand"
attribute to make them appear as if they are. So we need to detect a mouse-click on them another way. The standard IE4 Dynamic HTML technique is shown in the code below:

Sub document_onclick()

Set objSource = window.event.srcElement

If Left(objSource.id, 3) = "Car" Or Left(objSource.id, 3) = "Img" Then

'a car image or name was clicked, get the CarID key

intCarID = CInt(Mid(objSource.id, 4))

'change the style of the car names as appropriate

document.all("Car" & intCarID).className = "SELNAME"

If top.selectedModel > 0 And top.selectedModel <> intCarID Then 

document.all("Car" & top.selectedModel).className = "MODNAME"

End If

'store the selection in the frameset page variables

top.selectedModel = intCarID

top.selectedColor = 0

'update the 'salespersons comment' window

strMessage = document.all("Car" & intCarID).innerText_

& ", an excellent choice."

top.frames("menu").document.all("divMessage").innerText = strmessage

End If

window.event.cancelBubble = true

window.event.returnValue = false

End Sub

We can get the

CarID
from the
ID
attribute of the image or car name, because we put it there ourselves when we created the page. Then we only have to swap the text style of the previously selected item (if there was one and it's not the same as the current one) and the currently selected one. This makes the currently selected model name appear in red rather than gray—the style definitions are in the
<HEAD>
of the page and aren't shown in the code here.

The final task is to update the salesperson's comments that appear in the top left section of the page, above the navigation buttons. We do this by writing to the

innerText
property of a
<DIV>
on that page. We'll look at this page in detail later on.

© 1998 by Wrox Press. All rights reserved.