Since mid-1996, technologies geared towards Internet and Web applications have been improving by leaps and bounds. With the introduction of the HTML 3.2 <OBJECT> tag, ActiveX controls, and client-side Visual Basic scripting within browsers such as Microsoft Internet Explorer 3.0, developers now have the tools to begin developing fully interactive Web applications. With the availability of these new technologies, the Web browser is rapidly becoming a full-fledged GUI development environment.
The goal of this chapter is to show you how you can leverage these technologies to develop HTML form interfaces for your Web database and other applications. You will be able to develop applications that are far more interactive and functional, as well as more aesthetically pleasing.
To start, you learn how VB scripts are attached to HTML documents and invoked by various events. Next, you discover how Microsoft's Internet Explorer browser is really composed of a hierarchical set of component objects (such as links, frames, scripts, forms, and object elements), each with its own set of events, properties, and methods that you can access through your VB scripts. You'll see just how powerful this object model for scripting is for developing dynamic user interfaces.
The final section is dedicated to applying the material you learned in earlier sections. In this section you learn more about how to format form objects and content using HTML tables as well as the HTML layout control--a nifty ActiveX control that provides fine placement of objects on a page. This is followed by two examples, a search engine query form and a database query form, which illustrate how VBScript, ActiveX, and HTML objects can be used to create application user interfaces, complete with interactive responses to user actions, input validation, and submission of forms via VBScript.
In Chapter 12, "Introduction to Client-Side Web Application Development Using VBScript," you were briefly introduced to the use of VBScript within HTML forms. However, the methods in which VB scripts are attached to your HTML documents and forms was only touched upon briefly. In this section, you learn about the three ways in which scripts are attached to and invoked from HTML documents:
The <SCRIPT> tag is an element that is used for embedding scripts, such as VBScript or JScript, in an HTML document. Using the <SCRIPT> tag, the full source code for a script or scripts can be included within the body of the HTML document. Additionally, the SRC (that is, SRC=URL) attribute of the <SCRIPT> tag can be used to reference scripts outside of, or external to, the body of the document. This allows the use of URLs that point to a script from some other location.
The following simple script illustrates how a document's write method can be invoked to place a string into the current HTML document at the location of the script:
<HTML> <BODY> <SCRIPT language="VBScript"> <!-- document.write("Welcome to Omniscient!") --> </SCRIPT> ... body of HTML document ... ... other <SCRIPT>s as required ... </BODY> </HTML>
Here are a few things to note about how <SCRIPT> is evaluated when a document is loaded:
Scripts can also be added to documents by using attributes of HTML elements (such as forms, buttons, and links) that support scripts. In other words, attributes are used to bind or associate specific scripts with specific events that can occur on the document. When an event occurs on the document (say, the user clicks a button on a form), the script that has been associated with the event is executed.
In the following example, a button's onClick event is associated with the script btnPress, by including onClick=btnPress as an attribute to the <INPUT> tag used to create the button. Similar syntax can be used to bind events with scripts in <FORM> and <BODY> tags as well. When the button is pressed, the script named btnPress is executed to display a MsgBox dialog to the user:
<FORM NAME="myForm"> <INPUT TYPE="button" NAME="myButton" VALUE="pressed" onClick="btnPress" LANGUAGE="VBScript"> </FORM> <SCRIPT LANGUAGE="VBScript"> sub btnPress MsgBox "You pressed my Button!" end sub </SCRIPT>
Note that the LANGUAGE attribute was specified with the input tag. If not explicitly stated, the language of the most recently encountered script block would be used; if none were encountered previously, JScript would be the default.
An alternative syntax can also be used to associate an event with a script. The general form of the syntax is
<SCRIPT FOR="object" EVENT="event" LANGAUAGE="language">
The following example illustrates the use of this alternative syntax:
<FORM NAME="myForm"> <INPUT TYPE="button" NAME="myButton" VALUE="pressed"> <SCRIPT FOR=myButton EVENT="onClick" LANGUAGE="VBScript"> MsgBox "You pressed my Button!" </SCRIPT> </FORM>
It is also possible to invoke a script through the use of the anchor (<A>) tag combined with a custom URL type. This allows the execution of some script code when a hyperlink is clicked by a user. The general syntax used is
<A HREF="script-engine:script-code">link_content</A>
where script-engine represents the scripting engine to use and script-code is a string that evaluates to script code supported by the engine. The code is executed (in the context of the current page) at the time the URL is evaluated (that is, when the link is clicked).
The following example illustrates how JScript is used to display an Alert dialog when a link is pressed:
<A HREF="javascript:alert(document.title)"> Display title of current docuement</A>
<A HREF="javascript:VBScriptFunctionName()">link_content</A>.
The following example illustrates how this syntax can be used to reference a VBScript function that displays a MsgBox dialog when the user clicks a link:
<HTML> <!-- <SCRIPT language="VBScript"> SUB myVBFunction( ) MsgBox("You called a VBScript via JScript") END SUB --> </SCRIPT> <BODY> This is a <A HREF="JavaScript:myVBFunction()">Display a VBScript MsgBox</A> </BODY> </HTML>
In this section you learn about the structure of the scripting object model for Microsoft's Internet Explorer (IE) Web browser. The scripting object model provides a structured framework for manipulating component objects of the browser interface. It also provides the capability to embed applications developed using VBScript (note that the IE object model is also accessible from any scripting language, such as JScript, that is compatible with the ActiveX scripting framework).
So what does this mean to someone developing forms and user interfaces for database and other Web applications? Essentially, it means that you are no longer constrained by the limitations of HTML forms, interfaces, and server-side programs. Instead, Internet Explorer can now be viewed more as a graphical user interface development environment--not as sophisticated or rich in functionality as the X Window System for example, but an increasingly capable development environment nonetheless. You are now provided direct programmatic access to the objects, properties, and methods that make up Internet Explorer as well as the very elements, such as HTML form objects and ActiveX controls, used to create database query forms and application user interfaces.
It is now possible to develop user interfaces that integrate ActiveX controls, respond to user actions and events generated by form elements, implement client-side programs (for instance VBScript scripts run by an interpreter within the browser) to perform functions such as input validation, and even perform runtime changes to the characteristics of the interface itself. This type of user interface functionality is becoming increasingly commonplace, and days of using static HTML forms for Web applications are slipping quickly into history.
Figure 14.1 illustrates graphically the hierarchical nature of the scripting object model and depicts the objects to be presented in following sections. Note that the dotted lines following objects in this illustration indicate that multiple instances of that object type may exist. Here's a list of these objects:
FIGURE 14.1.The Internet Explorer scripting object model and object hierarchy.
Table 14.1 summarizes the methods, events, and properties for the IE scripting
object model components illustrated in Figure 14.1. These methods, events, and properties
are all accessible to developers creating database forms and application user interfaces.
They provide a rich set of functionality that can be tapped to created very complex
and sophisticated interfaces for Web applications.
Table 14.1. A Summary of the Methods, Events, and Properties for
Each Object in the Internet Explorer Object Scripting Model.
IE Object | Methods/Event Handlers | Events | Properties |
Window | alert, confirm, prompt, | onLoad, | name, parent, opener, self, top, |
open, close, setTimeout, | onUnLoad | location, defaultStatus, status, | |
clearTimeout, navigate | frames, history, navigator, | ||
onLoad and onUnload | document | ||
event handlers | |||
Document | write, writeLn, open, | N/A | linkColor,aLinkColor, vLinkColor, |
close, clear | bgColor, fgColor, anchors, links, forms, location, lastModified, title, cookie, referrer | ||
Link | onMouseMove, | onMouseMove, | href, protocol, host, hostname, |
onMouseOver and | onMouseOver, | port, pathname, search, hash, | |
onClick event handlers |
onClick | target | |
Anchor | N/A | N/A | name |
Form | submit | onSubmit | action, encoding, method, target, elements |
Element | click, focus, blur, | onClick, | form, name, value, defaultValue, |
select onClick, | onFocus, onBlur,checked, defaultChecked, length, | ||
onFocus, onBlur, | onChange, | options, selectedIndex | |
onChange and | onSelect | ||
onSelect event handlers | |||
History | back, forward, go | N/A | length |
Navigator | N/A | N/A | appCodeName, appName, appVersion,userAgent |
Location | N/A | N/A | href, protocol, host, hostname,port, pathname, search, hash |
http://www.microsoft.com/intdev/sdk
In the Programming Contents frame, scroll down to the section for ActiveX SDK docs and click the Scripting Obj Model link. This will take you to a location where you can read the documentation online or download the full 70+ page document in .zip format. This document contains a wealth of information, including examples, on all the events, event handlers, methods, and properties summarized in Table 14.1.
As illustrated in Figure 14.1, the window object is the top-level object in the IE scripting object model and, as such, represents the IE window and its methods and properties. All windows contain the following component objects:
Naming a Window Before a window can be accessed by name, it must first be given a name. This can be accomplished in a couple of ways. The following code creates a window with a name frame1 (with contents a.htm) by using the <FRAMESET> element:
<FRAMESET COLS = "200, *" FRAMEBORDER=0> <FRAME NAME= "frame1" SRC="a.htm"> <FRAME NAME= "frame2" SRC="b.htm"> </FRAMESET>
The following snippet of code accomplishes the same thing by creating the window with a URL that uses the TARGET attribute:
<A HREF="a.htm" TARGET = "frame1" Click here to see a.htm in frame "frame1".</A>
One other method for giving a window a name is to use the window's open method, as follows, to create a window named foo (with contents a.htm):
<SCRIPT Language="VBScript"> window.open ("a.htm", "foo"); </SCRIPT>
Referencing Window Object Properties and Methods Window object properties and methods can be referenced directly by scripts while in the window scope. For example, it is possible to reference the window's name within a script using
winname = name
rather than using
winname = window.name
Similarly, the following script will obtain the name of the current page and display the name by invoking the window's alert method:
<SCRIPT LANGUAGE="VBScript"> ... mystring = name alert mystring ... </SCRIPT>
Finally, the properties of other window objects can be accessed without explicitly mentioning the window. The following code will obtain the name of the current window's parent:
<SCRIPT LANGUAGE="VBScript"> ... mystring = parent.name ... </SCRIPT>
Adding Scripts to a Window Event Scripts can be added to window events by adding a script for either the onLoad or onUnLoad events in the <BODY> tag at the top of a page. Here's an example:
<HTML> ... <BODY Language="VBScript" onLoad="MyProc"> ... <SCRIPT language="VBScript"> ... Sub MyProc MsgBox "This is sub MyProc" End Sub ... </SCRIPT> .... </BODY> </HTML>
Using this code results in the procedure MyProc being called when the page is loaded. Calling Scripts from One Window to Another It is possible to call scripts from one window object to another. For example,
top.my_script()
will execute the script my_script() in the topmost window.
As illustrated in Figure 14.1, the document object is the next level below the window object in the IE scripting object model. The document object reflects the current HTML document in the browser (as well as objects on the page such as links, forms, ActiveX controls, buttons, and so on.) All document objects contain the following component objects:
Document.form(1).mycheckbox.enabled = False
within an event handler associated with the form represented by the array entry Document.form(0). You could use similar methods to perform other runtime modifications to forms, such as adding or removing entries to a pull-down menu control.
Accessing Document Object Properties A quick glance at Figure 14.1 reveals that scripts live within the window object, not the document object. Therefore, in order to access document properties, it is necessary that script developers use the syntax
document.property
to access the desired property. For example, a document's title can be obtained using the following script:
<SCRIPT LANGUAGE="VBScript"> ... mystring = document.title ... </SCRIPT>
Similarly, the background color of the HTML page could be set using the following script:
<SCRIPT LANGUAGE="VBScript"> document.bgColor = "Blue" </SCRIPT>
Accessing Forms Within a Document Object There are two ways in which a form can be accessed in a document: reference by name or through the form array. The following example illustrates how a form (Form1) is addressed by name:
<FORM NAME="Form1"> <INPUT TYPE="button" NAME="Button1" VALUE="Press" onClick="pressed"> </FORM>
For this case, a script could then access a button object (Button1) on the form by referring to form1 by name, as follows:
<SCRIPT LANGUAGE="VBScript"> sub pressed document.Form1.Button1.value = "Pressed" end sub </SCRIPT>
Alternatively, the button object (Button1) could be accessed by accessing form1 by index (that is, as the first element, or the element at Index 0, of the forms array for the document), as follows:
<SCRIPT LANGUAGE="VBScript"> sub pressed ... document.forms(0).Button1.value = "Pressed" arrayLen = document.forms.length `get the length of forms array ... end sub </SCRIPT>
Notice in the preceding example that the length of the forms array was also obtained.
It is also possible to refer directly to contained elements that are not form types. For instance, suppose you have created an object, as follows:
<OBJECT Name="myObject"> </OBJECT>
It is then possible to directly reference this object (say, an ActiveX control) from within a script. For example, the following code could be used to set the object's color property:
<SCRIPT LANGUAGE="VBScript"> sub foo myObject.color = "purple" end sub </SCRIPT>
The form object is a level below the document object in the IE scripting object model. The form object represents a form in the HTML document. There can be multiple forms within a document object and all are kept as an array as well as by name. All form objects can contain elements, which are arrays of objects (such as HTML form intrinsic objects or ActiveX controls) contained within the form. Accessing Elements Contained in a Form Scripts can reside either within a form object or within a window object. In the previous section on document objects, you saw that scripts living outside the form need to access form elements (that is, HTML objects or ActiveX controls) by name (for example, document.Form1.Button1.value = "Pressed") or via the form array (for example, document.forms(0).Button1.value = "Pressed"). However, there are cases where the script lies within the form itself:
<FORM NAME="thisForm"> <INPUT TYPE="button" NAME="Button1" VALUE="Press me"> <SCRIPT FOR="thisObject" EVENT="thisEvent" LANGUAGE="VBScript"> ... your VBScript code here ... </SCRIPT> </FORM>
In this case, the elements on the form can be accessed directly as seen with Button1 in the following example:
<FORM NAME="Form1"> <INPUT TYPE="button" NAME="Button1" VALUE="Press me"> <SCRIPT FOR="Button1" EVENT="onClick" LANGUAGE="VBScript"> Button1.value="Click" `direct access of this form element </SCRIPT> </FORM>
Accessing Methods for Elements Contained in a Form Scripts can also access the methods of elements contained in a form. For example, say you had a form used to query a database, and that form contained text input fields such as the following:
<FORM name="myForm"> <input type="text" size="85" maxlength="100" name="author_name"> ... other form elements ... </FORM>
Suppose that a VBScript procedure performs validation of data input to this and other fields when the user submits the form. If the validation routine detected an error for a specific input, it would be nice to set the cursor back to this specific field so that the user can correct the input. This could be accomplished by invoking the focus method for the text input element where the error occurred. For example, the data validation routine could contain the following line of code to accomplish this:
call Document.myForm.author_name.Focus()
The link object is a level below the document object in the IE scripting object model. It is referenced as a read-only property array. Every link that appears in an HTML document has a corresponding link object constructed and an entry in the link array.
Links are defined in scripting as the anchor tag, <A>, containing an HREF attribute. Here's an example:
<A HREF="http://www.omniscient.com/">
All properties of link objects are read-only and are the same as the location object's properties. Link objects are only accessible via the indexed array. For example, the fourth link on an HTML page (if it exists) could be referenced using the following code to access the link object entry at Index 3 in the array (remember that arrays are 0-indexed):
<SCRIPT language="VBScript"> ... thisLink = document.links(3).href ... </SCRIPT>
In this example, thisLink is set to the value of the href property (that is, the complete URL for the link) for the fourth link on the page.
The anchor object is a level below the document object in the IE scripting object model. The object specifies an array of anchors for a given HTML document. Every anchor (that is, every <A> tag) that appears in an HTML document has a corresponding anchor object constructed and an entry in the array.
The anchor object is referenced as a read-only property array. For example, the fourth anchor on an HTML page (if it exists) could be referenced using the following code to access the anchor object entry at Index 3 in the array:
<SCRIPT language="VBScript"> ... thisAnchor = document.anchors(3).name ... </SCRIPT>
In this example, thisAnchor is set to the value of the name property for the fourth anchor on the page.
The element object is a level below the form object in the IE scripting object model. Element objects are commonly intrinsic HTML objects (such as radio buttons and text input boxes) that are placed on a form using <INPUT> tags. Additionally, the elements can be more complex objects, such as ActiveX controls, placed on a form with the <OBJECT> tag. Element objects can be referenced either by name or by array. In either case, the reference to the object must follow the identifier for the form on which it resides.
Element objects are of particular interest to Web application developers because
elements on forms provide a primary means of interfacing with the user and collecting
information (such as constraints and clauses for database queries) that will ultimately
be used by the application at the Web server. Additionally, element objects on a
form can be used for presenting data and information (for example, the results of
a database query) to a user. This information might be presented graphically using
an ActiveX charting control or may be used to construct secondary database query
forms that use the result of the primary query to construct additional queries to
support a drill-down analysis. Intrinsic HTML Control Properties, Methods, and Events
Table 14.2 summarizes properties, events, and methods associated with HTML intrinsic
controls.
Table 14.2. Intrinsic HTML Control Properties, Methods, and Events.
HTML Control | Properties | Methods | Events |
button, reset, | form, name, value | click | onClick |
submit | |||
checkbox | form, name, value, | click, focus | onClick |
checked, defaultChecked | |||
radio | form, name, value, | click, focus | onClick |
checked | |||
password | form, name, value, | focus, blur, | N/A |
defaultValue | select | ||
text, textarea | form, name, value, | focus, blur, | onFocus, onBlur, |
defaultValue | select | onChange, onSelect | |
select | name, length, options, | focus, blur | onFocus, onBlur, |
selectedIndex | onChange | ||
hidden | name, value | N/A | N/A |
onEvent = "subroutine"
This method can be employed for all HTML intrinsic elements (that is, forms, buttons, links, and so on). For example, the following code uses this syntax to cause a MsgBox to be displayed when a button is clicked by the user:
<FORM name="myForm"> <input type="button" name="myButton" value="Press Me Now!" onClick="pressed"> </FORM> <SCRIPT language="VBScript"> sub pressed MsgBox "You really know how to press my buttons!" end sub </SCRIPT>
Note that this scripting method does not work for elements added to a form with the <OBJECT> tag.
The second method of scripting uses the following syntax:
FOR="object" EVENT="eventname"
This syntax is appropriate for use with any named element, including those added using the <OBJECT> tag. The following code uses this syntax to cause a MsgBox to be displayed when a button is clicked by the user:
<FORM name="myForm"> <input type="button" name="myButton" value="Press"> <SCRIPT FOR="Button1" EVENT="onClick" language="VBScript"> MsgBox "You really know how to press my buttons!" </SCRIPT> </FORM>
The history object is a level below the window object in the IE scripting object model. This object exposes methods (that is, forward, back, and go) for navigating through the current browser history list.
The navigator object is a level below the window object in the IE scripting object model. Navigator object properties (that is, appCodeName, appName, appVersion, and userAgent) provide script developers with information about the browser application.
The location object is a level below the window object in the IE scripting object model. The location object represents the current URL.
Setting any portion of the location object will cause the browser to automatically navigate to the newly constructed URL. For example, the following code can be used to cause the browser to navigate to the Omniscient Technologies site:
<SCRIPT language="VBScript"> ... location.href="http://www.omniscient.com/" </SCRIPT>
This technique could be employed to automatically route users to sites in response to a query posed by the user. Additionally, if an ActiveX browser control is used within an HTML document, this technique would be used to navigate the embedded browser to the site represented by the newly constructed URL.
Before the introduction of HTML 3.2 objects, ActiveX controls, and browsers (such as Internet Explorer) that support Visual Basic scripting, Web applications developers were shackled by the restrictions of intrinsic HTML 2.0 form objects and layout capabilities. These objects allowed virtually no client-side processing of user inputs or actions, such as a mouse click. Instead, all data validation, conditional logic, and forms input processing had to take place on the server. This took more time, consumed limited network bandwidth and server resources, and severely hampered the level of interactiveness a user could have with an application on a Web browser.
Using HTML 3.2 <OBJECT>s and a growing suite of available ActiveX controls, developers are now able to create highly interactive applications including
http://www.microsoft.com/workshop/author/cpad
This site also contains links to tutorials, white papers, FAQ samples, and a user discussion/support newsgroup. You should also visit the ActiveX Gallery site at
http://www.microsoft.com/activex/controls
to check out many of the controls offered by third-party vendors.
What is so significant about these controls and objects? Well, two things really. First, most provide a rich set of modifiable parameters that allow developers to tailor how they are presented to the user. For example, size, relative placement, color, font styles, labeling and captions, and so on can be initialized and modified at runtime. Second, most of these objects and controls are dynamic in that they respond to events. These events can be time-related events (such as a specific date or time) or user events such as a mouse click on the object. The fact that these objects and controls respond to events enables developers to create response functions associated with specific events. These response functions are client-side VBScript or JavaScript programs that take some action based on the type of event and perhaps the state or value of some object's parameters. This functionality allows developers to break through the constraints of older HTML and browser technology to create applications that perform the following functions:
All of this can be done strictly on the client side without communication with the server, until a form requires the application-specific processing the server provides (for example, database queries, interacting with a search engine such as Microsoft's Index Server, or other functionality provided by CGI and ISAPI programs).
http://www.microsoft.com/vbscript
This site includes links to VBScript examples that illustrate how VBScript can be incorporated along with HTML 3.2 form objects and ActiveX controls to jazz up your Web applications. There are also links to a VBScript FAQ and a downloadable tutorial and language reference.
An intuitive and aesthetically pleasing layout is part of a well-conceived and well-designed form. In the past, HTML has not been the best development environment when it came to satisfying the need for a form layout to be much more complex than a set of controls laid out in horizontal and vertical lines. However, three events have changed this situation dramatically:
Using HTML Tables Figure 14.2 illustrates a form with several intrinsic HTML controls
laid out using multiple nested HTML tables. Previously, developing such a form by
hand would take a substantial amount of time. However, development tools now make
developing such form layouts possible in a few minutes. Listing 14.1 provides the
code for this form.
FIGURE
14.2. A form layout that utilizes nested
HTML tables.
Listing 14.1. HTML Code for the Form Illustrated in Figure 14.2.
<html> <head> <title>HTML Controls Formatted Using a TABLE</title> </head> <body bgcolor="#FFFFFF"> <p align="center"><font size="4" face="Book Antiqua"><strong>HTML Controls Formatted Using a <TABLE></strong></font></p> <div align="center"><center> <form method="POST"> <table border="1" width="50%" bordercolor="#000000"> <tr> <td width="50%" bgcolor="#98DCDA"> <p><input type="radio" checked name="R1" value="V1">Option Group 1</p> </td> <td width="50%" bgcolor="#98DCDA"><input type="radio" name="R1" value="V2">Option Group 2</td> </tr> <tr> <td width="50%"><div align="center"><center> <table border="0" width="100%"> <tr> <td width="25%"> </td> <td width="75%"><div align="center"><center> <table border="0"> <tr> <td width="100%"><input type="checkbox" name="R1C1" value="ON"></td> <td><strong>Selection 1</strong></td> </tr> <tr> <td width="100%"><input type="checkbox" name="R1C2" value="ON"></td> <td><strong>Selection 2</strong></td> </tr> <tr> <td width="100%"><input type="checkbox" name="R1C3" value="ON"></td> <td><strong>Selection 3</strong></td> </tr> <tr> <td><input type="checkbox" name="R1C4" value="ON"></td> <td><strong>Selection 4</strong></td> </tr> </table> </center></div></td> </tr> </table> </center></div></td> <td width="50%"><div align="center"><center> <table border="0" width="100%"> <tr> <td width="25%"> </td> <td width="75%"><div align="center"><center> <table border="0"> <tr> <td width="100%"><input type="checkbox" name="R2C1" value="ON"></td> <td><strong>Selection 1</strong></td> </tr> <tr> <td width="100%"><input type="checkbox" name="R2C2" value="ON"></td> <td><strong>Selection 2</strong></td> </tr> <tr> <td width="100%"><input type="checkbox" name="R2C3" value="ON"></td> <td><strong>Selection 3</strong></td> </tr> <tr> <td><input type="checkbox" name="R2C4" value="ON"></td> <td><strong>Selection 4</strong></td> </tr> </table> </center></div></td> </tr> </table> </center></div></td> </tr> </table> </form> </center></div> </body> </html>
Using the HTML Layout Control The HTML layout control was designed to give developers a fine level of control over the layout and placement of HTML-intrinsic controls, ActiveX controls, and other objects on an HTML page. Essentially, the layout control provides a container for several objects. This container is then inserted as an object within your HTML document. The following template illustrates how an HTML layout is inserted into an HTML document:
<html> <head> <title> </title> </head> ... other HTML here ... <!-- Insert HTML Layout Control here --> <object id="object_id" classid="CLSID:class_id" align="baseline" border="0" style="LEFT:0;TOP:0"> <param name="ALXPATH" valuetype="ref" value="file:drive:\fullpath\filename.alx"> </object> ... other HTML here ... </body> </html>
Tools such as the HTML Control Pad by Microsoft provide a visual tool for inserting objects onto a layout and fine-tuning the placement of these objects. The Control Pad enables the developer to drag and drop controls on a grid in a manner similar to developing forms in Visual Basic. The resulting layout is stored in an .alx file that is then referenced in an HTML document. All controls (as well as their methods and properties) can be referenced within VB scripts attached to the HTML document. An example of this is shown in the last section of this chapter.
Figure 14.3 shows a form that uses an HTML layout to emulate the formatting of
the table shown in Figure 14.2. The code for this form is shown in Listings 14.2
and 14.3.
FIGURE
14.3. A form constructed using the HTML
layout control.
Listing 14.2. HTML Code for the Form Illustrated in Figure 14.3.
<html> <head> <title>controls.htm</title> </head> <body bgcolor="#FFFFFF"> <p align="center"><font size="5"> <strong>HTML Controls Formatted Using <br> an HTML Layout Control</strong></font></p> <p> <center> <object id="controls_alx" classid="CLSID:812AE312-8B8E-11CF-93C8-00AA00C08FDF" align="baseline" border="0" style="LEFT:0;TOP:0"> <param name="ALXPATH" valuetype="ref" value="file:D:\HTMLLayoutDir\controls.alx"> </object> </center> </p> </body> </html>
Listing 14.3. Code for the HTML Layout Control (controls.alx) Referenced in Listing 14.2.
<DIV BACKGROUND="#ffffff" ID="Layout1" STYLE="LAYOUT:FIXED;WIDTH:329pt;HEIGHT:218pt;"> <OBJECT ID="OptionButton1" CLASSID="CLSID:8BD21D50-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:25pt;LEFT:41pt;WIDTH:95pt;HEIGHT:18pt;TABINDEX:0;ZINDEX:0;"> <PARAM NAME="BackColor" VALUE="14079914"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="5"> <PARAM NAME="Size" VALUE="3360;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Option Group 1"> <PARAM NAME="GroupName" VALUE="R1"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="OptionButton2" CLASSID="CLSID:8BD21D50-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:25pt;LEFT:149pt;WIDTH:89pt;HEIGHT:18pt;TABINDEX:1;ZINDEX:1;"> <PARAM NAME="BackColor" VALUE="14079914"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="5"> <PARAM NAME="Size" VALUE="3122;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Option Group 2"> <PARAM NAME="GroupName" VALUE="R1"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R1C2" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:66pt;LEFT:58pt;WIDTH:75pt;HEIGHT:18pt;TABINDEX:2;ZINDEX:2;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2646;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 2"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R1C4" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:99pt;LEFT:58pt;WIDTH:74pt;HEIGHT:18pt;TABINDEX:3;ZINDEX:3;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2619;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 4"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R1C3" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:83pt;LEFT:58pt;WIDTH:76pt;HEIGHT:18pt;TABINDEX:4;ZINDEX:4;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2672;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 3"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R1C1" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:50pt;LEFT:58pt;WIDTH:71pt;HEIGHT:18pt;TABINDEX:5;ZINDEX:5;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2514;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 1"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R2C4" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:99pt;LEFT:165pt;WIDTH:76pt;HEIGHT:18pt;TABINDEX:6;ZINDEX:6;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2672;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 4"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R2C3" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:83pt;LEFT:165pt;WIDTH:77pt;HEIGHT:18pt;TABINDEX:7;ZINDEX:7;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2699;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 3"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R2C2" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:66pt;LEFT:165pt;WIDTH:75pt;HEIGHT:18pt;TABINDEX:8;ZINDEX:8;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2646;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 2"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="R2C1" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:50pt;LEFT:165pt;WIDTH:75pt;HEIGHT:18pt;TABINDEX:9;ZINDEX:9;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2646;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Selection 1"> <PARAM NAME="FontName" VALUE="Book Antiqua"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> </DIV>
This example showed you how to emulate the formatting of the table shown in the previous example. Unlike tables, however, formatting provided by the HTML layout control is not limited to placing objects in rows and columns. You could just as easily lay out the controls in a circular pattern or any other format you want. You can even overlay controls on top of each other if you wish. This technique can be used in conjunction with the ActiveX shape controls to create visually appealing forms that use colored shapes as backdrops to controls placed on a page. This backdrop object can be a variety of shapes and, if used properly, can emphasize logical groupings of controls.
In this section you get a glimpse of the greatly improved functionality and interactiveness that ActiveX controls and VBScript can bring to your applications. This example illustrates the construction of a form used to submit a query to Microsoft's Index Server (a content-indexing search engine tool for IIS). Several familiar HTML form objects are used along with the following ActiveX controls:
Figure 14.4 illustrates the Index Server query form created for this example.
FIGURE
14.4. An Index Server Query form implementing
ActiveX controls and VBScript subroutines to respond to user actions.
A few notes about this form:
FIGURE 14.5. VBScript MsgBox used to warn users when they select a time-consuming search using the form shown in Figure 14.4.
http://www.microsoft.com/frontpage
Listing 14.4 is a full listing for the HTML and VBScript code used to develop the form in Figure 14.4.
Listing 14.4. HTML and VBScript Code for the Index Server Query Form Shown in Figure 14.4.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <meta name="GENERATOR" content="Microsoft FrontPage 2.0"> <title>Index Server Query Form</title> </head> <body bgcolor="#FFFFFF"> <p align="center"> <font color="#0000A8" size="5" face="Wide Latin"><strong>I</strong></font><font color="#0000A8" size="4" face="Wide Latin"><strong>NDEX </strong></font><font color="#0000A8" size="5" face="Wide Latin"><strong>S</strong></font><font color="#0000A8" size="4" face="Wide Latin"><strong>ERVER </strong></font><font color="#0000A8" size="5" face="Wide Latin"><strong>Q</strong></font><font color="#0000A8" size="4" face="Wide Latin"><strong>UERY </strong></font><font color="#0000A8" size="5" face="Wide Latin"><strong>F</strong></font><font color="#0000A8" size="4" face="Wide Latin"><strong>ORM</strong></font></p> <form action="/scripts/vbtest.idq" method="GET" name="MainForm"> <div align="center"><center> <table border="1" bgcolor="#A4B0BD" bordercolor="#008080" bordercolordark="#008080" bordercolorlight="#008080"> <tr> <td align="center"><div align="center"><center> <table border="1" cellspacing="1" bgcolor="#A4B0BD" bordercolor="#008080" bordercolordark="#008080" bordercolorlight="#008080"> <tr> <td align="center"><font color="#FFFFFF" size="3" face="Arial"><strong>Enter a query restriction below</strong></font><font color="#FFFFFF" size="4" face="Arial">:</font> </td> <td align="right"> <input type="checkbox" name="cbEnum" value="ON"> <strong>Allow Enumerated Search?</strong> </td> </tr> <tr> <td colspan="2" width="80%"> <input type="text" size="85" maxlength="100" name="CiRestriction"> </td> </tr> </table> </center></div></td> </tr> <tr> <td align="center"><div align="center"><center> <table border="0"> <tr> <td align="center" width="50%"> <input type="radio" checked name="rbbool" value="AND"> <font face="Wide Latin"><strong>AND </strong></font> </td> <td align="center" width="50%"> <input type="radio" name="rbbool" value="OR"><font face="Wide Latin"><strong>OR</strong></font> </td> </tr> </table> </center></div></td> </tr> <tr> <td align="center"><div align="center"><center> <table border="0"> <tr> <td align="center" width="33%"><font size="3" face="Wide Latin"><strong>Filesize</strong></font> </td> <td align="center" width="20%"> <object id="lblInequal" name="lblInequal" classid="clsid:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" align="middle" border="0" width="16" height="24"> <param name="ForeColor" value="128"> <param name="BackColor" value="16777215"> <param name="Caption" value=">"> <param name="Size" value="423;635"> <param name="FontName" value="Wide Latin"> <param name="FontEffects" value="1073741825"> <param name="FontHeight" value="360"> <param name="FontCharSet" value="0"> <param name="FontPitchAndFamily" value="2"> <param name="FontWeight" value="700"> </object> </td> <td align="center" width="34%"><div align="center"><center> <table border="1" bgcolor="#A4B0BD" bordercolor="#008080" bordercolordark="#008080" bordercolorlight="#008080"> <tr> <td align="center" width="8%"> <object id="btnFSize" name="btnFSize" classid="clsid:79176FB0-B7F2-11CE-97EF-00AA006D2776" align="baseline" border="0" width="16" height="31"> <param name="Size" value="418;781"> <param name="Min" value="5000"> <param name="Max" value="100000"> <param name="Position" value="5000"> <param name="SmallChange" value="10000"> </object> </td> <td align="center" width="20%"> <object id="txtFSize" name="txtFSize" classid="clsid:8BD21D10-EC42-11CE-9E0D-00AA006002F3" align="baseline" border="0" width="127" height="25"> <param name="VariousPropertyBits" value="746604571"> <param name="BackColor" value="13290186"> <param name="ForeColor" value="3084984"> <param name="BorderStyle" value="1"> <param name="Size" value="3329;670"> <param name="SpecialEffect" value="0"> <param name="FontName" value="Wide Latin"> <param name="FontEffects" value="1073741825"> <param name="FontHeight" value="240"> <param name="FontCharSet" value="0"> <param name="FontPitchAndFamily" value="2"> <param name="ParagraphAlign" value="2"> <param name="FontWeight" value="700"> </object> </td> </tr> </table> </center></div></td> <td><font size="4" face="Wide Latin"> <strong>Bytes</strong></font> </td> </tr> </table> </center></div></td> </tr> <tr> <td align="center"><input type="submit" value="Execute Query"> <input type="reset" name="1" value="Clear"> </td> </tr> </table> </center></div><p align="center"> </p> <p align="center"> </p> <p align="center"> </p> <p align="center"> </p> <p align="center"> </p> <p align="center"> </p> </form> <script language="VBScript"> <!-- Dim F Set F = Document.MainForm btnMin = 5000 btnMax = 100000 F.btnFSize.value = btnMin F.txtFSize.value = btnMin sub btnFSize_SpinUp F.txtFSize.value = F.btnFSize.value end sub sub btnFSize_SpinDown F.txtFSize.value = F.btnFSize.value end sub sub lblInequal_Click if F.lblInequal.caption = ">" then F.lblInequal.caption = "<" else F.lblInequal.caption = ">" end if end sub sub cbEnum_OnClick if F.cbEnum.Checked then MsgBox "Please be advised that enumerated searches can take a long time  to complete and use valuable system resources. If an enumerated  search is not absoultely required, please change your selection" end if end sub --> </script> </body> </html>
Don't be fazed by the reference to an .idq file in the ACTION attribute for the form. This is simply a file used by Index Server to consolidate form content (passed to the server when the form is submitted) and then pose a query to the search engine.
In this section we pull together several of the concepts presented in earlier
sections of this chapter to show you how to construct an interactive database query
form using VBScript, ActiveX controls, and the HTML layout control. This example
illustrates the construction of a form used to submit a query to the Microsoft SQL
Server pubs database. The database query form can be seen in Figure 14.6.
FIGURE
14.6. The database query form used to
query the MS SQL Server pubs database.
An HTML layout control is used as a container for controls that will collect user input that is subsequently sent to the server and used to pose a query to the database. The following types of ActiveX controls are contained on the layout:
These controls are used to enter information such as author names, book titles, book categories, and price information that will be read by VB scripts attached to the main HTML form and submitted to the server to formulate a query to the pubs database. This simple form provides great flexibility in the types of queries and clauses that can be constructed.
Figure 14.7 illustrates how the layout looks during construction using the HTML
Control Pad.
FIGURE
14.7. The construction of the HTML layout
used in the database query form shown in Figure 14.6.
The code created by the HTML Control Pad is shown in Listing 14.5.
Listing 14.5. Code for the HTML Layout (pubs_query_layout.alx) Used by the Pubs Database Query Form Shown in Figure 14.6.
<!-- pub_query_layout.alx ALX HTML Layout and VBScript for Controls held within pubs_query.htm database query form created Feb 1997 - Drew Kittel --> <SCRIPT LANGUAGE="VBScript"> <!-- `Add menu items and set the default value displayed Sub pub_query_layout_OnLoad() call cboTitle.AddItem("like", 0) call cboTitle.AddItem("in", 1) call cboTitle.AddItem("=", 2) cboTitle.value = "like" call cboAuthor.AddItem("like", 0) call cboAuthor.AddItem("in", 1) call cboAuthor.AddItem("=", 2) cboAuthor.value = "like" end sub --> </SCRIPT> <DIV BACKGROUND="#ffffff" ID="pub_query_layout" STYLE="LAYOUT:FIXED;WIDTH:386pt;HEIGHT:234pt;"> <OBJECT ID="lblTitle" CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:5pt;LEFT:6pt;WIDTH:71pt;HEIGHT:17pt;ZINDEX:0;"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="Caption" VALUE="Book Title:"> <PARAM NAME="Size" VALUE="2505;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="txtTitle" CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:3pt;LEFT:170pt;WIDTH:207pt;HEIGHT:17pt;TABINDEX:1;ZINDEX:1;"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="Size" VALUE="7303;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> <OBJECT ID="lblAuthor" CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:55pt;LEFT:6pt;WIDTH:110pt;HEIGHT:17pt;ZINDEX:2;"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="Caption" VALUE="Author Lastname:"> <PARAM NAME="Size" VALUE="3881;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="txtAuthor" CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:55pt;LEFT:169pt;WIDTH:209pt;HEIGHT:17pt;TABINDEX:3;ZINDEX:3;"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="Size" VALUE="7373;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> <OBJECT ID="optAND1" CLASSID="CLSID:8BD21D50-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:30pt;LEFT:6pt;WIDTH:41pt;HEIGHT:18pt;TABINDEX:4;ZINDEX:4;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="5"> <PARAM NAME="Size" VALUE="1446;635"> <PARAM NAME="Value" VALUE="1"> <PARAM NAME="Caption" VALUE="AND"> <PARAM NAME="GroupName" VALUE="Group1"> <PARAM NAME="FontEffects" VALUE="1073741827"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="optOR1" CLASSID="CLSID:8BD21D50-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:30pt;LEFT:47pt;WIDTH:36pt;HEIGHT:18pt;TABINDEX:5;ZINDEX:5;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="5"> <PARAM NAME="Size" VALUE="1270;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="OR"> <PARAM NAME="GroupName" VALUE="Group1"> <PARAM NAME="FontEffects" VALUE="1073741827"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="lblCat" CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:104pt;LEFT:6pt;WIDTH:71pt;HEIGHT:17pt;ZINDEX:6;"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="Caption" VALUE="Categories:"> <PARAM NAME="Size" VALUE="2505;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="chk1" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:104pt;LEFT:113pt;WIDTH:140pt;HEIGHT:18pt;TABINDEX:7;ZINDEX:7;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="4939;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="WWW DB Development"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="chk2" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:121pt;LEFT:113pt;WIDTH:130pt;HEIGHT:18pt;TABINDEX:8;ZINDEX:8;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="4586;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Internet Programming"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="chk3" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:137pt;LEFT:113pt;WIDTH:116pt;HEIGHT:18pt;TABINDEX:9;ZINDEX:9;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="4092;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="General Computing"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="chk4" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:154pt;LEFT:113pt;WIDTH:108pt;HEIGHT:18pt;TABINDEX:10;ZINDEX:10;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="3810;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="General Business"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="chk5" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:170pt;LEFT:113pt;WIDTH:63pt;HEIGHT:18pt;TABINDEX:11;ZINDEX:11;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="2223;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Cooking"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="chk6" CLASSID="CLSID:8BD21D40-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:187pt;LEFT:113pt;WIDTH:99pt;HEIGHT:18pt;TABINDEX:12;ZINDEX:12;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="16292154"> <PARAM NAME="DisplayStyle" VALUE="4"> <PARAM NAME="Size" VALUE="3493;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="Other (specify)"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="txtOther" CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:187pt;LEFT:204pt;WIDTH:173pt;HEIGHT:17pt;TABINDEX:13;ZINDEX:13;"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="Size" VALUE="6103;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> <OBJECT ID="optAND2" CLASSID="CLSID:8BD21D50-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:80pt;LEFT:6pt;WIDTH:41pt;HEIGHT:18pt;TABINDEX:14;ZINDEX:14;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="5"> <PARAM NAME="Size" VALUE="1446;635"> <PARAM NAME="Value" VALUE="1"> <PARAM NAME="Caption" VALUE="AND"> <PARAM NAME="GroupName" VALUE="Group2"> <PARAM NAME="FontEffects" VALUE="1073741827"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="optOR2" CLASSID="CLSID:8BD21D50-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:80pt;LEFT:47pt;WIDTH:36pt;HEIGHT:18pt;TABINDEX:15;ZINDEX:15;"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="ForeColor" VALUE="2147483666"> <PARAM NAME="DisplayStyle" VALUE="5"> <PARAM NAME="Size" VALUE="1270;635"> <PARAM NAME="Value" VALUE="0"> <PARAM NAME="Caption" VALUE="OR"> <PARAM NAME="GroupName" VALUE="Group2"> <PARAM NAME="FontEffects" VALUE="1073741827"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="lblPrice" CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:212pt;LEFT:6pt;WIDTH:73pt;HEIGHT:17pt;ZINDEX:16;"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="Caption" VALUE="Unit Price:"> <PARAM NAME="Size" VALUE="2575;600"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="lblInEqual" CLASSID="CLSID:978C9E23-D4B0-11CE-BF2D-00AA003F40D0" STYLE="TOP:206pt;LEFT:116pt;WIDTH:14pt;HEIGHT:22pt;ZINDEX:17;"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="BackColor" VALUE="16777215"> <PARAM NAME="Caption" VALUE="<"> <PARAM NAME="Size" VALUE="511;767"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="400"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> <OBJECT ID="cboTitle" CLASSID="CLSID:8BD21D30-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:3pt;LEFT:117pt;WIDTH:46pt;HEIGHT:17pt;TABINDEX:18;ZINDEX:18;"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="DisplayStyle" VALUE="3"> <PARAM NAME="Size" VALUE="1623;600"> <PARAM NAME="MatchEntry" VALUE="1"> <PARAM NAME="ShowDropButtonWhen" VALUE="2"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> <OBJECT ID="txtPrice" CLASSID="CLSID:8BD21D10-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:209pt;LEFT:140pt;WIDTH:53pt;HEIGHT:17pt;TABINDEX:19;ZINDEX:19;"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="Size" VALUE="1870;600"> <PARAM NAME="Value" VALUE="50.00"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> <OBJECT ID="cboAuthor" CLASSID="CLSID:8BD21D30-EC42-11CE-9E0D-00AA006002F3" STYLE="TOP:55pt;LEFT:117pt;WIDTH:45pt;HEIGHT:17pt;TABINDEX:20;ZINDEX:20;"> <PARAM NAME="VariousPropertyBits" VALUE="746604571"> <PARAM NAME="DisplayStyle" VALUE="3"> <PARAM NAME="Size" VALUE="1588;600"> <PARAM NAME="MatchEntry" VALUE="1"> <PARAM NAME="ShowDropButtonWhen" VALUE="2"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontHeight" VALUE="240"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> </OBJECT> </DIV> <SCRIPT LANGUAGE="VBScript"> <!-- ` Change direction of inequality when clicked ` on by user sub lblInEqual_Click if lblInEqual.caption = ">" then lblInEqual.caption = "<" else lblInEqual.caption = ">" end if end sub --> </SCRIPT>
There is something very significant here that has not been explicitly pointed out previously. Not only is it possible to attach VB scripts to controls in your HTML files, it is also possible, as shown in the example, to attach scripts to the layout object itself and to objects within the layout. Listing 14.5 contains two such scripts. The script at the beginning of the file (pub_query_layout_OnLoad()) is invoked by the layout control's OnLoad event and is responsible for loading options into the ComboBox control using the AddItem method. It also presets the value property that is initially displayed. The script at the end of the file (lblInEqual_Click) is used to toggle the displayed value of the inequality (<, >) label when the user clicks it.
A Microsoft Forms 2.0 CommandButton control is included in the HTML form that holds the layout control. The event procedure (btnSubmit_Click()) associated with this button is used to perform validation and checking of user entries to the fields on the form as well as invoke the form's submit method in order to submit the form to the server for processing. Doing things in this manner allows you to execute the code necessary to validate input and inhibit submission of the form should any problems be detected. This would not have been possible using an intrinsic HTML SUBMIT button type.
The HTML and VBScript code for this form (refer to Figure 14.6) is shown in Listing 14.6.
Listing 14.6. HTML and VBScript Code for the pubs database query form Shown in Figure 14.6.
<!-- pubs_query.htm - Database query form Contains HTML Layout, HTML controls and VBScript for Controls Created Feb 1997 - Drew Kittel --> <html> <HEAD> <title>Publisher's Query Page</title> </HEAD> <BODY bgcolor="#FFFFFF"> <DIV align="center"> <center> <table border="0" width="100%"> <tr> <td align="center" width="10%"> <IMG src="books.gif" width="64" height="64"> </td> <td width="50%"><font color="#0000FF" size="6" face="Arial"> <strong>Publisher's Query Page</strong></font> </td> </tr> </table> </center> </DIV> <hr> <p align="center"><font size="4" face="Arial"><em><strong> Use the following form to query our extensive book database and view abstracts and summaries of books matching your search criteria. </strong></em></font></p> <FORM ACTION="http://dkittel.clark.net:8080/cgi-win/process_form_demo.exe" METHOD="POST" NAME="QFORM"> <center> <table border="1" width="80%" bordercolor="#0000FF"> <tr> <td align="center"> <OBJECT ID="qform_layout" CLASSID="CLSID:812AE312-8B8E-11CF-93C8-00AA00C08FDF"> <PARAM NAME="ALXPATH" REF VALUE="pub_query_layout.alx"> </OBJECT> </td> </tr> <TR> <TD ALIGN=CENTER bgcolor="#70BBF3"> <OBJECT ID="btnSubmit" WIDTH=115 HEIGHT=32 CLASSID="CLSID:D7053240-CE69-11CD-A777-00DD01143C57"> <PARAM NAME="ForeColor" VALUE="16711680"> <PARAM NAME="BackColor" VALUE="13750737"> <PARAM NAME="Caption" VALUE="SUBMIT QUERY"> <PARAM NAME="Size" VALUE="3037;846"> <PARAM NAME="FontName" VALUE="Arial"> <PARAM NAME="FontEffects" VALUE="1073741825"> <PARAM NAME="FontHeight" VALUE="200"> <PARAM NAME="FontCharSet" VALUE="0"> <PARAM NAME="FontPitchAndFamily" VALUE="2"> <PARAM NAME="ParagraphAlign" VALUE="3"> <PARAM NAME="FontWeight" VALUE="700"> </OBJECT> </TD> </TR> </table> </center> <! -- preset hidden form variables used to send user input on Submit --> <INPUT TYPE=hidden NAME="TITLE" value=" "> <INPUT TYPE=hidden NAME="TITLEOP" value=" "> <INPUT TYPE=hidden NAME="TITLECLAUSE" value=" "> <INPUT TYPE=hidden NAME="AUTHOR" value = " "> <INPUT TYPE=hidden NAME="AUTHOROP" value = " "> <INPUT TYPE=hidden NAME="AUTHORCLAUSE" value=" "> <INPUT TYPE=hidden NAME="CAT1" value = "OFF"> <INPUT TYPE=hidden NAME="CAT2" value = "OFF"> <INPUT TYPE=hidden NAME="CAT3" value = "OFF"> <INPUT TYPE=hidden NAME="CAT4" value = "OFF"> <INPUT TYPE=hidden NAME="CAT5" value = "OFF"> <INPUT TYPE=hidden NAME="CAT6" value = "OFF"> <INPUT TYPE=hidden NAME="CATOTHER" value = "OFF"> <INPUT TYPE=hidden NAME="INEQUALITY" value = " "> <INPUT TYPE=hidden NAME="PRICE" value = " "> </FORM> <SCRIPT LANGUAGE="VBScript"> <!-- `'''''''''''''''''''''''''''''''''''''''''''' ` Check if field has data or is empty `'''''''''''''''''''''''''''''''''''''''''''' Function ValidateTextField(formField, warnMessage) if Len(formField.Value) = 0 then alert warnMessage ValidateTextField = 0 exit Function end if ValidateTextField = 1 End Function `''''''''''''''''''''''''''''''''''''''''''''''''' ` This code is executed by a button click. ` Execution is prior to sending form contents ` via submit method `''''''''''''''''''''''''''''''''''''''''''''''''' Sub btnSubmit_Click() Dim F Set F = Document.QFORM ` Alert user that some field data may be missing (not ` that they are necessarily needed for the current query) dummy = ValidateTextField(F.qform_layout.txtTitle, "Title field is empty") dummy = ValidateTextField(F.qform_layout.txtAuthor, "Author field is empty") ` Don't allow submit if price is missing or < 0 if ValidateTextField(F.qform_layout.txtPrice, "You must supply a Price Âvalue!") = 0 then exit sub end if if F.qform_layout.txtPrice.Value < 0 then alert "Price value must be a positve number. Re-enter a value and Âre-submit the form" exit sub end if ` Obtain values of controls on HTML Layout Control ` and set hidden variables for submit to CGI program F.TITLE.value = F.qform_layout.txtTitle.Value F.TITLEOP.value = F.qform_layout.cboTitle.Value F.AUTHOR.value = F.qform_layout.txtAuthor.Value F.AUTHOROP.value = F.qform_layout.cboAuthor.Value F.INEQUALITY.value = F.qform_layout.lblInEqual.Caption F.PRICE.value = F.qform_layout.txtPrice.Value ` set boolean operators if F.qform_layout.optAND1.value = 0 then F.TITLECLAUSE.value = "AND" else F.TITLECLAUSE.value = "OR" end if if F.qform_layout.optAND2.value = 0 then F.AUTHORCLAUSE.value = "AND" else F.AUTHORCLAUSE.value = "OR" end if ` Create and echo a SQL-like query statement that illustrates to user ` what query will be used to query the database at the server. ` Ask user if this is correct and inhibit the submit if NO sqlQuery = "SELECT title, price" + Chr(13) + "FROM pubs..titles" + ÂChr(13) + "WHERE" + Chr(13) tClause = " title" + " " + F.TITLEOP.value + " " + F.TITLE.value + " " + ÂF.TITLECLAUSE.value +Chr(13) aClause = " author" + " " + F.AUTHOROP.value + " " + F.AUTHOR.value + Â " " + F.AUTHORCLAUSE.value +Chr(13) pClause = " price" + " " + F.INEQUALITY.value + " " + F.PRICE.value + Â " " + Chr(13) + Chr(13) ` Determine what checkboxes are selected ` continue creation of SQL-like statement to echo typeClause = " type in (" if F.qform_layout.chk1.value = True then F.CAT1.value = F.qform_layout.chk1.Caption typeClause = typeClause + F.qform_layout.chk1.Caption + ", " end if if F.qform_layout.chk2.value = True then F.CAT2.value = F.qform_layout.chk2.Caption typeClause = typeClause + F.qform_layout.chk2.Caption + ", " end if if F.qform_layout.chk3.value = True then F.CAT3.value = F.qform_layout.chk3.Caption typeClause = typeClause + F.qform_layout.chk3.Caption + ", " end if if F.qform_layout.chk4.value = True then F.CAT4.value = F.qform_layout.chk4.Caption typeClause = typeClause + F.qform_layout.chk4.Caption + ", " end if if F.qform_layout.chk5.value = True then F.CAT5.value = F.qform_layout.chk5.Caption typeClause = typeClause + F.qform_layout.chk5.Caption + ", " end if if F.qform_layout.chk6.value = True then F.CATOTHER.value = F.qform_layout.txtOther.Value typeClause = typeClause + F.qform_layout.txtOther.Value + ", " end if typeClause = typeClause + " )" + Chr(13) ` Finish formulating query and prompt user to validate it ` if user clicks on No button, exit the sub without submit ` of form. Otherwise submi the form. sqlQuery = sqlQuery + tClause + aClause + typeClause + pClause sqlMessage = "Your are about to send the following query" + Chr(13) + Chr(13) sqlMessage = sqlMessage + sqlQuery + "Is this correct?" if MsgBox(sqlMessage, vbYesNo, "Validate Query") = vbNo then exit sub end if ` SUBMIT call Document.QFORM.Submit() end sub --> </SCRIPT> </BODY> </html>
Here are a few things to note about this example:
FIGURE 14.8.This message box asks the user to validate that the SQL query constructed is what the user intended.
FIGURE 14.9.The form content (that is, field name and value pairs) received at the server when the form shown in Figure 14.6 is submitted.
The goal of this chapter was to show you how to employ HTML 3.2 objects, ActiveX controls, and VBScript to develop form interfaces for your Web database and other applications and to make them far more interactive and functional than those created with HTML 2.0 alone.
We started the chapter by showing you how VB scripts are attached to HTML documents, associated with certain events, and then executed when those events occur. Next, we presented an overview of the Internet Explorer object model for scripting and showed numerous examples of how component objects, events, methods, and procedures can be accessed by your VB scripts.
The final section of the chapter was dedicated to applying the material you learned in earlier sections. We demonstrated how to format form objects and content using HTML tables as well as the HTML layout control. We also presented two in-depth examples, a search engine query form and a database query form, which illustrated how tables and the HTML layout control can be used to create nice form layouts. We also demonstrated the power of combining VBScript, ActiveX, and HTML objects to create application user interfaces, complete with interactive responses to user actions, input validation, and submission of forms via VBScript.