You are on page 1of 188

/ASP

Annotated Examples
ANNOTATED EXAMPLES 1

CLARION/
ASP

Annotated
Examples
2 CLARION/ASP

COPYRIGHT 2002 by SoftVelocity Incorporated


All rights reserved.

This publication is protected by copyright and all rights are reserved by SoftVelocity Incorporated.
It may not, in whole or part, be copied, photocopied, reproduced, translated, or reduced to any
electronic medium or machine-readable form without prior consent, in writing, from SoftVelocity
Incorporated.

This publication supports Clarion 5.5. It is possible that it may contain technical or typographical
errors. SoftVelocity Incorporated provides this publication “as is,” without warranty of any
kind, either expressed or implied.

Revision 1.2 August 2002

SoftVelocity Incorporated
2769 East Atlantic Blvd.
Pompano Beach, Florida 33062
(954) 785-4555
www.softvelocity.com

Trademark Acknowledgements:
SoftVelocity  is a registered trademark of SoftVelocity Incorporated.
Clarion  is a trademark of SoftVelocity Incorporated.
Microsoft Windows and Visual Basic are registered trademarks of Microsoft Corporation.
All other products and company names are trademarks of their respective owners.

Printed in the United States of America


ANNOTATED EXAMPLES 3

Contents
INTRODUCTION 7
PRELIMINARY: SETUP 9
SQL Server 9
The Dictionary Changes 10
The /images Virtual Directory 11

SIMPLE ONE TABLE APP 13


Application Wizard ............................................................................................... 13
Applying the Global Extension ............................................................................. 14
Applying the Browse Extension ........................................................................... 16
Applying the Form Extension ............................................................................... 17
Generation and Setting Up IIS .............................................................................. 18
Testing the Application ......................................................................................... 19

THE TO DO LIST APPLICATION 23


Run the Application Wizard .................................................................................. 23
Set the Global Template Options .......................................................................... 25
Applying the Browse Template ............................................................................. 35
Applying the Form Template ................................................................................ 39
Generate the ASP Pages ........................................................................................ 44
Setup the IIS Virtual Directory ............................................................................. 44
Running Your First Test ........................................................................................ 45
Examining the HTML Frames .............................................................................. 48

SEARCH CONTACTS EXAMPLE 53


Run the Application Wizard .................................................................................. 53
Set the Global Template Options .......................................................................... 55
The BrowseviewContacts Procedure 61
Turning Off the Update Link ................................................................................ 66
The Orders Procedure 67
The Browse on the ProductPhotos View 72
The Update Procedures 74
4 CLARION/ASP

The Update Customers Form ................................................................................ 74


The Update Orders Form ...................................................................................... 75
The Update Suppliers Form .................................................................................. 75
The Update Employees Form ............................................................................... 76
The Update viewProductPhotos Form .................................................................. 77
Generate the ASP Pages ........................................................................................ 79
The Frames 79
The Search Frame ................................................................................................. 79
Generate the Project .............................................................................................. 82
Examining the Frame Set ...................................................................................... 82
The Main Frame.................................................................................................... 82
Setting Up the Virtual Directory in IIS ................................................................. 83
Running Your First Test ........................................................................................ 84
Testing the Search Frame ...................................................................................... 85

THE ORDERS EXAMPLE 87


Setup and Global Properties 87
General Tab ........................................................................................................... 88
Security Tab .......................................................................................................... 93
Administration Tab ............................................................................................... 94
Prep the Procedures 94
The Browse Procedures 95
Customize the BrowseProducts procedure: .......................................................... 95
Browse Customers Procedure ............................................................................... 98
The Browse Employees Procedure ....................................................................... 99
The Browse Orders Procedure ............................................................................ 101
The Browse View Order Details Extended Procedure ........................................ 104
The Browse Categories Procedure ...................................................................... 105
The Select Managers Procedure ......................................................................... 105
The Select Orders Procedure .............................................................................. 106
The Select Products Procedure ........................................................................... 107
The Update Procedures 108
The UpdateCategories Procedure ....................................................................... 108
The UpdateCustomers Procedure ....................................................................... 110
The UpdateEmployees Procedure ....................................................................... 112
The UpdateOrders Procedure ............................................................................. 114
The UpdateOrder_Details Procedure.................................................................. 117
The UpdateProducts Procedure .......................................................................... 118
ANNOTATED EXAMPLES 5

The UpdateShippers Procedure .......................................................................... 121


The UpdateSuppliers Procedure ......................................................................... 122
The ViewOrdersQuery Procedure ....................................................................... 124
Range Limits and "Duplicate" Browses 128
The BrowseOrders Procedure ............................................................................. 129
The BrowseProducts Procedure.......................................................................... 129
The BrowseView_Order_Details_Extended Procedure ..................................... 129
Copy the BrowseOrders Procedure .................................................................... 130
Copy the BrowseProducts Procedure ................................................................. 131

CUSTOMIZING GENERATED PAGES 133


The Categories Form with Filtered Products Browse Beneath 133
ViewOrdersQuery Form with the view_Order_Details_Extended Browse 136
Addendum: Priming a Listbox on Add 138
Introductory Page 139

PUBS EXAMPLE 141


ASP CODE WALKTHROUGH 143
Browse 143
Script Language and Notice ................................................................................ 143
Include Files........................................................................................................ 144
Global Overrides................................................................................................. 144
Variable Declarations .......................................................................................... 144
Debug Information.............................................................................................. 146
Prepare RecordSet and Session Variables ........................................................... 146
Column Sorts ...................................................................................................... 147
The Base SELECT Statement ............................................................................ 150
Appending WHERE and ORDER BY Clauses .................................................. 151
Checking for Reset or Locate Flags .................................................................... 151
Building the WHERE Clause .............................................................................. 152
Finishing the WHERE Clause............................................................................. 152
Open the RecordSet ............................................................................................ 152
More Debug Information .................................................................................... 153
Finish Up and Output ......................................................................................... 153
Function: NoRecordsFound ................................................................................ 154
Function:MergeBrowseProductsListTemplate .................................................... 155
Function: buildColumnLabels ............................................................................ 156
6 CLARION/ASP

Function: buildDataRows ................................................................................... 163


Function: BuildFooter ......................................................................................... 166
Edit/Update Page 169
Script Language and Notice ................................................................................ 169
Include Files and Declarations ............................................................................ 169
The MergeTemplate Function ............................................................................. 170
Open the Record Set ........................................................................................... 170
Function: displayBadRecord............................................................................... 171
MergeEditTemplate Function ............................................................................. 171
Get the Record .................................................................................................... 172
Set the Form Action ............................................................................................ 172
Get the Field Values ............................................................................................ 173
Display (or Not) the Delete Button ..................................................................... 174
Call the Merge Function and End ....................................................................... 174
The Edit Processor Page 174
Script Language and Notice ................................................................................ 175
Include Files........................................................................................................ 175
Variable Declarations and Open the Record Set ................................................. 175
The MergeTemplate Function ............................................................................. 176
Check for Not Found .......................................................................................... 176
Get the Record .................................................................................................... 177
Placing the Fields ................................................................................................ 178
Send the Data to the Merge ................................................................................. 182
ANNOTATED EXAMPLES 7

1. INTRODUCTION
This Annotated Examples manual consists of the following sections:

• Chapter 2, Part 1, SQL Server Setup walks you through attaching a


slightly modified “Northwind” database to your DBMS. Note that the
modifications consist of additional tables, views and triggers, and do not
alter any of the existing “Northwind” data except in one case: the images
in the “Categories” tables are stored in GIF format, not BMP, for
browser compatibility. Any existing samples from other programs which
you may have worked on or intend to work on should have no problem
accessing the sample data.
• Chapter 2, Part 2, Dictionary Changes, walks you through editing the
sample dictionary so that it reflects the connection to your server. This is
an optional step, because Clarion/ASP does not retrieve its connection
information from the dictionary.
• Chapter 2, Part 3, IIS /images virtual directory preps the virtual
directory for commonly used images, namely, the Clarion/ASP button
images.
• Chapter 3, the Single One Table App example shows you how to
generate a “bare minimum” Clarion/ASP app. Because Clarion/ASP
allows you to create a very rich interface, there are many design time
options in the template. This could be overwhelming to a new developer.
In this exercise, you’ll “wizard” up an app, apply the global extension
template, declare the ADO connection, then apply the template to a
browse and a form with no other options. The result will be a fully
functional but “plain” looking ASP application. The entire process
should only take a few minutes.
• Chapter 4, the To Do List Application example shows you a deceptively
simple application with lots of functionality, and introduces the topic of
“site integration.” It places the application inside an HTML frame (as
opposed to standing alone), and demonstrates the use of HTML
parameters to filter the data. Additionally, it demonstrates security and
the use of “My Records” to limit the viewing and editing of data to the
owner of that data.
• Chapter 5, the SearchContacts Application example introduces
concepts such as using “custom controls” for links which dynamically
call one procedure or another, or one filter or another based on record
contents. It makes extensive use of graphics, both from database fields
and external files. Finally, it illustrates the ability to edit the runtime
HTML templates, which is something many web designers are likely to
wish to do in order to “fine tune” the appearance of the application.
8 CLARION/ASP

• Chapter 6, the Orders example shows you advanced concepts such as


editing the generated ASP pages to actually change the functionality.
• Chapter 7, the final section provides an ASP code walkthrough,
describing what each section of the ASP code (browse, form, login, and
utility) actually do, and how they do it.
Before you begin, there are two important prerequisites:

• IIS must be set up on your machine, as per the section in the Users Guide
entitled Internet Information Server Setup.
• You should optionally (unless another developer in your shop has already
done this) have the MS SQL Enterprise Manager client tools installed on
your machine, along with rights to modify the Northwind sample
database on your server (You’ll be adding two tables using scripts
provided with Clarion/ASP.
• An HTML editor is an optional third “prerequisite,” but highly
recommended.
ANNOTATED EXAMPLES 9

2. PRELIMINARY: SETUP
SQL Server
Included in your installation, in the \c55\examples\asp directory, you’ll find
two modified Northwind demonstration databases: northwind.mdf, and
northwind.ldf, contained in a file called northwind database.zip.

Microsoft SQL Server 2000 allows you to copy a file to the database server
and attach. This is much simpler than running scripts to build the modified
database. MS SQL Server 7.0 allows something similar, though not quite as
conveniently.

The modifications in this database consist of additional tables, views and


triggers, and do not alter any of the existing “Northwind” data except in one
case: the images in the “Categories” tables are stored in GIF format instead
of BMP, for browser compatibility. Any existing programs which you may
have worked on or intend to work on should have no problem accessing the
sample data.

For SQL Server 2000 users, the process requires that you copy the attached
files to a directory on the server (you may not attach over the network to a
file on your local drive) to the directory in which you wish them permanently
to reside. You must also have the MS SQL Server Enterprise Client tools on
your desktop, if you wish to run the “attach” process from your desk.

These instructions are for MS SQL Server 2000. Instructions for MS SQL
Server 7.0 are included in the section “Applying the Global Extension,”
which is at the beginning of the exercise. (You’ll be using the OLE DB
Provider to “attach,” because the 7.0 Enterprise Manager client does not
support attaching a database.

Please unzip the files in the northwind database.zip to the server.

Once the file is copied to the server, do the following:


1. Open the MS SQL Server client software. (The MS SQL Server snap in
for the Microsoft Management Console).
2. Double click the correct SQL Server in the left pane of the Enterprise
Manager client so that you see the Databases folder, and the databases
below it.
3. Right click the Northwind database icon, and choose All Tasks >
Rename Database. Type in a new name such as Northwind2. Note: you
may have to stop the northwind database first.
10 CLARION/ASP

4. After renaming the old one, right click the Databases folder, and choose
All Tasks > Attach Database...
5. In the Attach Database dialog, type in the fully qualified file name (as
seen by the server) for the northwind.mdf file you copied to the server
(previously expanded from the zip file, and copied along with the LDF
file). Be sure, also, that the User ID and password that you type in this
dialog (as opposed to the runtime user, which you typed in the previous
box) has administrator privilege on the SQL Server. Please note also that
importing the .MDF and .LDF files does not permit us to import user
accounts! Be sure that your runtime user account is set up on the
machine! Depending on the SQL Server setup, you may also have to
grant access to the public group for the attached database!
6. Type in Northwind in the Attach As box.
7. Choose a database owner from the dropdown list. In default installations,
this should probably be the “sa” SQL administrator account.
8. Exit MMC when done.

The Dictionary Changes


Though this is an optional step, we highly recommend it. By storing this in
the dictionary, you can browse the tables using the dictionary editor, or
generate a desktop application to enter some data while constructing your
ASP application.

To substitute your server information:


1. With the Clarion developement environment open, choose File > Open.
2. In the Open File dialog, choose “Files of Type” Dictionary (*.DCT), and
open examples\asp\northwind.dct.

For each table listed in the left pane of the Dictionary Editor which then
opens:
3. Right-click and choose Properties. This opens the Edit Table Properties
dialog.
ANNOTATED EXAMPLES 11

4. In the Owner field, the three parameters are server name, database name,
and user name. Change the server and user names to those applicable to
your server, and press OK to close the Edit Table Properties dialog.

5. Save and close the Dictionary Editor when all tables are modified.

The /images Virtual Directory


Many sites store images to be used throughout the site in a single directory
off the root, usually called /images. This saves disk space because the image
files need not be repeated throughout. The Clarion/ASP button images are a
good candidate for storing in a central location because they are repeated
from application to application.

The install program copies the images to a default directory called


\C55\images\asp. This section instructs you to create a virtual directory
called images, pointing to that directory. If you already have a /images
virtual directory on your “localhost” site, you may simply copy the images to
it and skip over the following instructions:
1. Open up whichever of the IIS administrative tools is applicable to your
operating system. (Windows NT: Start > Programs > Administrative
Tools > Internet Services Manager; Windows 2000/XP: Start > Settings
> Control Panel > Administrative Tools > Internet Information Services).
2. In the left hand pane, locate an icon called “default web site” and expand
it (the node order should be something like: Internet Information
Services > your computer name > Web Sites > Default Web Site).
3. Right-click the default web site and choose New > Virtual Directory.
12 CLARION/ASP

4. Press the Next button, and when prompted, name for the virtual directory
“images.”
5. Press the Next button, and when prompted, navigate to your the
\C55\images\asp directory by pressing the Browse button. (or to
whatever the relative path should be if you installed Clarion to a
directory other than \C55.
Note: the Clarion/ASP install provides for a default set of blue buttons
(enabled), all 20 pixels by 20 pixels. Disabled state is grayscale images (of
the same buttons). Below the images directory, you'll find alternate button
sets in green and brown. Since the blue buttons are repeated in a
subdirectory, should you wish to experiment, you can simply copy over one
set of buttons with another.
ANNOTATED EXAMPLES 13

3. SIMPLE ONE TABLE APP


In this section you’ll generate an application and apply the minimum
changes necessary to implement a Clarion/ASP application. This assumes
that your Internet Information Server installation is set up properly, as
described in the Users Guide.

Application Wizard
Close any projects open in the Clarion development environment before
beginning.
1. From the Clarion development environment, choose File > New >
Application.
2. For the purposes of this exercise, we will assume that you have installed
Clarion to the default location, C55. In the Open File dialog which
opened upon the previous command, navigate to the C55\examples\asp
directory. Press the “New Folder” button in the Open File dialog. Name
the directory “MyASP” and double click it to open it. Once in the
directory, type “MyASP” in the file name box, thus creating a new .app
file called c:\c55\examples\asp\MyASP\MyASP.app. (Note: make sure
“Use QuickStart” is unchecked).
3. In the Application Properties dialog which appears, press the ellipsis
button next to the dictionary field, navigate one directory above, and
choose northwind.dct for the dictionary.

4. Be sure that the Application Wizard box is checked before pressing the
OK button to close the dialog. This launches the Application Wizard.
5. Choose the ABC Class application wizard in the first window; note that
Clarion/ASP may be applied to both ABC and Clarion template set
applications.
6. Press the Next button when the first, introductory panel of the wizard
appears.
7. Uncheck the “Generate Procedures for All Files in my Dictionary” box
on the next panel and press Next.
8. Select Products from the tables list in the next pane, and press Next.
14 CLARION/ASP

9. Click Next to pass the next panel (or two if using Enterprise). When you
arrive at the panel with the “Generate Reports for Each File” box,
uncheck that box and press Next until finished with the wizard.

Applying the Global Extension


You should now have a small application tree and are ready to apply the ASP
template. You’ll start with the global template extension:
1. From the development environment menu, choose Application > Global
Properties.
2. In the Global Properties dialog, press the Insert button.
3. In the Extension and Control Templates dialog, press the Insert button.
4. Choose the ASP Global Extension Template (class SV ASP) in the Select
Extension dialog and press the Select button.

You’ve now populated the global extension. There is only one required piece
of information: the connection information which will allow us to tell ADO
how to access the database:

1. While still in the Extension and Control Templates dialog, with the ASP
global extension selected, select the Database tab on the right side of the
dialog.
2. Press the Connection Properties button on this tab. The Connection
Properties dialog appears.
3. Enter a user name for the database.
4. Enter a password for the database. Do not be concerned with storing
these in the .app file; assuming you set up your web server properly,
ANNOTATED EXAMPLES 15

these items are not accessible to the end user because they never become
part of the HTML source that IIS sends to the browser; this strictly
remains on the server.

5. Press the Call Connection Builder button.


The Data Link Properties dialog now appears. If ADO and MDAC were not
installed with the operating system, they can be installed by Microsoft Office
or with the MS SQL Server Enterprise Manager software. Fill in the
properties as follows:
1. Select the Provider tab, if the dialog did not automatically open to it, and
choose Microsoft OLE DB Provider for SQL Server, then press the Next
button.
2. On the Connection tab, enter the server name, or choose it from the drop
list in item number 1.
3. Enter the user name and password for the database in item number 2.
4. Check the “Allow Saving Password box,” in number 2. You must not
skip this step, else Internet Information Server has no way to log into the
database.

5. Type “northwind” in the “Select the database on the server” box. Be sure
to test the connection by pressing the Test Connection button.
16 CLARION/ASP

5a. For MS SQL Server 6.5 users only: this is the point at which you attach
the database. Select the “Attach a database file as database name” radio
button, and type “northwind2” in the box below the radio button.
5b. Do not press the File Lookup button next to the “using the filename”
box. Instead, you must type in the fully qualified path on the server, not
your local machine, for the northwind.mdf file, which you must copy
there. You must also copy the northwind.ldf file. Be sure, also, that the
User ID and password that you type in this dialog (as opposed to the
runtime user, which you typed in the previous box) has administrator
privilege on the SQL Server. Please note also that importing the .MDF
and .LDF files does not permit us to import user accounts! Be sure that
your runtime user account is set up on the machine! Depending on the
SQL Server setup, you may also have to grant access to the public group
for the attached database! SQL Server 7.0 developers, please remember
that if this manual refers to the northwind database in any exercise, it
will actually be the northwind2 database for you.
6. Press the “Test Connection” button, and verify that you receive a success
message. If not, review the settings in this dialog.
7. Press the OK button to close the Data Link Properties dialog.
You should have now returned to the Connection Properties dialog, and a
connection string something like the one below should appear at the bottom
of this dialog:
Provider=SQLOLEDB.1;Password=YourPassword;Persist Security Info=True;User
ID=YourUsername;Data Source=YourDataServer

You may now close the global extension dialog:


1. Press the OK button to close the Connection Properties dialog.
2. Press the OK button to close the Extension and Control Templates
dialog.
3. Press the OK button to close the Global Properties dialog.

You should now have only the Application Tree dialog open. You are now
ready to apply the Browse extension.

Applying the Browse Extension


You may now apply the Browse extension to the browse on the Products
table:
1. Right click on the BrowseProducts procedure in the Application Tree
dialog and choose Extensions from the popup menu.
2. Press Insert when the Extension and Control Templates dialog appears.
ANNOTATED EXAMPLES 17

3. Choose ASP Browse from the Select Extension dialog and press the
Select button.

4. There are no further required items; therefore press OK to close the


Extension and Control Templates dialog.

Applying the Form Extension


You may now apply the From extension to the update procedure for the
Products table:
1. Right click on the UpdateProducts procedure in the Application Tree
dialog and choose Extensions from the popup menu.
2. Press Insert when the Extension and Control Templates dialog appears.
3. Choose ASP Form from the Select Extension dialog and press the Select
button.

The Clarion/ASP templates will attempt to create a link to a select browse


procedure for the Supplier and Category fields in this table, so that an end
user could press a lookup button and choose from a popup window list of
suppliers or categories. We’ll actually disable that in this example, to keep
the final applications as small and simple as possible.
4. Click the Controls tab in the ASP prompts.
5. Select the SupplierID field and press Properties.
6. Select the Validation tab in the Controls dialog.
7. Change the Client Side Validation dropdown list from Must be in File to
No Validation and press OK.
18 CLARION/ASP

8. Select the CategoryID field and press Properties.


9. Select the Validation tab in the Controls dialog.
10. Change the Client Side Validation dropdown list from Must be in File to
No Validation and press OK.
11. There are no further required items; therefore press OK twice to close the
Extension and Control Templates dialog.

Note: because MS SQL Server has a constraint on the SupplierID and


CategoryID columns, the data integrity will be maintained; all we did was
take off the client side check, and the server therefore would generate a
message should someone try to enter an illegal value.

Generation and Setting Up IIS


You’ve now applied all the necessary parts for a minimal ASP application.
The template has already created a link between the browse and the form.
You’re now ready to generate and test.
1. From the development environment menu, choose Project > Generate
All. This creates the necessary subdirectories, generates the ASP, HTM,
and CSS (cascading style sheets) files necessary for the product, and
copies images as necessary.
The output is placed in the project\asp directory, as well as directories
beneath it called HTML, images, and styles. Before you may test, however,
you must “tell” Internet Information Server where the application is:
1. From the Windows Start menu, choose Start > Programs >
Administrative Tools > Internet Information Services (the exact name
and location of the IIS configuration manager may vary slightly from
version to version of Windows.

2. Open each successive node in the tree pane at the left of the Internet
Information Services manager until you can see the “Default Web Site”
node.
ANNOTATED EXAMPLES 19

3. Right click on the “Default Web Site” node and from the popup menu,
choose New > Virtual Directory.
4. Press Next to skip past the introductory pane of the Virtual Directory
Wizard.
5. On the second pane, enter “MyASP” in the Alias box. This will serve as
the name for the virtual directory. Press Next.

6. Press the Browse button next to the Directory box on the next panel.
Browse to the application’s directory, then locate the asp directory
beneath it and select the asp directory. If you’ve installed to the default
Clarion directory and followed our suggestion for the application
directory name above, that directory should be
\C55\examples\asp\myasp\asp.

7. Press the Next button twice, and the Finish button, accepting the
defaults.

Testing the Application


Clarion/ASP generates a debug/test page to insure that the database access
has been properly defined. You may access this page through another page it
automatically generates, the index page. The index page is meant to serve as
a temporary table of contents so that the developer can test the individual
procedure pages before incorporating them into a site.

Note that it is very important that you do not copy the debug/test page to a
server visible on the Internet, as it will display your database server name,
user ID, and password.
20 CLARION/ASP

To test the application, load the index page, view the query/test page, then
load the browse and form procedures:
1. Open your browser, type http://localhost/myasp/index.htm in the address
box, and press enter. This should display the index page. At the top is a
link to the test page, then the browses (HTML tables), then the forms
(HTML forms).

2. Click on the MyASPTest.asp link to test the queries. If successful, the


last item in the results page will be the FileSystem system, and it will
display a “success” message.

3. Press the Back button in your browser to return to the index page.
4. Locate the link to BrowseProductsList.asp and click on it. A browse
table page should appear. Page through the table using the navigation
button bar at the bottom to test your access.
ANNOTATED EXAMPLES 21

5. A pencil graphic should appear in the right hand column of the browse
list. Click on any one of the graphics. An update form (view only) should
appear.

6. At the bottom of the update form another pencil graphic should appear.
Click on it. An editable update form should appear.

7. Change one of the less important column values (such as Units on Order)
and press the Submit button. An “Update Succeeded” message should
appear. Note: you will see ellipsis buttons next to the CategoryID and
SupplierID fields. Don’t bother pressing them; you’ve disabled the logic
and haven’t applied the ASP extension to the select browses. That will be
for a later lesson!
22 CLARION/ASP

8. Press the back button, so that you return to an edit form, and press the
help button. A popup window should appear with text at the bottom
instructing that you should have customized your help text.

You may now close your browser or return to your home page. You’ve
successfully created and tested a simple Clarion/ASP application. You may
now continue on to work with the example applications.
ANNOTATED EXAMPLES 23

4. THE TO DO LIST APPLICATION


This exercise walks you through setting up and running the “todo” list
example application. More than the traditional desktop “to do” application,
this example aims to be attractive, intelligent, and functional.

Note: If you’re not reading/doing the examples in this book in order, some of
these steps may seem repetitious, since you’re setting up access to the same
database, and a similar style sheet (but using different colors).

This application uses Clarion/ASP’s “My Records” feature, which filters all
recordsets so that one field must always match the user’s ID. That, in
combination with the use of where clauses from links in the frame allows for
flexible functionality with the use of only two procedures. Note that though
this exercise will create the Clarion/ASP application from scratch, the
HTML frames are provided in finished state.

The sample application will be installed to beneath your Clarion directory, in


examples\asp\northwind\todo. In addition to the sample file, several images
and an html design time template are located in the
examples\asp\northwind\todo\asp directory and subdirectories, and the
dictionary resides in examples\asp\northwind.

Follow these steps to create the application. Note that we’ve also provided an
application called todo.app.done should you wish to update your dictionary
and simply rename that rather than follow the steps to create your own.

There are many, many steps in this exercise, most of them concerned with
setting up a style sheet. This exercise could easy take over an hour. We’ve
found that with familiarity, and once you have IIS, the DSN, and a preferred
style sheet set up, it’s possible to take a generated application and apply
Clarion/ASP to it in under a minute.

Run the Application Wizard


For the sample todo app, you’ll require only two tables: a security table, and
the todo items table.

Start in the Clarion development environment, without opening a dictionary


or application.
1. Choose File > New > Application.
2. In the Open File dialog, navigate to the examples\asp\todo directory,
name the application Todo.app, be sure that the quickstart wizard is
unchecked, and press OK.
24 CLARION/ASP

Note: we’ve included a finished example called complete.app. Feel free


to examine this. Important: you cannot generate and run the complete
example as is, because you must first edit the connection string to
reference your DBMS server.
3. In the Application Properties dialog, select the northwind dictionary (in
the directory above), check the Application Wizard checkbox and press
OK.

4. In the Select an Application Wizard dialog, select ApplicationWizard


and press Select.
5. Click Next when you see the introductory panel of the Application
Wizard.
6. Be sure the Generate Procedures for all Files checkbox is unchecked in
the next panel of the wizard.
7. Select aspusers and ToDoList in the next panel, labelled “Select files to
Use,” then press Next.

8. Press Next on both of the next two panels, then be sure that “Generate
Reports for All Files” is unchecked on the following panel, labelled
“Finally...” Press Finish.

The application appears as a default application containing six procedures.


ANNOTATED EXAMPLES 25

Set the Global Template Options


This section walks you through setting the global options. It will include
walking you through creating a style sheet. Creating a style sheet makes this
a somewhat lengthy process, but one which you probably won’t do for every
project (more likely, you’ll reuse a style sheet created previously, or slightly
modify one).

Begin with your application tree open to the application created in the
previous section. To apply the Global template:

1. Press the Global button on the Application Tree toolbar.


2. Press the Extensions button in the Global Properties dialog.
3. Press the Insert button in the Extensions and Control Templates dialog.
4. Locate the ASP Global Template Extension in the Select Template
extension dialog. Select it and press Select.
The design time template interface for the Clarion/ASP global template
appears in the right hand side of the Extension and Control Templates dialog.
The first tab of the ASP template interface is labelled Global:
1. Accept the language and help defaults at the top of the tab.
26 CLARION/ASP

2. Skip over the Style Sheet group box; you’ll find directions for this in the
next section.
3. In the HTML Design time templates group box, press the Default
Templates button. A default template dialog appears with four edit
boxes. The default template provides the “setting” for the Clarion/ASP
browse tables and forms; in essence the background, top, and bottom for
the pages. We’ve placed an HTML design time template in the
examples\todo\html directory called todolist.htm. Type this file name
(just the file, not the path) into each of the four boxes in this dialog, and
press OK.

4. Accept the defaults for both List and Form defaults.


5. In the Cascading Style Sheets group box, press the Style Sheet Editor
button. The next section details the steps necessary for the styles.

Set up the Style Sheet

Starting with the Style Sheet Editor dialog, opened in the last section:
1. Press the Insert button to declare a new style. the Style Sheet dialog
appears.
2. Type in “MyStyles” in the file name box at the top.
ANNOTATED EXAMPLES 27

3. Accept the defaults for the hyperlinks styles, and click on the Body Tag
tab.
4. Set the body width by typing 99% in the width box.
5. Set no body color (i.e., it will pick it up from the design time template)
by typing COLOR:NONE in the background color box. In the steps
below, we will set distinctive colors for the components that Clarion/
ASP places in the pages it generates. For those developers used to Red-
Green-Blue values for desktop applications, you’ll soon see that HTML
specifies the use of hexidecimal values for colors; therefore the template
translates from decimal to hexidecimal, and you’ll see the hexidecimal
values.

6. Click on the Background Class tab. Set the body width to 98% by typing
it in the width box
7. Set the background color to COLOR:NONE by typing it in the
background color box. The background class differs from the body in
that this choice is for the inside of the forms that Clarion/ASP places on
the background of the page, and the body is for the entire page.

8. Click on the Data tab and repeat: set the body width to 98% by typing it
in the width box, and the background color to COLOR:NONE. Now we
can customize the individual parts, all of which are accessed through this
tab.
28 CLARION/ASP

9. Press the Borders button. Four group boxes, for the top, bottom, left and
right border lines each contain three options for the line style, width and
color.
10. Set the Line Width for all four sides to “thin.” Note that you’re provided
either with specific pixel width choices or relative choices.
11. Set the Line Style for all four sides to solid.
12. Set the Background Color box for all four sides to COLOR:NONE. The
grid, therefore, will pick up the “surrounding” color when it “divides”
the individual cells in the grid.
13. Using the keyboard shortcuts Ctrl-C to copy and Ctrl-V to paste, copy
the color value from the top Colors box into the three color boxes below,
making the border line colors for top, bottom, left and right all the same.

14. Press OK to close the Borders dialog.


15. Back in the Style Sheet dialog, press the Padding button. This controls
the fill space around the data grid cells. Set the padding to 2 pixels for all
sides.
16. Back in the Style Sheet dialog, in the sub classes group, press the Header
button. This controls the appearance of the text at the very top of
browses and forms, in effect, the “caption” area.
17. Press the ellipsis button next to the background color. In the Color Picker
dialog, press Define Custom Colors, click on a blank custom color box,
and then in the right side of the dialog, enter 241, 242, and 212
ANNOTATED EXAMPLES 29

respectively for the red, green, and blue values. The sample box should
show a sandy color. Press the “Add to Custom Colors” button, then press
OK. The value 0D4F2F1H should appear in the Background Color box.
18. Back in the header dialog, set the text alignment to left.

19. Press the font button. In the font dialog, press the ellipsis next to the
color. Click on a blank custom color box; either below or to the right of
the first custom color box that you filled two steps ago. Define a new
custom color with the RGB values of 0, 0, and 32. The color should be a
very, very dark blue. Select Add to Custom Colors and press OK. The
value 0200000H should appear in the background color box. Press OK
to close the font dialog.

20. Back in the Style Sheet dialog, press the Column Label button.
21. In the Column Label dialog, press the ellipsis (...) button next to
background color. Click on a blank custom color box. Define a new
custom color with the values of 133, 153, and 82. The color is a medium
green. The value 0529985H should appear in the background color box.
Press OK to close the dialog.
22. Back in the Column Label dialog, set the text alignment to Left.
23. Press the Data Rows button. We’ll declare two classes for data row
appearance. First, however, set the grid spacing thickness to 1.
24. Press the Insert button and type “MyDataRow” in the class name box in
the Data Rows dialog.
30 CLARION/ASP

25. In the same dialog, press the ellipsis (...) button next to background
color. The very first custom color should be the first sandy color you
created. (If you’ve closed the session and restarted, you may open the
Color Picker dialog, press Define Custom Colors, click on a blank
custom color box, and then in the right side of the dialog, enter 241, 242,
and 212 respectively for the red, green, and blue values. The sample box
should show a sandy color. Press the “Add to Custom Colors” button,
then press OK. The value 0D4F2F1H should appear in the Background
Color box). Select that box and press OK.
26. Back in the Data Rows dialog, press Insert to create another class for
data row, and type “AlternateRow” in the class name box.

27. In the same dialog, press the ellipsis (...) button next to background
color. Open the Color Picker dialog, press Define Custom Colors, click
on a blank custom color box, and then in the right side of the dialog,
enter 199, 208, and 168 respectively for the red, green, and blue values.
The sample box should show a somewhat lighter green color than the one
you defined previously. Press the “Add to Custom Colors” button, then
press OK. The value 0A8D0C7H should appear in the Background Color
box. Press OK to close the Data Rows dialog. Note: we will not actually
implement a greenbar effect in this example. But you may do so for extra
credit later, if you like. You might also experiment with conditional style
formatting; for example, applying the alternate style to high priority
tasks.

28. Back in the Style Sheet dialog, press the Footer button, and then the
ellipsis button next to background color in the next dialog.
29. In the color picker dialog, locate the color you defined for the header, the
sandy color. Select that box and press OK. The value 0D4F2F1H should
appear in the background color box.
30. Back in the Footer dialog, set text alignment to left, then press OK to
close the Footer dialog.
31. Press the Input Label button, press the ellipsis (...) button next to
background color, and locate the color you chose for the column labels
(the darker green color). Select that box and press OK. The value
ANNOTATED EXAMPLES 31

0529985H should appear in the background color box. Press OK to close


the Input Label dialog.
32. Back in the Style Sheet dialog, press the Input button.
33. In the Input dialog, press the ellipsis (...) button next to the background
color. Locate the light sandy color. Select that box and press OK. The
value 0D4F2F1H should appear in the background color box. Press OK
to close the Input dialog.
34. Press OK to close the Style Sheet dialog.
35. Press Ok to close the Style Sheet Editor dialog.

Applying the Style Sheet to the Project

Simply defining the Style Sheet does not apply it to the project. If you were
to generate the project now, the ASP pages would not include the HTML tag
which merges in the style sheet formatting options. Note that there are four
choices. This allows you to define the look of your browse tables, forms, and
help popups separately. Note also the additional option for Global
Cascading. Because style sheets are merged, you can create a hierarchy of
styles, defining some formatting options as a global choice, but then adding
additional options separately in style sheets for the forms and browses.

Once you’ve returned to the Global Extensions and Control Templates:


1. Press the Style Sheets button.
2. Select the MyStyles style sheet you created in the previous section for
each of the four cascading style sheet options.

3. Press OK to return to the Global template options.


Run the Connection Wizard

1. While still in the Extension and Control Templates dialog, with the ASP
global extension selected, select the Database tab on the right side of the
dialog.
2. Press the Connection Properties button on this tab. The Connection
Properties dialog appears.
3. Enter a user name for the database.
4. Enter a password for the database. Do not be concerned with storing
these in the .app file; assuming you set up your web server properly,
32 CLARION/ASP

these items are not accessible to the end user because they never become
part of the HTML source that IIS sends to the browser; this strictly
remains on the server.

5. Press the Call Connection Builder button.


The Data Link Properties dialog now appears. If ADO and MDAC were not
installed with the operating system, they can be installed by Microsoft Office
or with the MS SQL Server Enterprise Manager software. Fill in the
properties as follows:
1. Select the Provider tab, if the dialog did not automatically open to it, and
choose Microsoft OLE DB Provider for SQL Server, then press the Next
button.
2. On the Connection tab, enter the server name, or choose it from the drop
list in item number 1.
3. Enter the user name and password for the database in item number 2.
4. Check the “Allow Saving Password box,” in number 2. You must not
skip this step, else Internet Information Server has no way to log into the
database.

5. Type “northwind” (or northwind2 if you followed the attach steps for
MS SQL Server 7) in the “Select the database on the server” box. Be
sure to test the connection by pressing the Test Connection button.
ANNOTATED EXAMPLES 33

6. Press the OK button to close the Data Link Properties dialog.


You should have now returned to the Connection Properties dialog, and a
connection string something like the one below should appear at the bottom
of this dialog:
Provider=SQLOLEDB.1;Password=YourPassword;Persist Security Info=True;User
ID=YourUsername;Data Source=YourDataServer

You may now press the OK button to close the Connection Properties dialog.

Set Security Options

Click the Security tab within the Clarion/ASP global options. This step will
allow you to identify where the list of users and passwords will be stored.

The Northwind database you previously attached contained a table called


ASPUsers. Its structure is as follows:
CREATE TABLE [dbo].[aspusers] (
[ID] [int] IDENTITY (1001, 1) NOT NULL ,
[First_Name] [nchar] (32) NULL ,
[Last_Name] [nchar] (40) NOT NULL ,
[AccessLevel] [tinyint] NOT NULL ,
[Email] [nchar] (128) NOT NULL ,
[Password] [nchar] (14) NOT NULL
)

For those developers not conversant with MS SQL Server’s flavor of SQL:
the nchar type provides fixed length unicode support, and IDENTITY is an
auto increment type. In this case, the parameters (1001, 1) mean “start
counting” at 1001, and increment by 1 for each new insert.

Your application will use this table to check user security. Be sure (when
you’re ready to test) that you’ve entered at least one record in this table, and
that you remember the user ID (email in this case) and password you’ve
entered!
1. Check the “Provide User Based Security” box.
2. Press the ellipsis (...) button for the User Table, and select the aspusers
table.
34 CLARION/ASP

3. Press the ellipsis (...) button for the Unique ID column and select ID.
(this is different than the user ID; this is for internal use so that the
Clarion/ASP code can uniquely identify a row).
4. Press the ellipsis (...) button for the login name column and select Email.
This will be the data that the end user must type in at the user prompt.
5. Press the ellipsis (...) button for the user password column and select
Password.
6. Press the ellipsis (...) button for the user security level column and select
AccessLevel. See the section in the Clarion/ASP manual entitled Global
Options/Security Tab for a detailed description of how the security
access levels work.
7. Press the ellipsis (...) button for the user email column and select Email.
This is in case your application must use a different user ID than email.
8. Press the ellipsis (...) button for the user name column and select
First_Name.
9. Press the ellipsis (...) button for the user second name column and select
Last_Name.
ANNOTATED EXAMPLES 35

Later during this exercise you’ll be implementing “My Records” security


which will limit access to individual records to the owner of each record.
This will be done at the procedural level, but overall security must first be
implemented at the global level.

Finish the Global Options

Click on the Administration tab of the Global Options (you may need to
scroll the tabs to the right). You should always fill in the Administrator Email
for all projects. Clarion/ASP automatically sends an email message to the
administrator in case of database access failure.

For this particular exercise, feel free to type in a bogus address, such as
noone@nowhere.com in the Administrator Email box.

When ready, press OK twice to close the Global options dialog.

Applying the Browse Template


You’ll now apply Clarion/ASP to the browse on the ToDoList table. You
should see a procedure called BrowseToDoList in your application tree.
1. Right click the procedure and choose Extensions to open the Extensions
and Control Templates dialog.
2. Press the Insert button to insert a new extension.
3. Choose ASPBrowse from the Select Extension dialog and press Select.
36 CLARION/ASP

The Clarion/ASP browse extension template is now applied, and may now be
customized.

Enable My Records Filtering

First, you’ll set up application so that each record has an owner. When end
users run the application, they will view and edit only those task records
which belong to them. These will be identifed by the end user’s email
address. Set these options on the Globals tab of the Clarion/ASP browse
extension template.
1. Check the Override box.
2. Select the Security sub tab.
3. Verify the Enable Security for this Procedure box is checked (this tab
also allows you to specify that a particular procedure within an otherwise
secure application should not receive security).
4. Check the Enable My Records Filtering box.
5. Press the ellipsis button (...) next to the Data Column to Test box, and
select UserName.
ANNOTATED EXAMPLES 37

6. Verify that the dropdown list selection for Compare to Session, shows
UserEmail.
With these steps you’ve specified that each browse contains a clause limiting
the query to those rows in which the value in the UserName column equals
the user’s email address. No one, therefore, can view another user’s records.

Specifying Columns for the Browse

Because there will be a limited amount of space within the table displaying
the browse data, and because unlike desktop applications there can be no
horizontal scroll bar, you’ll delete some fields from the browse (though
you’ll later keep all fields for the form).

Click on the Data Columns tab. This displays the fields within the browse,
which it gathers from the fields within the list box that the application wizard
creates.

Use the delete button to delete extra fields, and the up/down arrow buttons to
rearrange the order so that the end result are the following fields, in this
order:

Subject
DueDate
Status
Priority
StartDate
PerCentcomplete
38 CLARION/ASP

Reminder
RemindDate
IDNumber

Customize Individual Fields

In this part you’ll apply formatting to some of the fields in the field list, plus
specify a link from the browse to a form.
1. Select the Subject field and press the Properties button.
2. Select the Appearance tab in the Data Columns dialog.
3. Specify 35% (don’t forget the % character) in the width box. This
specifies that the column should receive a minimum of 35% of the width
of the table.

4. Press the OK button to close the Data Columns dialog.


5. Select the PercentComplete field and press the Properties button.
6. Click the Column Sorting tab in the Data Columns dialog.
7. Specify that the Column Header Text says “Completed,” which is a little
shorter and more readable than PerCentComplete. Note that we could
have specified this in the data dictionary. We puposely neglected to do so
ANNOTATED EXAMPLES 39

in order to illustrate that you may customize the header text in this
dialog.

8. Press the OK button to close the Data Columns dialog.


9. Select the IDNumber field and press the Properties button.
10. On the General tab in the Data Columns dialog, check the “Include in
SQL Select but do not Display” box. Note that the additional tabs for
formatting disappear when the box is checked. We wish to include this
column in the Select statement, because we pass its value to the update
procedure (in steps four through eight), but there’s no need for the end
user to see a task ID number.

11. Press OK twice to close the Data Columns and Extensions dialog and
return to the Application Tree. You’ve now configured the browse.

Applying the Form Template


You’ll now apply Clarion/ASP to the update form for the ToDoList table.
You should see a procedure called UpdateToDoList in your application tree.
Applying the extension once provides for setting options for four separate
ASP procedures, namely add, edit, delete and query by form.

1. Right click the procedure and choose Extensions to open the Extensions
and Control Templates dialog.
40 CLARION/ASP

2. Press the Insert button to insert a new extension.


3. Choose ASPForm from the Select Extension dialog and press Select.

The Clarion/ASP form extension template is now applied, and may now be
customized.

Enable My Records Filtering

First, you’ll set up the form so that each record has an owner. When end
users run the application, they will view, edit or delete only those task
records which belong to them. These will be identifed by the end user’s email
address. Set these options on the Globals tab of the Clarion/ASP form
extension template.

1. Select the Override check box at the top of the Globals tab.
2. Select the Security sub tab on the Globals tab.
3. Check the Enable Security box.
4. Check the Enable My Records Filtering box.
5. Press the ellipsis button (...) next to the Data Column to Test box, and
select UserName.
6. From the dropdown list for Compare to Session, select UserEmail.
ANNOTATED EXAMPLES 41

With these steps you’ve specified that no one can edit another user’s records.
Should an end user attempt to “manually” link to someone else’s data (for
example, by entering a URL such as /UpdateProcedureEdit.asp?ID1=###),
an error message will display.

Note that you may also specify titles for the pages which will be generated
for adds, changes and deletes. These titles appear within what the equivalent
of the caption area will be. These override the global options.

1. Still on the Globals tab, choose the Titles sub tab.

2. Change the Insert title from “Insert Record” to “Insert Task.”


3. Optionally change the Edit, Delete, View and Search titles similarly.
Set Actions Options

Select the Actions tab to specify that a query by form be generated, as well as
identifying the parent browse (cannot always be done automatically) and
specifying titles for the page.
1. Check the Generate QBF box.
2. Select “BrowseToDoList” as the parent browse procedure from the
dropdown list if it’s not already selected. Verifying the parent browse is
simply an exercise in forming a good habit. We expect that many Clarion
programmers will be applying the Clarion/ASP templates to procedures
with many browses, and if there are enough, it may be difficult for the
form template to identify the proper parent procedure.
42 CLARION/ASP

Set Data Control Options

In setting the control options, you’ll specify that any unnecessary controls
are removed from the query by form (focusing the end user upon a smaller
number of fields, all of which are indexed), setting an appearance option on
three fields, and reordering the controls.
1. The fields list should be in the order as follows, based upon their order in
the update form, which in turn was based upon the order specified in the
data dictionary:
Subject
DueDate
Status
Priority
IDNumber
StartDate
PerCentComplete
Reminder
RemindDate
UserName
Notes
DateCompleted
DateCreated
DateModified

Note that unlike the browse, there are no up/down, insert and delete buttons
on the controls tab for the form. This is because the form extension template
ANNOTATED EXAMPLES 43

reads the window structure, and assumes that you wish to place exactly those
controls in that order.

Should you not be happy with the order, you must edit the window structure
as text (using the ellipsis button next to the Window button on the Procedure
Properties dialog). Cut and paste the controls and prompts so that they
appear in the order you wish.

Long range, should you wish to be able to generate other applications that
display the fields in a consistent order, you must modify the dictionaries so
that the fields lists within the table you wish to place in order reflect the
order you wish, bearing in mind that you may have set the “populate first”
and “populate last” options. Unlike an ISAM database, you do not need to
worry about field order in the SQL Clarion FILE definition.

To continue with selecting options for the fields in this table:


1. Select the DueDate field and press the Properties button. Check the
“Omit from QBF page” box and press OK.
2. Select the PerCentComplete field and press the Properties button. Check
the “Omit from QBF page” box and press OK.
3. Select the StartDate field and press the Properties button. Check the
“Omit from QBF page” box and press OK.

4. Select the Reminder field and press the Properties button. Check the
“Omit from QBF page” box and press OK.
5. Select the RemindDate field and press the Properties button. Check the
“Omit from QBF page” box and press OK.
6. Select the DateCompleted field and press the Properties button. Check
the “Omit from QBF page” box and press OK.
7. Select the UserName field and press the Properties button. Check the
“Omit from QBF page” box. Also, check the “Read Only” box. This will
inhibit users from possibly editing the ID of another user. Note that this
field will be invisible on an update/add form. Press OK.
8. Select the IDNumber field and press the Properties button. Check the
“Omit from QBF page” box. Also, check the “Read Only” box. Note that
44 CLARION/ASP

this field will not be present on the update/view only form, anyway,
because we’ve selected “My Records” filtering, which automatically
hides the filter field from the end user. Press OK.
9. Press OK to close the Extension and Control Templates dialog.

Generate the ASP Pages


Congratulations. You’ve finished setting up your Clarion/ASP application
and are ready to generate and test on your local machine.

The generation process is no different than normal Clarion source code


generation. The only difference is that in addition to the Clarion source code
modules, the application generator also produces .asp pages, as well as htm
files.

To generate your project, with only the Application Tree window open,
choose Project > Generate All from the development environment menu.

Setup the IIS Virtual Directory


This section adds a virtual directory for the project’s asp subdirectory so that
you may easily run the Clarion/ASP on your local web server.

1. Open the Internet Services Manager via whatever the proper shortcut is
in your version of Windows. In Windows 2000, for example, choose
Start > Programs > Administrative Tools > Computer Management, then
expand Services and Applications > Internet Information Services in the
left pane.
2. Right click on the Default Web Site icon and choose New > Virtual
Directory.
ANNOTATED EXAMPLES 45

3. Press the Next button in the wizard which then appears, and name the
alias “task.”
4. Press the Next button and enter the path. If you installed Clarion and
Clarion/ASP to their defaults, the path should be
C:\C55\examples\asp\todo\asp. Note that there are two directories named
asp in this path; be sure to pick the right one.
5. In the Access Permission panel, verify that “Read” and “Run” are
checked (the first two options in the list. Press Next.

6. Press Finish to close the wizard.

Running Your First Test


Clarion/ASP automatically generates an “index” or “table of contents” page
for you. This allows you to test your procedures easily, but is not meant for
deployment (it’s simply a list of textual links to the procedures, grouped by
procedure type).
1. Open your browser.
2. Open the URL http://localhost/task/index.htm. This is the simple list of
procedures that Clarion/ASP automatically generates for you as a
convenience in testing your application.
46 CLARION/ASP

If you did not receive an index page listing your procedures, either IIS
isn’t running or you did not set up your virtual directory correctly. Go
back to the beginning of this exercise and review those sections.
3. Click on the link to the Browse/ToDoList. You should be prompted for a
log in.
4. Log in. If you cannot log in, be sure that you’ve added your user ID,
password, and email to the aspusers tables using the SQL Enterprise
Manager tool.

5. Your browse list probably contains no records. You should see a text link
offering to add a record. Click the link.
ANNOTATED EXAMPLES 47

6. Enter the information for a new record and press the submit button
(notice first that the date fields can be filled in directly from the
calendar). You should receive an acknowledgement that your insert
succeeded. Near the acknowledgement should be a link offering to return
you to the list. When you link back, you should see your record.

7. Within that record, as it appears in the browse, you should see an icon on
the right serving as an automatically generated link to an edit page for
that record. Click on that link.
8. Press the back button to return to the browse. Use the Insert Record
button in the navigation button area to insert another record. When the
other record is added, return to the browse.
9. Now that you have two records within the browse, click on the column
titles to check the sorting feature.
48 CLARION/ASP

10. When done, you may simply let the application time out. since there is
no such thing as “state” within an HTML application, there is no “exit”
command, short of closing the browser.

Examining the HTML Frames


When it comes time to deploy your applications, many developers will be
integrating Clarion/ASP pages in an existing site.

We’ve included three extra HTML files with this sample application. They
demonstrate opening the Clarion/ASP generated pages inside a frame, and
calling the pages with HTML parameters. A frame provides a setting for two
or more HTML pages, which appear inside it. An HTML parameter is a
parameter appended at the end of a URL, separated from the URL with a
question mark character. Note that Clarion/ASP did not generate these files;
should you wish to create similar ones at your site you must coordinate with
your web master.

In this section, we’ll open those files using Explorer (as opposed to Internet
Explorer).

1. In an Explorer window locate the current Clarion project directory (the


one in which you created todolist.app. Open the asp directory located
one level beneath it.
2. Right click the file TASKS.HTML and choose Open With... Open it
using either an HTML editor (pick yours from the list), or Notepad. This
is the frameset file, the “holder” for two other pages. If you do have an
HTML editor, when the file opens, switch to source view.

We’ll call your attention to only four features of the frame:


ANNOTATED EXAMPLES 49

• On line three, the <title> tag indicates the title that will appear in the
caption bar of the frame. The caption bar text does not change even
though the frame contents may. Everything between <title> and </title>
will be the caption text.
• On line six, the <frameset> tag appears, definining this as a frame set.
This line indicates the size of each frame. The frames themselves must
be described in the following lines, before the </frameset> tag.
In HTML, which is a tagged formatting language, a tag consists of a
tagname and optional parameters in angle brackets, as in <tagname
parameter1=value1>. Each tag must have a complimentary closing tag
consisting of angle brackets, a forward slash, and the tag name, as in </
tagname>.
• On line seven, the first frame is defined. The sequence is always left to
right. The src= parameter indicates the location of the HTML page which
is to fill the right hand frame. In this case it’s "todonav.html" which
indicates a document in a directory below the asp directory. The actual
document name consists of “todo,” an “r” meaning “right,” and “nav”
meaning “navigation. It will contain a navigation box with pictures that
link to other parts of the application.
• On line nine, the second frame is declared. This is a simple page with a
SoftVelocity logo.

At this point, you may load the frameset and frames


1. In your browser, by typing http://localhost/task/tasks.html. Don’t click
on any links yet. First, examine the links.
2. Right click in the dark gray area of the navigation bar at the left, but not
on one of the pictures. Choose “View Source” from the popup menu. The
HTML source should appear in notepad.
50 CLARION/ASP

At this point we’ll examine the link urls for each of the “pictures” in the
navigation bar. Links start with <a> and end with </a> tags.
1. If wordwrap in Notepad is on, turn it off.
2. Notice line 27, which starts with “<div align...> and includes the link to
the “Reminders” browse:
<a href="UpdateToDoListAdd.asp" target="mainFrame"><img src="IMAGES/
newnote32x32.GIF" width="30" height="32" border="0"></a>

Each of the links we’ll examine include the parameter


target="mainFrame." This instructs the browser to open the target page
in the “bigger” frame at right, which is the main frame (this is the
navigation frame).
This URL has no parameters (it’s just UpdateToDoListAdd.asp). It’s not
necessary to provide any parameter to an add form.
3. Notice line 33, which is the link from the “Reminders” caption below the
second picture. The line includes the following:
<a href="BrowseToDoListList.asp ?WHR=dbo.todolist.Reminder=
1%20and%20dbo.todolist.RemindDate%20%3E=
%20GETDATE()%20and%20dbo.todolist.DateCompleted%20IS%20NULL">Reminders</
a>

The link is to the browse page, and appends a parameter. The %##’s
indicate ASCII characters, which translate to the following:
<a href="BrowseToDoListList.asp ?WHR=dbo.todolist.Reminder=1 and
dbo.todolist.RemindDate <= GETDATE() and dbo.todolist.DateCompleted
IS NULL" >Reminders</a>

?WHR indicates to the ASP code that Clarion/ASP generates that the text
following the equal sign should be appended to any default where clause
ANNOTATED EXAMPLES 51

(and in fact there is a where clause existing already for the browse,
because we’ve enabled MyRecords.
Note: the GETDATE() function is a TSQL (MS SQL Server procedural
language) function which returns today’s date.
Therefore, the complete query (not including the field list, which is
simply abbreviated below, including the My Records filter, and
indicating where the user email will be filled in via a session variable) is:
SELECT (fieldlist) FROM dbo.ToDoList WHERE
dbo.todolist.Reminder=1 and
dbo.todolist.RemindDate <= GETDATE() and
dbo.todolist.DateCompleted IS NULL and
dbo.todolist.UserName = (UserEmail Session Variable)

In other words, fill the browse only with my records, but only those for
which a reminder was set, if the reminder date is today or before, and finally,
if the task is incomplete.

This page also includes links to the same browse page with different
parameters: “To Do,” and “Done.” The “To Do” link contains essentially the
opposite of the reminders where clause. The “Done” link populates the
browse with anything marked “Complete” or 100% percent complete.

By providing your web master with the text for the where clause, and
advising the web master that the parameter should be named “WHR,” and
that the user identifier is a session variable called “UserEmail,” you provide
your web master with “the keys to the kingdom.” The web master should be
able to open any part of your Clarion/ASP application and zero in on the
data, or pre-fill in any forms to an almost unlimited degree. A great deal of
scenarios are thoroughly documented in the “How - To’s section of the
manual.

There are two final links to examine in this particular page.

The search link (lines 53 - 54) simply points to the search page, with no
parameters:
<a href="UpdateToDoListsearch.asp" target="mainFrame">Search</a>

On line 60, a javascript function instructs the top frame to close itself,
mimicing an exit function. We included this only because it provided the
effect of making this feel like a desktop application. Most web sites will not
want to do such a thing!
<a href="javascript:top.self.close();">Exit</a>

At this point, feel free to close the notepad window with the source code and
explore the application using the pictures in the navigation bar. Notice that
with the first link to one of the task pages you’re requested to login.
52 CLARION/ASP

Help Pages

Notice also that the help links point to HTML pages which appear in popup
windows correctly sized to the text.

The best way to create your help text is to open the “template” help files
which Clarion/ASP generates for you in an HTML editor. You’ll find a text
marker labelled “Customize your help text here” in each of the files that are
generated for you in the project\asp\help folder.

Should you wish instead to link to other site pages for help text, simply
customize the help page addresses in the procedure(s) you wish.
ANNOTATED EXAMPLES 53

5. SEARCH CONTACTS EXAMPLE


This exercise walks you through setting up and running the “Search
Contacts” list example application.

The database side of this example is a little trickier than it appears. The
Northwind sample database contains two different tables with contact
information: customers and suppliers. The unique ID in the former is a
string, and the latter, a numeric. This example creates a union of the two
tables, and adds a column to hold the contact type based on where it came
from. Therefore, the browses will display information from a view. But then
to zero in on the data, rather than use the view, the forms will view (they
could just as well edit) the original table. This affords us with an opportunity
to show you some of the more complicated things you can do with custom
links in Clarion/ASP, including creating a dynamic link that calls either one
procedure or another, and passes either one parameter or another based on
the contact type.

Follow these steps to create the application. Note that we’ve also provided an
application called search.app.done should you wish to update your dictionary
and simply rename that rather than follow the steps to create your own.

Run the Application Wizard


For the sample search app, you’ll require several tables and views:
Customers, Contacts, Orders, Order_Details, Employees, Suppliers,
Products, viewProductPhotos, and of course, viewContacts. Note that you
will not require the users table: this example will be all view-only, and for
that reason, we haven’t demonstrated security.
54 CLARION/ASP

Start in the Clarion development environment, without opening a dictionary


or application.
1. Choose File > New > Application.
2. In the Open File dialog, navigate to the examples\asp\search directory,
name the application search.app, be sure that the quickstart wizard is
unchecked, and press OK.
Note: we’ve included a finished example called complete.app. Feel free
to examine this. Important: you cannot generate and run the complete
example as is, because you must first edit the connection string to
reference your DBMS server.
3. In the Application Properties dialog, select the northwind dictionary (one
directory level up), check the Application Wizard checkbox and press
OK.

4. In the Select an Application Wizard dialog, select ApplicationWizard


and press Select.
5. Click Next when you see the introductory panel of the Application
Wizard.
6. Be sure the Generate Procedures for all Files checkbox is unchecked in
the next panel of the wizard.
7. Select the tables Customers, Orders, Order_Details, Employees,
Suppliers, Products, viewProductPhotos, and viewContacts in the next
panel, labelled “Select files to Use,” then press Next.

8. Press Next on both of the next two panels, then be sure that “Generate
Reports for All Files” is unchecked on the following panel, labelled
“Finally...” Press Finish.

The application wizard appears with a default application containing six


procedures.
ANNOTATED EXAMPLES 55

Set the Global Template Options


Begin with your application tree open to the application created in the
previous section. To apply the Global template:
1. Press the Global button on the Application Tree toolbar.
2. Press the Extensions button in the Global Properties dialog.
3. Press the Insert button in the Extensions and Control Templates dialog.
4. Locate the ASP Global Template Extension in the Select Template
extension dialog. Select it and press Select.

The design time template interface for the Clarion/ASP global template
appears in the right hand side of the Extension and Control Templates dialog.
The first tab of the ASP template interface is labelled Global:
1. Accept the language and help defaults at the top of the tab.

2. Skip over the Style Sheet group box; you’ll find directions for this in the
next section.
3. In the HTML Design time templates group box, press the Default
Templates button. A default template dialog appears with four edit
boxes. The default template provides the “setting” for the Clarion/ASP
browse tables and forms; in essence the background, top, and bottom for
the pages. We’ve placed an HTML design time template in the
examples\search\html directory called search.htm. Type this file name
(just the file, not the path) into each of the four boxes in this dialog, and
press OK.
56 CLARION/ASP

4. Accept the defaults for both List and Form defaults.


5. In the Cascading Style Sheets group box, press the Style Sheet Editor
button. The next section details the steps necessary for the styles.

Set up the Style Sheet

Starting with the Style Sheet Editor dialog, opened in the last section:
1. Press the Insert button to declare a new style. the Style Sheet dialog
appears.
2. Type in “Silver” in the file name box at the top.

3. Accept the defaults for the hyperlinks styles, and click on the Body Tag
tab.
4. For this example, you’ll create a silver color scheme. For this
background, however, we’ll specify that it pick up the color from the
design time template. Type COLOR:NONE in the background color box.

5. Click on the Background Class tab. We’ll specify that it pick up the
color from the design time template. Type COLOR:NONE in the
background color box. The background class is for the inside of the
forms that Clarion/ASP places on the background of the page (the body
is for the entire page).
6. Set the background width to 100%.
7. Click on the Data tab. We’ll specify that it pick up the color from the
design time template. Type COLOR:NONE in the background color box.
ANNOTATED EXAMPLES 57

8. Press the Borders button. Four group boxes, for the top, bottom, left and
right border lines each contain three options for the line style, width and
color.
9. Set the Line Width for all four sides to “thin.” Note that you’re provided
either with specific pixel width choices or relative choices.
10. Set the Line Style for all four sides to solid.
11. Set the colors for the top and left borders to black (the bottom left corner
in the color samples boxes).
12. Set the bottom and right borders to gray (fourth from the left on the
bottom row of the color samples boxes).

13. Press OK to close the Borders dialog.


14. Back in the Style Sheet dialog, press the Padding button. This controls
the fill space around the data grid cells.
15. In the Padding dialog, change the values so that all four boxes are the
same value, 2 pixels (abbreviated as px throughout HTML), and press
OK.
16. Back in the Style Sheet dialog, press the Header button. This controls the
appearance of the text at the very top of browses and forms, in effect, the
“caption” area.
17. Press the ellipsis button next to the background color. In the Color Picker
dialog, press Define Custom Colors, click on a blank custom color box,
and then in the right side of the dialog, enter 146, 147, and 170
respectively for the red, green, and blue values. The color should be a
dark silver. Press the “Add to Custom Colors” button, then press OK.
The value 0AA9392H should appear in the Background Color box.
18. Back in the header dialog, verify that the text alignment is blank. Select
and delete any existing value if necessary. By deleting the value from the
style, the column header alignment can be set on a procedure by
58 CLARION/ASP

procedure basis; if the style contains an alignment value, it will take


precedence over the value set in the procedure.

19. Press the font button. In the font dialog, type COLOR:White in the color
box. Press OK to close the font dialog. The header, therefore, will be
white text on a dark silver background.
20. Back in the Style Sheet dialog, press the Padding button. This controls
the fill space around the data grid cells. In the Padding dialog, change
the values so that all four boxes are the same value, 2 pixels (abbreviated
as px throughout HTML), and press OK.
21. Back in the Style Sheet dialog, press the Column Label button.
22. In the Column Label dialog, press the ellipsis (...) button next to
background color. Select an empty custom color box at the bottom of the
dialog, and press the Define Colors button. Enter a new Red/Green/Blue
value of 203, 204, 218, press Add to Custom Colors, and then the OK
button. The color should be a shade of silver. The value 0DACCCBH
should appear in the background color box. Press OK to close the dialog.

23. Back in the Column Label dialog, set the text alignment to Left.
24. Press the Padding button. This controls the fill space around the data grid
cells. In the Padding dialog, change the values so that all four boxes are
the same value, 2 pixels (abbreviated as px throughout HTML), and
press OK, then press OK to close the Column Label dialog.
25. Press the Data Rows button. We’ll declare two classes for data row
appearance. First, however, set the grid spacing thickness to 1.
26. Press the Insert button and type “MyDataRow” in the class name box.
27. In the same dialog, press the ellipsis (...) button next to background
color. Open the Color Picker dialog, press Define Custom Colors, click
on a blank custom color box, and then in the right side of the dialog,
enter 240, 241, and 245 respectively for the red, green, and blue values.
The sample box should show a lighter silver color than the one you
defined previously. Press the “Add to Custom Colors” button, then press
ANNOTATED EXAMPLES 59

OK. The value 0F5F1F0H should appear in the Background Color box.
Press OK to close the dialog.

28. Back in the Data Rows dialog, press Insert to create another class for
data row, and type “AlternateRow” in the class name box.
29. In the same dialog, press the ellipsis (...) button next to background
color. Open the Color Picker dialog, press Define Custom Colors, click
on a blank custom color box, and then in the right side of the dialog,
enter 224, 223, and 227 respectively for the red, green, and blue values.
The sample box should show a very slightly darker silver color than the
one you defined last. Press the “Add to Custom Colors” button, then
press OK. The value 0E3DFE0H should appear in the Background Color
box. Press OK to close the Data Rows dialog.
30. Back in the Style Sheet dialog, press the Footer button, and then the
ellipsis button next to background color in the next dialog.
31. In the color picker dialog, locate the color you defined for the header, the
darkest gray. Select that box and press OK. The value 0AA9392H should
appear in the background color box (RGB 146, 147, 170).
32. Back in the Footer dialog, set text alignment to left, then press OK to
close the Footer dialog.
33. Press the Input Label button, press the ellipsis (...) button next to
background color, and locate the color you chose for the column labels
(the “medium” gray, the Red/Green/Blue value of 203, 204, 218). The
value 0DACCCBH should appear in the background color box. Press
OK to close the Input Label dialog.
35. Back in the Style Sheet dialog, press the Input button.
36. In the Input dialog, press the ellipsis (...) button next to the background
color. Locate the third color you defined, a light silver (RGB 240, 241,
245). Select that box and press OK. The value 0F5F1F0H should appear
in the background color box. Press OK to close the Input dialog.
37. Press OK to close the Style Sheet dialog.
38. Press Ok to close the Style Sheet Editor dialog.

Applying the Style Sheet to the Project

Simply defining the Style Sheet does not apply it to the project. If you were
to generate the project now, the ASP pages would not include the HTML tag
which merges in the style sheet formatting options. Note that there are four
60 CLARION/ASP

choices. This allows you to define the look of your browse tables, forms, and
help popups separately. Note also the additional option for Global
Cascading. Because style sheets are merged, you can create a hierarchy of
styles, defining some formatting options as a global choice, but then adding
additional options separately in style sheets for the forms and browses.

Once you’ve returned to the Global Extensions and Control Templates:

1. Press the Style Sheets button.


2. Select the Silver style sheet you created in the previous section for each
of the four cascading style sheet options.

3. Press OK to return to the Global template options.


Run the Connection Wizard
1. While still in the Extension and Control Templates dialog, with the ASP
global extension selected, select the Database tab on the right side of the
dialog.
2. Press the Connection Properties button on this tab. The Connection
Properties dialog appears.
3. Enter a user name for the database.
4. Enter a password for the database. Do not be concerned with storing
these in the .app file; assuming you set up your web server properly,
these items are not accessible to the end user because they never become
part of the HTML source that IIS sends to the browser; this strictly
remains on the server.
5. Press the Call Connection Builder button.
The Data Link Properties dialog now appears. If ADO and MDAC were not
installed with the operating system, they can be installed by Microsoft Office
or with the MS SQL Server Enterprise Manager software. Fill in the
properties as follows:

1. Select the Provider tab, if the dialog did not automatically open to it, and
choose Microsoft OLE DB Provider for SQL Server, then press the Next
button.
2. On the Connection tab, enter the server name, or choose it from the drop
list in item number 1.
3. Enter the user name and password for the database in item number 2.
ANNOTATED EXAMPLES 61

4. Check the “Allow Saving Password box,” in number 2. You must not
skip this step, else Internet Information Server has no way to log into the
database.
5. Type “northwind” in the “Select the database on the server” box. Be sure
to test the connection by pressing the Test Connection button.
6. Press the OK button to close the Data Link Properties dialog.

You should have now returned to the Connection Properties dialog, and a
connection string something like the one below should appear at the bottom
of this dialog:
Provider=SQLOLEDB.1;Password=YourPassword;Persist Security Info=True;User
ID=YourUsername;Data Source=YourDataServer

You may now press the OK button to close the Connection Properties dialog.

The BrowseviewContacts Procedure


You’ll be applying the browse extension to three of the browse procedures:
viewContacts, Orders, viewProductPhotos. This is the first.
1. Locate the BrowseviewContacts procedure in the Application Tree.
Right click the procedure and choose Extensions.
2. In the Extensions and Control Templates dialog, press the Insert button.
Choose the ASP Browse Extension Template.
3. Now that you’ve applied the template, on the Data Columns tab, use the
delete and up/down keys so that you’re left with only the following
fields, in the following order: CompanyName, ContactName,
ContactTitle, Phone, EditCustomer, EditSupplier, Type and Country.

4. You’ll now customize some of these fields. Click on ContactTitle, and


press the Properties button.
5. In the Data Columns dialog, on the first tab, click the “Include with Prior
Column.” This will display the title in the same “cell” as the preceding
column, the ContactName. Next to the checkbox, in the box labelled
“preceeding text,” type in “<br>,” without the quotes and comma. This is
62 CLARION/ASP

the “break” tag, indicating there should be a line break inserted before
the ContactTitle data value. Press OK to close the data columns dialog.

5. Next, select the EditCustomer field, and press the Properties button. In
this field, we’ll define a custom link. The custom link allows you to
display data or a graphic, and provides a “free form” means of
specifying the target. This will demonstrate using a combination of static
HTML and dynamic VBScript to create the link target. For those
developers with some familiarity with HTML, the custom link allows
you to define the entire <a></a> tag, with everything inbetween.
6. In the Data Columns dialog, click the Actions tab.
7. Select Custom Link as the “Create Column as Link” type choice.
8. Type the following exactly as it appears below, in the Custom Link box:
<A HREF=UpdateCustomersView.asp?ID1=" &
MID(TRIM(oRSviewContacts.Fields("EditCustomer").Value),1,50) &
"><IMG alt='Customer Details' src='images/customerdetail32x32.GIF'
border=0></A>

Note: we’ve supplied a small text file called “cheat sheet” in case you don’t
wish to type this text (and the three others like it, below), or in case you’re
concerned about making a typo. It’s in the project directory.

The above code:


• <A is the beginning of the link tag
ANNOTATED EXAMPLES 63

• HREF=UpdateCustomersView.asp?ID=" is the first part of the URL to


link to... the edit/view only procedure for the update on the customers
table. Note that we’ve ignored the update on the view. Should you wish
to change this to a real update, you need only change the page name.
• & MID(TRIM(oRSviewContacts.Fields("EditCustomer").Value),1,50)
This is a VBScript function. The view contains the customer’s unique ID
(a string, such as ALFKI) in the EditCustomer field. The
oRSviewContacts.Fields function returns the value of the field named in
the brackets (oRSviewContacts is a recordset object that has a “Fields”
method, whose parameter is the field name). The Trim function deletes
any trailing spaces. The MID function eliminates any nulls. So this
function “delivers” the customer ID as the ?ID parameter for the update/
view function.
• &"><IMG alt='Customer Details' src='images/customerdetail32x32.GIF'
border=0></A> The remainder of the static HTML appends a tag
identifying an image to display, its location, the fact that it has no border,
and the ending link tab </A>.
Therefore, this custom link displays an image, repeated for each
customer, and that image serves as a link to a view only update
procedure, passing the unique customer identifier for each customer.
9. Press OK to close the Data Columns dialog.
10. Click the Edit Supplier field and press the Properties button.
11. In the Data Columns dialog, on the first tab, click the “Include with prior
column.” This will display the title in the same “cell” as the preceding
column, the ContactName. Leave the next checkbox, with the box
labelled “preceeding text,” blank. This will not place any extra space
between the previous column and this. The reason we wish to do this is
that because of the way the view is constructed, one or the other of these
two columns will always be null. In defining the view, we didn’t create a
single column for an important reason: so that we could more easily
create two completely different hyperlinks. Press OK to close the data
columns dialog.
12. In the Data Columns dialog, click the Actions tab.
13. Select Custom Link as the “Create Column as Link” type choice.
14. Type the following exactly as it appears below, in the Custom Link box:
<A HREF=UpdateSuppliersView.asp?ID1=" &
MID(TRIM(oRSviewContacts.Fields("EditSupplier").Value),1,50)
&"><IMG alt='Supplier Details' src='images/supplierdetail32x32.GIF'
border=0></A>

This code works exactly the same as the custom link code above. The
only difference is that it’s using the Supplier ID (a numeric), a different
graphic, and calling a different update/view procedure. Note that there’s
64 CLARION/ASP

no need to convert the numeric to a string in the ?ID parameter. All


HTML parameters are treated as strings.

15. Press OK to close the Data Columns dialog.


16. Click the Type field and press the Properties button.
17. In the Data Columns dialog, on the first tab, click the “Include with prior
column.” This will display the title in the same “cell” as the preceding
column, the Supplier. In the next box labelled “preceeding text,” type
“&nbsp;&nbsp;” without the quotes, but with the semi colons. This will
place two spaces between the previous column and this. The HTML
special character &nbsp stands for non-breaking space. Press OK to
close the data columns dialog.
18. In the Data Columns dialog, click the Actions tab.
19. Select Custom Link as the “Create Column as Link” type choice.
20. Type the following exactly as it appears below, in the Custom Link box:
<A HREF=" & oRSviewContacts("Type") & "ViewSpecialList.asp?ID1=" &
MID(TRIM(oRSviewContacts.Fields("EditCustomer").Value),1,50)
&MID(TRIM(oRSviewContacts.Fields("EditSupplier").Value),1,50)
&"><IMG alt='View Orders or Products' src='images/" &
MID(TRIM(oRSviewContacts.Fields("Type").Value),1,50) &"32x32.gif'
border=0></A>

The code above uses the value in the Type field, which will be either
“Supplier” or “Customer” to call one of two procedures:
“SupplierViewSpecialList” or “CustomerViewSpecialList.” Neither of
these procedures exist on the application tree yet; you’ll rename the
browse suppliers and browse customers procedures to these names. To
detail the code piece by piece:
• <A HREF=" is the beginning of the link tag plus the parameter for the
hypertext target.
• & oRSviewContacts("Type") returns the value from the Type column in
the record set. This will always be either “Customer” or “Supplier,”
which means that as we build the link to the procedure page, we can
depend on it always existing.
ANNOTATED EXAMPLES 65

• & "ViewSpecialList.asp?ID=" is static text containing the rest of the


procedure name to call, and the ?ID=, indicating that the next bit will be
the parameter to pass to the procedure page.
• & MID(TRIM(oRSviewContacts.Fields("EditCustomer").Value),1,50)
returns a customer ID if it’s a customer record, or an empty string if it’s
null, i.e., a supplier record.
• &MID(TRIM(oRSviewContacts.Fields("EditSupplier").Value),1,50)
returns a supplier ID if it’s a supplier record, or an empty string if it’s a
null, i.e., a customer record. This makes it safe to append to the
preceding.
• &"><IMG alt='View Orders or Products' src='images/" appends the
HTML indicating that an image is to be displayed, including its “tool
tip,” which is in the ALT parameter.
• & MID(TRIM(oRSviewContacts.Fields("Type").Value),1,50) returns the
first part of the image file name, i.e., “customer” or “supplier.” The two
possible images to display are customer32x32.gif and supplier32.32.gif,
both of which exist in the /images directory.
• &"32x32.gif' border=0></A> is the rest of the image file name and the
ending link tag.
21. Press OK to close the Data Columns dialog.
22. Click the Country field and press the Properties button.
17. In the Data Columns dialog, on the first tab, click the “Include with prior
column.” This will display the title in the same “cell” as the preceding
column, the link to the update procedure. In the next box labelled
“preceeding text,” type “&nbsp;&nbsp;” without the quotes, but with the
semi colons. This will place two spaces between the previous column
and this. The HTML special character &nbsp stands for non-breaking
space. Press OK to close the data columns dialog.
24. In the Data Columns dialog, click the Actions tab.
25. Select Custom Link as the “Create Column as Link” type choice.
26. Type the following exactly as it appears below, in the Custom Link box:
<A HREF=BrowseViewContactsList.asp?WHR=dbo.viewContacts.Country='" &
MID(TRIM(oRSviewContacts("Country")),1,50) &"'><IMG alt='View All
From " & MID(TRIM(oRSviewContacts("Country")),1,50) &"'
src='images/" & MID(TRIM(oRSviewContacts("Country")),1,50) & ".gif'
border=0></A>

This code calls the same browse, but adds a custom where clause, filtering
the rows so that only those rows belonging to the same country as the row
that was clicked upon appear. Needless to say, this is not a real world
feature: it’s in the sample to illustrate what you can do. It also displays the
66 CLARION/ASP

country’s flag (note that this presupposes that you have all the flags in the
directory, in the file format countryname.gif.

Line by line, the code does the following:

• <A HREF= BrowseViewContactsList.asp?WHR=


dbo.viewContacts.Country='" Provides the link tag, the hypertext targe’s
page name, the ?WHR parameter identifer, the first part of the SQL
select statement and a single quote which needs to be passed to the
DBMS because the value will be a string.
• & MID(TRIM(oRSviewContacts("Country")),1,50) returns the name of
the country, from the database, protecting against any NULL values.
Note that in general, NULLs can wreak havoc with ASP/ADO code.
• &"'><IMG alt='View All From " provides the first part of the tool tip
text.
• & MID(TRIM(oRSviewContacts("Country")),1,50) provides the
country name to finish up the tool tip text.
• &"' src='images/" & provides the HTML to identify the image file
location.
• & MID(TRIM(oRSviewContacts("Country")),1,50) provides the country
name, which is also the file name (without the extension).
• & ".gif' border=0></A> provides the image file extension and ending
link tag.

Turning Off the Update Link


Press OK once to return to the prompts for the browse extension.

This is a view, and you don’t wish to lead the end user into thinking they can
edit it as is. Therefore, you’ll wish to cancel the custom link which was
populated.
ANNOTATED EXAMPLES 67

1. Select the Globals tab in the browse extension template.


2. Check the override check box to enable the sub tabs.
3. Uncheck the Create Detail Link as Custom Column checkbox.

4. Back on the “outside” tabs of the browse extension, flip to the Custom
Columns tab.
5. Select and delete the Automatic Detail Link.
6. Press OK to close the Browse Extensions prompts.

The Orders Procedure


The second browse procedure needs to be renamed. As you recall in the last
section, we used custom link text to dynamically call procedure pages. From
the customer data, we linked to orders, and from the supplier data, we linked
to products. The word “Customer” or “Supplier” was in the view data;
therefore, we wish to rename the BrowseOrders procedure so it contains the
word “Customer.” We’ve arbitrarily chosen “CustomerViewSpecial,” but we
could have just have easily chosen “CustomerOrdersBrowse.”

Before you apply the ASP browse extension template, however, open the
window for this procedure, and populate two fields from related tables. This
will automatically include them in the browse fields.
1. Right click the BrowseOrders procedure in the application tree and
choose Window from the popup menu.
2. When the window formatter appears, right click the browse box and
choose List Box Format.
3. First, re-order the existing fields, adding any fields necessary so that only
the following appear in this order: OrderID, OrderDate, RequiredDate,
ShippedDate, EmployeeID, CustomerID, ShipVia, Freight, and
ShipName.
68 CLARION/ASP

4. Still in the window formatter, click on the OrderID field and press the
insert field button. In the field list window, select the orders table in the
File Browsing List box node, then press the Insert button. Select the
Customers table. (Note: Customers will already appear in the left hand
pane, in the “Other Tables” node. You may leave that node as is).
5. Select the new “Customers” node, which appears as a child to the Orders
table, then select the “Company Name” field from the fields list, then
press the select button to bring it into the listbox formatter list.
6. Click on the EmployeeID field in the listbox formatter list, and press the
insert field button. In the field list window, select the orders table (again)
in the File Browsing List box node, then press the Insert button. Select
the Employees table. (Note: Employees will already appear in the left
hand pane, in the “Other Tables” node. You may leave that node as is).

7. Select the new “Employees” node, which appears as a child to the Orders
table, then select the “LastName” field from the fields list, then press the
select button to bring it into the listbox formatter list.
ANNOTATED EXAMPLES 69

8. Close and save the Window Formatter changes.


Now you can apply the ASP browse extension:
1. In the Application Tree, right click the BrowseOrders procedure and
choose Rename from context menu. Rename the procedure
“CustomerViewSpecial” and press OK.

2. Back in the Application Tree, right click the CustomerViewSpecial


procedure and choose Extensions from the context menu. This opens the
Extensions and Control Templates dialog.
3. Press the Insert button to insert a new extension.
4. Choose ASPBrowse from the Select Extension dialog and press Select.
The Clarion/ASP browse extension template is now applied, and may now be
customized.

Note that the browse box control in the window structure of this procedure
already includes columns from two other tables: the company name from the
customers table, and the employee last name from the employee table, which
you added in the Window Formatter. You won’t have to worry about the SQL
necessary to join the tables to display the data from the additional tables
because Clarion/ASP will do it for you automatically.
70 CLARION/ASP

The next step is to review the columns in the data columns list, place them in
the proper order, place links to other procedures where necessary, and hide
some of the columns because they’re unnecessary to the end user (but useful
to have in the SQL Select statement).
1. Scroll to and select the Data Columns tab.
2. Verify that the following columns appear in this order by using the up,
down, and delete buttons where necessary: CompanyName (from
Customer), OrderID, OrderDate, RequiredDate, ShippedDate, LastName
(from Employees), EmployeeID, CustomerID, ShipVia, Freight, and
ShipName.

3. Double click the OrderID field; we’ll make this a link to the update form
(view only). Note that while we could just enable the automatic detail
link as View Only, that would lead to only the data from the view; by
linking to the Orders table, we’ll display other information. More
importantly, this provides you with experience in populating a link to a
procedure manually.
4. In the Data Columns dialog, select the Actions tab.
5. Choose “Procedure Link” from the “Create this column as link”
dropdown.
6. Choose “Data Column” from the “Pass this data” dropdown.
7. Choose “Order ID” from the “Data column to pass” dropdown.
8. Choose “Update Orders” from the procedure to link dropdown.
9. Choose “View” as the “type of procedure, and press OK to close the
Data Columns dialog. Creating links to another procedure page is a
straightforward means of creating a flow from procedure to procedure
for the end user. In this case, all Order ID’s in the list will appear as
links, so that merely by clicking an order the end user sees the order
information. Press OK.
ANNOTATED EXAMPLES 71

10. Back in the Prompts for ASP Browse dialog, double click the Employee
ID field to display the Data Columns dialog.
11. This column will serve as a link to the Employee update form (view
only). Select the Actions tab.
12. Choose “Procedure Link” from the “Create this column as link”
dropdown.
13. Choose “Data Column” from the “Pass this data” dropdown.
14. Choose “Employee ID” from the “Data column to pass” dropdown.
15. Choose “Update Employees” from the procedure to link dropdown.
16. Choose “View” as the “type of procedure, and press OK to close the
Data Columns dialog.
You’ll set the final four columns in the data columns list so that they’re part
of the recordset, but not displayed in the browse. This is useful in that it
allows Clarion/ASP to automatically link the tables with join statements (you
could delete the fields entirely, but then you’d write the SQL yoursellf). Take
the following steps on each of these four fields in turn: CustomerID,
ShipVia, Freight, and ShipName:
1. Double click the field name.
2. Place a checkmark in the “Include in SQL Select but do not Display”
box, in the top group box of the General tab.
72 CLARION/ASP

3. Press OK to close the Data Columns dialog.


4. Press OK twice to close the Extensions and Control Templates dialog.
The Orders browse is now complete.

The Browse on the ProductPhotos View


The final browse for modification is the browse on the ProductPhotos view.
This procedure, like the last, also requires renaming because the custom
links we created before will use the string from the “type” field (“customer”
or “supplier”) to dynamically create the name of the procedure page to call.
Once you’ve renamed the procedure, then you can apply the ASP browse
extension template:

You may optionally modify the listbox control in the window structure of
this procedure so that it includes columns from two other tables: the
company name from the suppliers table, and the category name from the
categories table (since we already demonstrated that in the last section, and
it’s a Clarion, not a Clarion/ASP item, we will not repeat those instructions).

To apply the ASP extension:


1. In the Application Tree, right click the BrowseviewProductPhotos
procedure and choose Rename from context menu. Rename the
procedure “SupplierViewSpecial” and press OK.
2. Back in the Application Tree, right click the SupplierViewSpecial
procedure and choose Extensions from the context menu. this opens the
Extensions and Control Templates dialog.
3. Press the Insert button to insert a new extension.
4. Choose ASPBrowse from the Select Extension dialog and press Select.
The Clarion/ASP browse extension template is now applied, and may now be
customized.
ANNOTATED EXAMPLES 73

The next step is to review the columns in the data columns list, place them in
the proper order, place links to other procedures where necessary, and hide
some of the columns because they’re unnecessary to the end user (but useful
to have in the SQL Select statement).
1. Scroll to and select the Data Columns tab.
2. Verify that the following columns appear in this order by using the up,
down, and delete buttons where necessary: ProductName, Product ID,
Supplier ID, Company Name (optional, from the Suppliers table),
Quantity per Unit, Photo, Category ID, and Category Name (optional,
from Categories).

3. Double click the ProductName field; we’ll make this a link to the update
form (view only).
4. In the Data Columns dialog, select the Actions tab.
5. Choose “Procedure Link” from the “Create this column as link”
dropdown.
6. Choose “Data Column” from the “Pass this data” dropdown.
7. Choose “Product ID” from the “Data column to pass” dropdown. Note
that this time we’ve chosen one field for display, and a completely
different field which will server as the ?ID value when passing the
parameter to the update form.
8. Choose “Update viewProductPhotos” from the procedure to link
dropdown.
9. Choose “View” as the “type of procedure, and press OK to close the
Data Columns dialog.

You’ll set three more columns in the data columns list so that they’re part of
the recordset, but not displayed in the browse. Take the following steps on
each of these four fields in turn (note: these are not contiguous in the list):
Product ID, Supplier ID, and Category ID:
1. Double click the field name.
74 CLARION/ASP

2. Place a checkmark in the “Include in SQL Select but do not Display”


box, in the top group box of the General tab.
3. Press OK to close the Data Columns dialog.
4. Press OK twice to close the Extensions and Control Templates dialog.
Note: though we chose not to display the photos in this particular browse,
you can indeed display jpg and gif file data within your browses. We
recommend, of course, that you consider the download times, and set the
number of rows accordingly, If, for example, you place jpg files in a fifteen
row browse, and their average size is 80KB, you’ve added 1.4MB to the
download.

The ProductPhotos browse is now complete, and now it’s time to move on to
the update forms.

The Update Procedures


The application contains five view only update forms, plus one search form.
The first three update forms require little customization.

The Update Customers Form


1. In the Application Tree, right click the UpdateCustomers procedure and
choose Extensions from the context menu. this opens the Extensions and
Control Templates dialog.
2. Press the Insert button to insert a new extension.
3. Choose ASPForm from the Select Extension dialog and press Select.
4. In the Prompts for ASP Form dialog, select the Actions tab, and uncheck
all actions except View, and then check Generate QBF.
5. Select “BrowseViewContacts” from the Parent Browse Dropdown list
(we wish to return the end user back to the special view page instead of
the normal parent browse).
6. Press OK to close the Extensions and Control Templates dialog.

The Clarion/ASP form extension template is now applied, and may now be
customized.
ANNOTATED EXAMPLES 75

The Update Orders Form


1. In the Application Tree, right click the UpdateOrders procedure and
choose Extensions from the context menu. this opens the Extensions and
Control Templates dialog.
2. Press the Insert button to insert a new extension.
3. Choose ASPForm from the Select Extension dialog and press Select.
4. In the Prompts for ASP Form dialog, select the Actions tab, and uncheck
all actions except View, and then check Generate QBF.
5. Select “CustomerViewSpecial” from the Parent Browse Dropdown list
(we wish to return the end user back to the special view page instead of
the normal parent browse).

6. Press OK to close the Extensions and Control Templates dialog.

The Clarion/ASP form extension template is now applied, and may now be
customized.

The Update Suppliers Form


1. In the Application Tree, right click the UpdateSuppliers procedure and
choose Extensions from the context menu. this opens the Extensions and
Control Templates dialog.
2. Press the Insert button to insert a new extension.
3. Choose ASPForm from the Select Extension dialog and press Select.
4. In the Prompts for ASP Form dialog, select the Actions tab, and uncheck
all actions except View, and then check Generate QBF.
5. Select “BrowseViewContacts” from the Parent Browse Dropdown list
(we wish to return the end user back to the special view page instead of
the normal parent browse).
6. Press OK to close the Extensions and Control Templates dialog.
76 CLARION/ASP

The Clarion/ASP form extension template is now applied, and may now be
customized.

The Update Employees Form


The customizations to this form will consist of adding a photo as a custom
control. First, you’ll need to remove it from the controls list (otherwise it just
shows up as high ASCII characters.
1. In the Application Tree, right click the UpdateEmployees procedure and
choose Extensions from the context menu. this opens the Extensions and
Control Templates dialog.
2. Press the Insert button to insert a new extension.
3. Choose ASPForm from the Select Extension dialog and press Select.
4. In the Prompts for ASP Form dialog, select the Actions tab, and uncheck
all actions except View and Generate QBF.
5. Select “CustomerViewSpecial” from the Parent Browse Dropdown list
(we wish to return the end user back to the special view page instead of
the normal parent browse).
6. Scroll to and select the Controls tab.
7. Locate the Photo field in the controls list; press the properties button,
uncheck the populate option for this field, and close the Controls dialog.
8. Scroll to and select the Custom Controls tab.
9. Press the Insert button.
10. Type Photo as both the control name and caption.
11. Select “Above” for the control location. When you place a custom
control in an update form, you may locate it either above or below all of
the edit controls on the form. As always, you may load the runtime
HTML template for the update form in an HTML editor, and move the
template symbols to any layout you wish.
12. Choose “Static Text” from the “Populate From” box, being sure to leave
the “Enter display text” box as blank. Since we don’t wish to display
anything but the picture, we must indicate there is no data.
ANNOTATED EXAMPLES 77

13. On the Actions tab, press the Image button to display the Image dialog.
14. Select “Data Column” from the “Populate From” drowdown list.
15. Choose Employee ID from the field list dialog for the “ID Value”
column. This indicates the unique value column for use with SQL select
statements.
16. Choose “Employees” from the Select Table dialog for the source table.
Note that this and the previous choice allow for populating the image
from another table and that Clarion/SQL will then handle the necessary
SQL.
17. Select “Employee ID” column from the fields list for the “ID Column.”
This duplication is necessary because of the option to display an image
stored in another table.
18. Select “Photo” from the fields list for the image column. Note that in
previous steps, you ran a command file which loaded the employee table
with photographs. These are not part of the Northwind sample database
by default.
19. Select “jpg” from the Image type dropdown list.

20. Press OK three times to return to the Application tree.

The Update viewProductPhotos Form


The Northwind database in its default form has no product photos field. The
database you attached contains a product photos table, consisting of the
product ID and the binary field for the photo. It also created a view called
viewProductPhotos, consisting of both the products and product photos
tables.
78 CLARION/ASP

The only customization necessary for this procedure is to add the photo.
1. In the Application Tree, right click the UpdateviewProductPhotos
procedure and choose Extensions from the context menu. this opens the
Extensions and Control Templates dialog.
2. Press the Insert button to insert a new extension.
3. Choose ASPForm from the Select Extension dialog and press Select.
4. In the Prompts for ASP Form dialog, select the Actions tab, and uncheck
all actions except View and Generate QBF.
5. Select “SupplierViewSpecial” from the Parent Browse Dropdown list
(we wish to return the end user back to the special view page instead of
the normal parent browse).
6. Scroll to and select the Custom Controls tab.
7. Press the Insert button.
8. Type Photo as both the control name and caption.
9. Select “Below” for the control location.
10. Choose “Static Text” from the “Populate From” box, being sure to leave
the “Enter display text” box as blank. Since we don’t wish to display
anything but the picture, we must indicate there is no data.

11. On the Actions tab, press the Image button to display the Image dialog.
12. Select “Data Column” from the “Populate From” drowdown list.
13. Choose Product ID from the field list dialog for the “ID Value” column.
This indicates the unique value column for use with SQL select
statements.
14. Choose “viewProductPhotos” from the Select Table dialog for the source
table.
15. Select “Product ID” column from the fields list for the “ID Column.”
ANNOTATED EXAMPLES 79

16. Select “Photo” from the fields list for the image column. Note that in
previous steps, you ran a command file which loaded the employee table
with photographs. These are not part of the Northwind sample database
by default.
17. Select “jpg” from the Image type dropdown list.
18. Press OK three times to return to the Application tree..

Generate the ASP Pages


Congratulations. You’ve finished setting up your Clarion/ASP application
and are ready to generate and test on your local machine.

The generation process is no different than normal Clarion source code


generation. The only difference is that in addition to the Clarion source code
modules, the application generator also produces .asp pages, as well as htm
files.

To generate your project, with only the Application Tree window open,
choose Project > Generate All from the development environment menu.

The Frames
This application utilizes a simple two part (left and right )HTML frame,
which is provided to you in the project\asp\html directory. The main feature
of the frame is a search form on the left which allows the end user to specify
category type (contact or supplier), plus type in all or part of the contact
name, company name and country name.

The Search Frame


This frame is a slightly modified query by form page, and was produced by
Clarion/ASP. This page was modified after generation in an HTML editor to
make it narrow enough to serve as a “navigation” frame.

Clarion/ASP outputs HTML runtime templates. These are normal HTML


pages with symbols (existing simply as HTML text) representing the
locations in which the ASP page will “place” its fields and labels at the time
it merges the data and the template to output the page that the end user sees
in the browser. Because the form fields correspond to the field names in the
database (pre-pended with “txt), it’s simple to load the runtime template into
an HTML editor, and quickly identify the part you wish to move.

It’s very important to note that after you’ve edited the file that unless you
turn off the HTML generation (on the Clarion/ASP global properties/
generation tab), your changes will be overwritten.
80 CLARION/ASP

The HTML runtime templates reside in the project\asp\html directory. They


share the same name as their corresponding asp file name (i.e., the procedure
name, plus “list,” “add,” “edit,” “view,” or “search.”

For the search example, we’ve supplied the modified HTML template, and
placed it outside that directory, so that you won’t overwrite it by issuing the
Generate command before you’ve read this section. This file is located in the
project directory. We suggest that you copy it into its normal location, but
then set the file attribute to read only, so that you won’t accidentally
overwrite it. Note that this will produce an warning during the generate
process.
1. Locate the \C55\examples\asp\search\UpdateviewContactsSearch.htm
file.
2. Copy it to the \C55\examples\asp\search\asp\html directory.
3. Right click the
\C55\examples\asp\search\asp\html\UpdateviewContactsSearch.htm
which you just copied and choose Properties from the context menu.
4. Check the Read Only attribute box and press OK to change the property.
You can also turn off the HTML generation option, but we recommend that
until you’re thoroughly familiar with what files Clarion/ASP creates and
where it places them that you use this method.

Additionally, we set the target of the Submit and Reset buttons so that the
search results would output to the main frame, leaving the search frame
always available to the end user, at the left hand side.

Needless to say, should the end user not type in any parameters, but instead
merely push the submit button, a target page, the browse on the contacts
view, would appear without any filter.

Because you copied the HTML file, you do not need to perform any editing;
however, so that you can understand how we modified the HTML, below are
the steps which would be taken if you did have to modify the HTML.
Compared to the customization of the HTML page and elements, the
ANNOTATED EXAMPLES 81

customization for the form target isn’t as readily available because the
<FORM> tag is stored in the ASP page, and not in the HTML page. To
duplicate this functionality, you would hand edit the ASP page you generated
as follows:
1. Open the generated page, which is
project\asp\UpdateviewContactsSearch.asp. You may load it into
notepad.
2. Search for “FormDeclaration.” You’ll find the following line:
FormDeclaration = "<form name='form1' id='form1' method='POST'
action='BrowseviewContactsList.Asp' >"

3. Insert the following before the closing angle bracket:


target='mainFrame'

The complete line should look like this:


FormDeclaration = "<form name='form1' id='form1' method='POST'
action='BrowseviewContactsList.Asp' target='mainFrame'>"

4. Save the file and exit notepad.


5. Right click the project\asp\UpdateviewContactsSearch.asp which you
just edited and choose Properties from the context menu.
6. Check the Read Only attribute box and press OK to change the property.
Final Note: should you wish to enable security on an application such as this,
you could easily enable it on all pages except the search frame. This would
allow all users to load the frame and see the search form, plus an
introductory page (described below). The login would appear only after the
end user pressed the submit button. There are two methods you could use to
create the search from without security: (1) turn off security on the
UpdateviewContactsSearch procedure. Since this application doesn’t use this
procedure except for the search (it uses the UpdateCustomer and
UpdateSupplier, but not this one), that presents no problem. But what if you
82 CLARION/ASP

wished to accomplish the same in another application, and you wished a


regular update to have security on for the update, but off for the search? In
that case (2) you must generate all the pages with security on, copy the
generated pages to another directory, regenerate with security off, and copy
just the search page to that other directory. Alternately, you can edit the
single generated page for the search. A single line turns on security; you
could delete it, or comment it out (place a single quote character at the
beginning of the line:
<!-- #include file="login.asp"-->

Generate the Project


You may now generate the project with the Project > Generate All command.
Please note, however, you will receive a compiler warning, because the
template will attempt to overwrite the read-only search form runtime
templage you previously copied to the asp directory. Simply ignore the error.

Examining the Frame Set


The Frame Set refers to an HTML page which merely contains information
placing two or more other HTML pages “inside” it. The frame set for this
project is called default.htm, and a copy resides in the project\asp directory:
<html>
<head>
<title>Northwind Contact Search</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<frameset cols="171,*" frameborder="NO" border="0" framespacing="0"
rows="*">
<frame name="leftFrame" scrolling="NO" noresize
src="UpdateviewContactssearch.asp">
<frame name="mainFrame" src="html/intro.htm">
</frameset>
<noframes><body bgcolor="#FFFFFF" text="#000000">
</body></noframes>
</html>

The HTML above simply sets the page title, the size of the navigation (or
search frame), the names of the two pages which will be placed in the left
frame and main frame, and a body background color.

The Main Frame


The initial page which appears in the main frame, as per the HTML frame set
code above, is called intro.htm. This is simply a page with a logo and short
instructions. Since the application has to first tell people what they can
search for (via the search frame) before they actually begin viewing the date,
it makes sense to show simple instructions.
ANNOTATED EXAMPLES 83

The following is the code for the intro window:


<title>SoftVelocity Demo Center -- Clarion/ASP</title>
<body bgcolor="#EFF3FF">
<table width="100%" border="0" cellspacing="0" cellpadding="0"
align="center" height="100%">
<tr>
<td align="center" valign="middle">
<p>&nbsp;</p>
<p><img src="/IMAGES/SoftVelocityLogo240w.GIF" width="240"
height="127"></p>
<p>This demonstrates Clarion/ASP flexibility in dynamically calling
various
procedures based on end user selections.</p>
<p>Enter search criteria to begin the demo.</p>
</td>
</tr>
</table>

Setting Up the Virtual Directory in IIS


The output is placed in the project\asp directory, as well as directories
beneath it called HTML, images, and styles. Before you may test, however,
you must “tell” Internet Information Server where the application is:
1. From the Windows Start menu, choose Start > Programs >
Administrative Tools > Internet Information Services (the exact name
and location of the IIS configuration manager may vary slightly from
version to version of Windows.

2. Open each successive node in the tree pane at the left of the Internet
Information Services manager until you can see the “Default Web Site”
node.
3. Right click on the “Default Web Site” node and from the popup menu,
choose New > Virtual Directory.
4. Press Next to skip past the introductory pane of the Virtual Directory
Wizard.
5. On the second pane, enter “search” in the Alias box. This will serve as
the name for the virtual directory. Press Next.
84 CLARION/ASP

6. Press the Browse button next to the Directory box on the next panel.
Browse to the application’s directory, then locate the asp directory
beneath it and select the asp directory. If you’ve installed to the default
Clarion directory and followed our suggestion for the application
directory name above, that directory should be
\C55\examples\asp\search\asp.

7. Press the Next button twice, and the Finish button, accepting the
defaults.

Running Your First Test


Clarion/ASP automatically generates an “index” or “table of contents” page
for you. This allows you to test your procedures easily, but is not meant for
deployment (it’s simply a list of textual links to the procedures, grouped by
procedure type).
1. Open your browser.
2. Open the URL http://localhost/search/index.htm.
If you did not receive an index page listing your procedures, either IIS
isn’t running or you did not set up your virtual directory correctly. Go
back to the beginning of this exercise and review those sections.
3. Click on the link to the Browse/BrowseviewContactsList.asp.
4. Examine the browse (which should be non-filtered, and contain all the
customer/supplier records, approximately 120 total) and verify that it
“looks” the way it should: A company name column, a contact/title
column, a phone number, and a column at the right with three graphics,
ANNOTATED EXAMPLES 85

which should lead to either customer or supplier view form, an orders or


products browse filtered to the selected row ID, or another contacts
browse filtered to the country of the selected row ID.

5. Navigate through the subsequent links and verify that you see the various
view only update forms, including those for products and employees,
which should display the photos.

Testing the Search Frame


Now you can test the search frame:

1. Open the URL http://localhost/search/default.htm.


2. Type a letter such as “M” or “J” in the contact name field and press the
Submit button.
86 CLARION/ASP

3. Verify that the browse which appears in the main frame (the right hand
side) is properly filtered to show only those contacts whose first names
start with the letter you just typed.

Congratulations, you’ve built the search application. Explore the resot of the
application as you desire. You’ll find view only update forms and pictures of
employees and products.
ANNOTATED EXAMPLES 87

6. THE ORDERS EXAMPLE


The Orders example provides an opportunity to show how extensible
Clarion/ASP is. This chapter will set up more complex behaviors, such as
forms and browses on the same procedure page, and demonstrate the editing
of the generated ASP and HTML runtime template pages. Additionally, you
may further use the application as a “jumping off” point for demonstrating
the use of VBScript in Clarion/ASP embed points (as documented in the
User’s Guide).

You’ll find those pages which were customized post generation in a file
called custom.zip in the project\asp\ and project\asp\html directories. Feel
free to unzip and use these files if you wish to follow the Users Guide in
editing the pages.

Setup and Global Properties


1. Choose File > New > Application.
2. Navigate to Clarion\examples\asp\Orders in the Open File dialog, and
name your Application Orders.app.
Note: we’ve included a finished example called complete.app. Feel free
to examine this. Important: you cannot generate and run the complete
example as is, because you must first edit the connection string to
reference your DBMS server.
3. Choose the Northwind dictionary in the Application Properties. Make
sure the Application Wizard box is checked and run the Application
Wizard (not Quick Start).
4. Uncheck the “Include all files” box; instead, include only the following
tables/views: Employees; Categories; Customers; Shippers; Suppliers;
Orders; view Order Details Extended; Managers; Order Details;
Products; view Orders Query. Uncheck the Generate All Reports option.
Apply the Global template/Connection Properties
1. From the development environment menu, choose Application > Global
Properties.
2. In the Global Properties dialog, press the Extension button, then the
Insert button.
3. In the Extension and Control Templates dialog, press the Insert button.
4. Choose the ASP Global Extension Template (class SV ASP) in the Select
Extension dialog and press the Select button.
88 CLARION/ASP

5. In the Extension and Control Templates dialog, with the ASP global
extension selected, select the Database tab on the right side of the dialog.
6. Press the Connection Properties button on this tab. The Connection
Properties dialog appears.
7. Enter a valid user name for the database.
8. Enter a password for that user.
9. Press the Call Connection Builder button.
10. Select the Provider tab, if the dialog did not automatically open to it, and
choose Microsoft OLE DB Provider for SQL Server, then press the Next
button.
11. On the Connection tab, enter the server name, or choose it from the drop
list in item number 1.
12. Enter the user name and password for the database in item number 2.
13. Check the “Allow Saving Password box,” in number 2. You must not
skip this step, else Internet Information Server has no way to log into the
database.
14. Type “northwind” in the “Select the database on the server” box.
15. Press the “Test Connection” button, and verify that you receive a success
message. If not, review the settings in this dialog.
16. Press the OK button to close the Data Link Properties dialog. You should
have now returned to the Connection Properties dialog, and a connection
string something like the one below should appear at the bottom of this
dialog: Provider=SQLOLEDB.1;Password=YourPassword;Persist
Security Info=True;User ID=YourUsername;Initial
Catalog=northwind;Data Source=YourDataServer.
17. Press the OK button to close the Connection Properties dialog.

General Tab
Style Sheet

1. In the Global Extension dialog, click on the Global tab.


2. In the Cascading Style Sheets group box, press the Style Sheet Editor
button.
3. Press the Insert button to declare a new style. The Style Sheet dialog
appears.
ANNOTATED EXAMPLES 89

4. Type in “MyStyles” in the file name box at the top.


5. Accept the defaults for the hyperlinks styles, and click on the Body Tag
tab.
6. Set the body width by typing 100% in the width box.
7. Set the body color. Delete the current background color (COLOR:
White). Press the ellipsis next to the background color. Click on a blank
custom color box. Define a new custom color with the RGB values of
255, 243, and 255. The color should be an off white. Select Add to
Custom Colors and press OK. The value 0FFF3FFH should appear in the
background color box.

8. Set the text alignment to null by choosing the bottom (empty) dropdown.
9. Click on the Background Class tab. Set the width to 100% by typing it in
the width box.
10. Set the background color to COLOR:NONE by typing it in the
background color box.
11. Click on the Data tab. Set the width to 100% by typing it in the width
box.
12. Delete the current background (0FF990H). Press the ellipsis next to the
background color. Click on a blank custom color box; either below or to
the right of the first custom color box that you filled previously. Define a
new custom color with the RGB values of 255, 153, and 0. The color
should be somewhat orange. Select Add to Custom Colors and press OK.
The value 099FFH should appear in the background color box.
13. Press the Borders button. Four group boxes, for the top, bottom, left and
right border lines each contain three options for the line style, width and
color. Set the Line Width for all four sides to “thin.”
14. Set the Line Style for all four sides to solid.
15. Set the Background Color box for all four sides to COLOR:NONE. The
grid, therefore, will pick up the “surrounding” color when it “divides”
the individual cells in the grid.
90 CLARION/ASP

16. Press OK to close the Borders dialog.


17. Back in the Style Sheet dialog, in the sub classes group, press the Header
button. This controls the appearance of the text at the very top of
browses and forms, in effect, the “caption” area. Delete the current
background color (0FF990H).
18. Press the ellipsis button next to the background color. In the Color Picker
dialog, press Define Custom Colors, click on a blank custom color box
and in the right side of the dialog define a new custom color with 198,
89, and 24 respectively for the red, green, and blue values. The sample
box should show a brown-ish color. Press the “Add to Custom Colors”
button, then press OK. The value 01859C6H should appear in the
Background Color box.
19. Back in the header dialog, set the text alignment to left.
20. Press the font button. In the font dialog, delete the current font color
(COLOR:Black), and press the ellipsis next to the color. Locate the color
you created for the body (values of 255, 243, and 255). The color should
be off white. The value 0FFF3FFH should appear in the background
color box. Press OK to close the font dialog.
21. Back in the Style Sheet dialog, press the Column Label button.
22. In the Column Label dialog, delete the current background color and
press the ellipsis (...) button next to the background color box. Click on a
blank custom color box. Define a new custom color with the values of
120, 168, and 255. The color should be light blue. The value 0FFA878H
should appear in the background color box. Press OK to close the dialog.
23. Back in the Column Label dialog, set the text alignment to Left.
24. Press the Font button, delete the current value (COLOR:Black) and set a
new font color: press the ellipsis (...) button next to background color.
Click on a blank custom color box. Define a new custom color with the
values of 222, 235, and 239. The color should be yet another shade of off
white. The value 0EFEBDEH should appear in the background color
ANNOTATED EXAMPLES 91

box. Press OK to close the dialog, and OK once more to close the
Column Label dialog.
25. Press the Data Rows button. We’ll declare two classes for data row
appearance. First, however, set the grid spacing thickness to 1.
26. Press the Insert button and type “MyDataRow” in the class name box in
the Data Rows dialog.
27. In the same dialog, delete the current background color (0DCDCDCH)
and set a new background color: choose the custom color you defined for
the column label text (values of 222, 235, and 239, another shade of off
white. The value 0EFEBDEH should appear in the background color
box.
28. Set text alignment to null (last "empty" entry in the dropdown list).

29. Back in the Data Rows dialog, press Insert to create another class for
data row, and type “AlternateRow” in the class name box.
30. In the same dialog, delete the current background color (0DCDCDCH)
and press the ellipsis (...) button next to background color. Open the
Color Picker dialog, and choose the very first custom color you created
(one of the off whites; RGB values 255/243/255, Hex value 0FFF3FFH.
31. Set text alignment to null (last "empty" entry in the dropdown list). Press
OK to close the Data Rows dialog.
32. Back in the Style Sheet dialog, press the Footer button. Delete the
current background color (0FF9900H) and then press the ellipsis button
next to background color in the next dialog. Set a new background color:
click on a blank custom color box. Define a new custom color with the
values of 239, 150, and 123, hex 0FFF3FFH. The color should be
brown-ish-red. The value 07B96EFH should appear in the background
color box.
33. Back in the Footer dialog, set text alignment to left, then press OK to
close the Footer dialog.
34. Press the Input Label button, delete the current background color and
press the ellipsis (...) button next to background color. Click on a blank
custom color box. Define a new custom color with the values of 242,
242, and 242. The color should be off white. The value 0F2F2F2H
should appear in the background color box. Press OK to close the dialog.
35. Back in the Input Label dialog, Press the Font button, delete the current
font color (COLOR:Black) and set a new font color: press the ellipsis
92 CLARION/ASP

(...) button next to background color. Click on a blank custom color box.
Define a new custom color with the values of 32, 32, and 32. The color
should be dark gray. The value 0202020H should appear in the
background color box. Press OK to close the dialog, and OK again to
close the Input Label dialog.
36. Back in the Style Sheet dialog, press the Input button.
37. In the Input dialog, delete the current background color (0DCDCDCH)
and press the ellipsis (...) button next to the background color.Select the
off white defined for the MyDataRow (RGB values 222/235/239, hex
0EFEBDEH. Press OK to close the Input dialog.
38. Press OK to close the Style Sheet dialog.
39. Press OK to close the Style Sheet Editor dialog.
40. Press the Style Sheets button and choose the MyStyles style sheet for all
four options. Then press OK to close the dialog and apply the style
choices at the global level.

Design Time Template


1. Verify that the attachment (generic.htm) is located in your project\HTML
directory. This template provides for links to what will be the
“switchboard” (which will act as a limited table of contents) and to
selected query pages. When creating Clarion/ASP projects it’s useful to
consider a design time template such as this so that every single part of
the application will have access to the other parts.
Below is the design time template, as loaded in an HTML editor. Note
the links in the small table at upper left. Note also that the “Clarion/
ASP” symbol (into which AppGen will merge it’s code when generating
the runtime templates from this plus the template options) is located in
another table, which will center the Clarion/ASP content (this is only an
option and is not required of your applications.
ANNOTATED EXAMPLES 93

3. Press the Default Templates button on the Global tab.


4. Type generic.htm into each of the four boxes for the design time
template.
5. Press OK to close the dialog.
List Defaults
1. Press the List Defaults button on the Global tab.
2. Set the Data Records per HTML list to 6 rows.
3. Uncheck “Show Add Button on DB Navigation Bar.” Where desired, we
will add a custom “new” button to the various procedures.
4. Uncheck the “Show QBF Button on DB Navigation Bar.” The design
time template will contain links to the queries we wish to allow.
5. Press OK to close the dialog.

Security Tab
This next set is optional. This chapter will not mention user level security at
the procedure levels. Should you expect to deploy this sample application to
a server connected to the Internet, by all means apply security, and set access
levels according to those used by your security table.

1. Click on the Security tab in the global extension.

2. Check the Provide User Based Security box.

3. Set the User Table to aspusers (or whichever security table you use).

4. Set the unique ID column to ID.

5. Set the login name column to Email.

6. Set the login password column to password.

7. Set the Security Level column to accesslevel.

8. Set the User email column to email.

9. Set the user name column to First_Name.

10. Set the second user name column to Last_name.


94 CLARION/ASP

Administration Tab
1. Click on the Administration tab in the global extension.
2. Type "Northwind Traders" in the Site Title box.
3. Press OK to close the global extensions.

Prep the Procedures


Apply the ASP browse and form templates (according to whichever is
applicable) to the following procedures, accepting all the defaults for now.
Note: it may help to click the "Category" tab in the app tree, so that you view
the procedures by type.
• BrowseCategories
• BrowseCustomers
• BrowseEmployees
• BrowseOrders
• BrowseOrder_Details
• BrowseProducts
• BrowseShippers
• BrowseSuppliers
• Browse_view_order_details_extended (you’ll be required to set the
unique key to keyOrderProd on the HTML Table tab for this one because
there is no key with a PRIMARY attribute in the dictionary. We’ve done
this purposely, because you may sometimes encounter VIEW definitions
in which one was not declared.)
• SelectCategories
• SelectManagers
• SelectOrders
ANNOTATED EXAMPLES 95

• SelectProducts
• UpdateCategories
• UpdateCustomers
• UpdateEmployees
• UpdateOrders
• UpdateOrder_Details
• UpdateProducts
• UpdateShippers
• UpdateSuppliers
• UpdateViewOrdersQuery

The Browse Procedures


Note that later in this chapter, when it’s time to explain editing generated
ASP code that we will do further customizations some of these same
browses.

Customize the BrowseProducts procedure:

1. Open the BrowseProducts procedure.


2. Open the window, right click on the browse box and open the list
formatter.
3. Add a new field. In the select column dialog, File Browsing Listbox
node, click on the Products table, press the Insert button, and choose the
Categories table. Select the Category Name field from the right hand
pane. Note that though the Categories table is already in the "Other
Tables" node, you must still insert it.
96 CLARION/ASP

4. Add another new field. In the select column dialog, File Browsing
Listbox node, click on the Suppliers table, press the Insert button, and
choose the CompanyName field from the right hand side. Note that
though the Suppliers table is already in the "Other Tables" node, you
must still insert it.

5. Close the Listbox and Window formatters, and open the ASP browse
extension.
6. On the Data Columns tab, press the Insert button, insert the
CAT:CategoryName field and press OK.
7. On the Data Columns tab, press the Insert button, insert the
SUP:CompanyName field and press OK.
8. Doubleclick the CategoryID field, and check the "Include in SQL Select
but do not display box." The logic is that there is no need for the end user
to view ID number fields.
9. Doubleclick the ProductID field, and check the "Include in SQL Select
but do not display box."
10. Doubleclick the SupplierD field, and check the "Include in SQL Select
but do not display box."

11. Reorder the fields to the following order:


• Product Name
• Category Name
• Supplier Company Name
• Quantity Per Unit
ANNOTATED EXAMPLES 97

• Unit Price
• Units in Stock
• Units On Order
• Reorder Level
• (the CategoryID, ProductID and SupplierID fields can be in any order)
13. Format the Unit Price field by doubleclicking it, opening the appearance
tab and setting the formatting functions dropdown to currency, and
choosing 2 digits after decimal. Press OK.

14. Doubleclick the Category/CategoryName field. Click its Actions tab. Set
the first dropdown to Procedure Link. Specify passing a data column. In
the Data Column to pass, specify PRO:CategoryID. Set the procedure to
link to to UpdateCategories. Set the Action to View. Click OK.
Throughout the browses you will insert links to related tables wherever
possible.
15. Doubleclick the Supplier/CompanyName field. Click its Actions tab. Set
the first dropdown to Procedure Link. Specify passing a data column. In
the Data Column to pass, specify PRO:SupplierID. Set the procedure to
link to UpdateSuppliers. Set the Action to View. Click OK.

16. On the Page tab, press the Regenerate SQL button.


17. Close the Procedure.
98 CLARION/ASP

Browse Customers Procedure

1. Open the BrowseCustomers procedure, ASP extension.


2. Select the Data Columns tab.
3. Doubleclick the CustomerID tab and check the "Include in SQL select
but do not display" button.
4. Doubleclick the Contact Title column. Check the "Include with Prior
Column" box. Enter <BR> in the "preceding text" box (line break). In
this table we will include a multi line address column.

5. Doubleclick the Address column. Check the "Include with Prior


Column" box. Enter <BR> in the "preceding text" box (line break).
6. Doubleclick the City column. Check the "Include with Prior Column"
box. Enter <BR> in the "preceding text" box (line break).
7. Doubleclick the Region column. Check the "Include with Prior Column"
box. Enter &nbsp; in the "preceding text" box (non breaking space).
ANNOTATED EXAMPLES 99

8. Doubleclick the Postal Code column. Check the "Include with Prior
Column" box. Enter &nbsp;&nbsp; in the "preceding text" box (two non
breaking spaces). (Note: leave the Country field as is; this is a useful
column to separate, in that sorting by country could be desired).
9. Close and save the changes for the procedure by pressing OK.

The Browse Employees Procedure

1. Open the BrowseEmployees procedure, ASP extension.


2. Click on the Data Columns tab.
3. Use the Delete button so that you have only the following fields: Last
Name, First Name, Employee ID, Title, Birth Date, Hire Date.
100 CLARION/ASP

4. Double click the Employee ID field and check the "Include in SQL select
but do not display" button.
5. Double click the First Name field. Click the column sorting tab.
Uncheck the enable sorting button. There is no need to include
extraneous sort options.

6. Double click the Title Name field. Click the column sorting tab.
Uncheck the enable sorting button.
7. Click the Page tab and press the Regenerate SQL button.
8. Click the HTML table tab, check the "populate an entry locator" button,
and select the Last Name field from the drop down field list. (note: there
are only 8 employees in this table; this is just for practice!).

9. Close and save the Browse Employees procedure by pressing OK.


ANNOTATED EXAMPLES 101

The Browse Orders Procedure

1. Open the Browse Orders procedure.


2. Open the window, right click on the browse box and open the list
formatter.
3. Add a new field. In the select column dialog, click on the Orders table,
press the Insert button, and choose the Customers table. Select the
Company Name field from the right hand pane. Note that though the
Customers table is already in the "Other Tables" node, you must still
insert it.
4. Add a new field. In the select column dialog, click on the Orders table,
press the Insert button, and choose the Employees table. Select the Last
Name field from the right hand pane. Note that though the Employees
table is already in the "Other Tables" node, you must still insert it.

5. Add a new field. In the select column dialog, click on the Orders table,
and from the right hand side, select the ORD:RequiredDate field (the
original SQL field, not the Clarion group).
6. Add a new field. In the select column dialog, click on the Orders table,
and from the right hand side, select the ORD:ShippedDate field (the
original SQL field, not the Clarion group).
102 CLARION/ASP

7. Add a new field. In the select column dialog, click on the Orders table,
and from the right hand side, select the ORD:OrderDate field (the
original SQL field, not the Clarion group).
8. Add a new field. In the select column dialog, click on the Orders table,
and from the right hand side, select the ORD:PostalCode field.
9. Add a new field. In the select column dialog, click on the Orders table,
and from the right hand side, select the ORD:Country field.
10. Close the listbox and window formatters. By adding file drop control
templates to a window you instruct Clarion/ASP to provided a table
loaded dropdown instead of a button which leads to a select browse.
11. Open the asp extension.
12. Select the Data Columns tab, and using the Insert button, add
CUS:CompanyName, EMP:LastName, ORD:OrderDate,
ORD:RequiredDate, ORD:ShippedDate, ORD:PostalCode, and
ORD:Country to the list of controls.
13. Double click on OrderID, CustomerID, and EmployeeID, and for each
check the "Include in SQL Select but do not display" box.
14. Using the delete button, delete the Freight field.
15. Make sure the field order is as follows: OrderDate,
CustomerCompanyName, Employee Last Name, Required date, Shipped
date, Shipped Via (the shipper ID), Ship Name, Ship Address, Ship City,
Ship Region, Ship Postal code, and ShipCountry. The order of the "do
not display fields" (OrderID, CustomerID, and EmployeeID) doesn't
matter.

16. Doubleclick the Company Name field and click the Actions tab. Set the
field up as a Procedure Link, passing the column ORD:CustomerID, to
the UpdateCustomers procedure, in View mode.
17. Doubleclick the Employee Last Name field and click the Actions tab. Set
the field up as a procedure link, passing the column ORD:EmployeeID,
to the UpdateEmployees procedure, in View mode.
ANNOTATED EXAMPLES 103

18. Doubleclick the Ship Via field and click the Actions tab. Set the field up
as a procedure link, passing the column ORD:ShipVia, to the
UpdateShippers procedure, in View mode. note that “ShipVia” is the ID
number for the shipper in this table layout.
19. Doubleclick the Ship Name column. Check the "Include with Prior
Column" box. Enter &nbsp;&nbsp;&nbsp;<i>Shipped to:</i><BR> in
the "preceding text" box. To explain: the shipper number (the previous
column) will be a hyperlink. Following that will be two spaces, the
words "Shipped to" in italics, a line break, and then the ship name.

20. Doubleclick the Ship Address column. Check the "Include with Prior
Column" box. Enter <BR> in the "preceding text" box.
21. Doubleclick the Ship City column. Check the "Include with Prior
Column" box. Enter <BR> in the "preceding text" box.
22. Doubleclick the Ship Region column. Check the "Include with Prior
Column" box. Enter &nbsp; in the "preceding text" box.
23. Doubleclick the Ship Postal Code column. Check the "Include with Prior
Column" box. Enter &nbsp;&nbsp; in the "preceding text" box.
24. Click the Page tab and press the Regenerate SQL button.

25. Click the Custom Controls tab.


26. Double click the Automatic Details Link which the template already
generated.
104 CLARION/ASP

27. In the Procedure to Link dropdown list, change the target procedure to
UpdateviewOrdersQuery and press OK. This is a view only update form
upon an existing view in the database.
28. Close the Browse Orders procedure.

The Browse View Order Details Extended Procedure


1. Open the Browse view Order Details Extended procedure, ASP
extension.
2. Click the Data Columns tab. Double click the Order ID field. Check the
Include in SQL Select but do not display box.
3. Select the Custom Columns tab. Double click the Automatic Detail Link.
Change the Procedure to Link to to the Update Order Details procedure
and press OK.

Note: This is a very important concept. In some of the example


procedures above, we let the template create a custom JOIN select. here
we used a VIEW already present on the DBMS. The only drawback is
that we don’t accept an automatic detail link to the update in these cases
(some DBMS’s support updatable VIEWs, but it’s best to avoid them).
When using a VIEW for the browse, it’s simple enough to “point” the
update to an update(s) on the component table(s).
In general, using VIEWs for the browse is better because the DBMS
probably optimizes VIEWs, hence, returnd the data faster than had you
used a SELECT with JOIN. This exercise demonstrates both methods so
that you know that you can use either.
4. Back on the Custom Columns tab, press the Insert button to add a new
custom column.
5. Name the column “Add” by typing it in the Column Name box.
6. From the “Create Column as Link” dropdown, choose Custom Link.
ANNOTATED EXAMPLES 105

7. Type the following in the Custom link box. It calls the Add procedure for
the Order Details table and primes the invoice number by setting the
value of the text box in the HTML form which will contain the variable
via a URL parameter. Note that custom links are just one way to prime a
form; using a static link with additonal parameters is another.
<A HREF=UpdateOrder_DetailsAdd.asp?txtOrder_DetailsOrderId=" &
oRSview_Order_Details_Extended.Fields("OrderID").Value & "><IMG
SRC='" & IconAdd & "' BORDER='" & IconBorder & "' HEIGHT='" &
IconHeight & "' WIDTH='" & IconWidth & "' ALT='Insert New Item'></A>

8. Save the Order Details Extended procedure.

The Browse Categories Procedure


This procedure demonstrates enabling the end user to click on the lookup
button and return a single value to a selected field. The Select Products
example later in this chapter will demonstrate returning two values.

1. Open the Browse Categories procedure, ASP extension.


2. Click the Data Columns tab. Select the Picture field and press the Delete
button. You may include a graphic image in a browse, but it must be in
the custom controls list. For this procedure, we will simply delete it.
3. On the Page tab, press the “Regenerate SQL” button.

The Select Managers Procedure


This select/lookup browse is called by the Employees update form.
106 CLARION/ASP

1. Open the Select Managers procedure, ASP extension.


2. Select the Page tab, and check the “This is a Select Procedure” box.
3. Set MGR:Last Name as the column to hyperlink.
4. Press the Column Assignments button, then Insert to add an assignment.
5. Press the ellipsis button next to the “Column to Fill From” box.
6. Click MGR:EmployeeID and press the Select button.
7. Press the ellipsis button next to the “Target Column” box.
8. Select the “Other Tables” node in the Tables pane of the Select Column
dialog, press the Insert button, add the Employees table, then select
EMP:EmployeeID field (the Employee update will be the calling
procedure).
9. Press OK three times to close the dialogs and save the procedure
changes.

The Select Orders Procedure


This select/lookup procedure is called by the Order Details update.
1. Open the Select Orders procedure, ASP extension.
2. Select the Page tab, and check the “This is a Select Procedure” box.
3. Set ORD:OrderID as the column to hyperlink.
4. Press the Column Assignments button, then Insert to add an assignment.
5. Press the ellipsis button next to the “Column to Fill From” box.
6. Click ORD:OrderID and press the Select button.
ANNOTATED EXAMPLES 107

7. Press the ellipsis button next to the “Target Column” box.


8. Select the “Other Tables” node in the Tables pane of the Select Column
dialog, press the Insert button, add the Order Details table, then select
ORD2:OrderID field (the Order Details update will be the calling
procedure).
9. Press OK three times to close and save the procedure changes.

The Select Products Procedure


This select/lookup procedure is called by the Order Details update.
1. Open the Select Products procedure, ASP extension.
2. Select the Page tab, and check the “This is a Select Procedure” box.
3. Set PRO:ProductName as the column to hyperlink.
4. Press the Column Assignments button, then Insert to add an assignment.
5. Press the ellipsis button next to the “Column to Fill From” box.
6. Click PRO:ProductID and press the Select button.
7. Press the ellipsis button next to the “Target Column” box.
8. Select the “Other Tables” node in the Tables pane of the Select Column
dialog, press the Insert button, add the Order Details table, then select
ORD2:ProductID field (the Order Details update will be the calling
procedure).
9. Press OK to return to the Column Assignments dialog.
10. Press Insert to add another column to assign. This demonstrates how to
call a lookup and return multiple values. We wish the lookup to fill in
both the Product ID and the unit price.
11. Press the ellipsis button next to the “Column to Fill From” box.
12. Click PRO:Unit Price and press the Select button.
13. Press the ellipsis button next to the “Target Column” box.
14. Click on the Order Details table inserted in step 8, and then select
ORD2:UnitPrice
15. Press OK three times to close the dialogs and save the procedure
changes.
108 CLARION/ASP

The Update Procedures


The UpdateCategories Procedure

This will be one of the four main “entry points” to the application, in that an
HTML “intro” page will provide links to form/navigation procedures to
Categories, Suppliers, Products and Orders, each starting at the first row.
1. Select the UpdateCategories procedure.
2. Open the ASP extension.
3. On the Actions tab, uncheck all actions except View. This will disallow
anyone from adding a category.

4. Select the Custom Controls tab, and double click on the CAT:Picture
field.

5. Click on the Actions tab and press the Image button. The template
extension automatically populates the image field to this tab, but you are
responsible for setting the image source and type (there is no way for the
template to determine the image type, i.e, .JPG or .GIF, so this will be
done in the next step. Note also the field contents for all records for this
binary field have been modified vs. the original Northwind database. In
the sample database shipped with MS SQL Server, the binary images
were stored as bitmaps. The custom file which you previously attached
ANNOTATED EXAMPLES 109

to the server contain exactly the same images, except stored in .GIF
format, for display in browsers. Should you attempt to display the
bitmap binary data in a browser, the ASP page would generate an error.
6. In the Image dialog, choose Populate from Data Column.
7. Specify CategoryID for the ID Value Column.
8. The Table With Image box should already be filled with “Categories.”
9. Set the ID column to Category ID.
10. Choose “Picture” for the Image column.
11. Choose .GIF for the image type.

12. Press OK to close the Image dialog.


13. Press OK to close the Controls dialog.
14. Back on the Prompts for ASPForm dialog, Custom Controls tab, press
the Insert button to insert another custom control.
15. Name this one "ProductsLink" by typing that name in the Control name
box.
16. Set the control location to below, and the "populate from" to static text.
17. Type "Products..." in the Enter Display Text box. This text will serve as a
tooltip for the image we will specify in a later next step.
18. Select the Actions tab.
19. Specify this is a Procedure Link in the "Create this as a link" dropdown.
20. Specify "Key value" in the "Pass this data" dropdown. Note that
sometimes this exercise specifies passing a key, and at others, a column.
Either is acceptable.
21. Select Cat:Categories (which will be the category ID number) as the key
to pass.
22. Specify BrowseProducts as the procedure link.
23. Specify List as the type of procedure.
110 CLARION/ASP

24. Press the Image button.


25. Select "Disk file" as the "Populate from" options.
26. Type pointingfinger.gif in the file name box.
37. Press the OK button three times to finish editing the procedure.

The UpdateCustomers Procedure

1. Select the UpdateCustomers procedure.


2. Open the ASP extension.
3. On the Actions tab, uncheck the Delete box. This will disallow anyone
from deleting a customer.
4. Click on the Custom Controls tab and press Insert to add a new custom
control.
5. Type "Orders" as the control name.
6. Type "View List of Orders for this Customer" for the Caption.
7. Set the control location to "Below."
8. Set the "Populate from" to "Static Text."
ANNOTATED EXAMPLES 111

9. Type "Orders..." as the display text.

10. Select the Actions tab.


11. Choose "Procedure Link" in the "Create this as a link" dropdown.
12. Choose "Data column" in the "Pass this data" dropdown.
13. Choose “CUS:CustomerID” as the data column to pass.
14. Choose "Browse Orders" as the procedure to link to.
15. Set the type of procedure to "List" and press OK.

16. On the Actions tab, check the “Generate QBF” box and specify the
Browse Customers procedure as the parent browse. Optionally return to
the Controls tab, and specify that non essential (in your opinion) fields
not be included in the Query by Form by double clicking the field, and
checking the Omit from QBF Page box. In general, query forms should
have as few fields as possible, so as not to overwhelm the end user, and
where possible, the fields should be key components or included in
indices, for best performance.
Note: remember when populating a checkbox control on a query form
that unchecked does not mean null (or no choice for that field). It means
the query seeks records for which the value for that field is false. This
concept could be confusing for many end users; therefore we recommend
that when using Queries as a main navigation aid for your applications
that you review the use of checkboxes.
112 CLARION/ASP

17. Press OK to return to the application tree. Note: the User’s Guide
“demonstrates” embed code as an addition to this procedure, using
embedded VBScript and adding custom controls to display the most
recent order and the total value of all orders for the customer.

The UpdateEmployees Procedure

1. Select the UpdateEmployees procedure.


2. Open the window in this procedure.
3. Locate the Photo field and delete it. It should be on the “General” tab.
4. Close and save the Window.
5. Open the ASP extension.
6. On the Actions tab, uncheck the Delete box. This will disallow anyone
from deleting a customer.
7. Select the Custom Controls tab, and press the Insert button to insert a
new control.
8. Type "Photo" in the control name field. Set the control location to above,
and the "populate from" to static text. Leave the display text blank; the
page will only display the picture.
9. Select the Actions tab and press the Image button.
10. Choose "Data column" from the populate from dropdown list.
11. Select Emp:EmployeeID as the ID value column (the unique field for this
table).
ANNOTATED EXAMPLES 113

12. Select Employees as the table with the image (this dialog allows you to
display an image from another table as well as the one currently open).
13. Select Emp:EmployeeID as the ID value column (the unique field for the
table, the same one, with the image).
14. Select Emp:Photo as the column with the image.
15. Select jpg as the image type. IMPORTANT: this depends upon the use of
the custom Northwind database supplied with Clarion/ASP.

16. Press OK twice to close the Image and Controls dialogs.


17. Back in the Prompts for ASPForm dialog, click on the Controls tab.
18. Double click the ReportsTo field to display the properties dialog.
19. Click on the Validation tab.
20. From the Procedure to Call drop box, select the SelectManagers
procedure. Because this tab includes the “Must be in File” choice, it will
automatically populate a lookup button which will call the procedure so
that the end user can select a manager from a list. Press OK. Note that in
other procedures we “short circuited” this behavior by substituting table
loaded lists for selects, using the File Drop control template after
deleting the entry field from the window structure.
21. On the Actions tab, check the “Generate QBF” box and specify the
Browse Employees procedure as the parent browse. Optionally return to
the Controls tab, and specify that all non essential fields should not be
included in the Query by Form by double clicking the field, and checking
the Omit from QBF Page box.
22. Press OK to close the Controls dialogs and return to the Application tree.
114 CLARION/ASP

The UpdateOrders Procedure

1. Select the UpdateOrders procedure.


2. Open the window for this procedure.
3. Select the CustomerID field and delete it. We will replace it with a
control template so that the end user will see a table loaded list box.
4. Select the EmployeeID field and delete it. We will also replace this with
a control template so that the end user will see a table loaded list box.
5. Select the Control Templates tool from the Tools palette, choose "File
Drop." When the Select Column dialog appears, locate the new “File
Loaded Drop Box” node, select the “To Do” node beneath it, press the
Insert button, select the Customers table from the table list, then back in
the Control Templates dialog, locate the “Update Record on Disk” node,
select the Orders table which will be located as its subordinate node,
then select the Orders CustomerID field from the right side of the dialog
and press Select.
6. The cursor should change to a cross hair. Click inside the window.
7. Locate the Customers table node under the File Drop box you added two
steps ago, click it, then add the Customers CompanyName field to the
list box, which should then be visible in the right hand pane. Press OK to
return to the window.
8. The List box formatter should now appear containing the CUS:Company
Name column. Press OK.
ANNOTATED EXAMPLES 115

9. Right click on the newly placed drop down list control and choose
Actions. Set the field to fill from to Cus:CustomerID, the target field to
Ord:CustomerID (from the node under the “Update Record on Disk”
node), press Select, and press OK to close the List Properties dialog.

10. Select the Control Templates tool from the Tools palette, choose "File
Drop." When the Select Column dialog appears, locate the new “File
Loaded Drop Box” node, select the “To Do” node beneath it, press the
Insert button, select the Employees table from the table list, then back in
the Control Templates dialog, locate the “Update Record on Disk” node,
select the Orders table which will be located as its subordinate node,
then select the Orders EmployeeID field from the right side of the dialog
and press Select.
11. The cursor should change to a cross hair. Click inside the window.
12. Locate the Employees table node under the File Drop box you added two
steps ago, click it, then add the Employees Last_Name field to the list
box, which should then be visible in the right hand pane. Press OK to
return to the window.
13. The List box formatter should now appear containing the
Emp:Last_Name column. Press OK.
14. Right click on the newly placed drop down list control and choose
Actions. Set the field to fill from to Emp:EmployeeID, the target field to
Ord:EmployeeID (from the node under the “Update Record on Disk”
node), and press OK.
116 CLARION/ASP

15. Close and save the window changes.


16. Select the ASP form extension.
17. Select the Custom Controls tab, and press the Insert button to insert a
new control.
18. Type "ViewOrderDetail" in the control name field. Set the control
location to below, and the "populate from" to static text. Type "Order
Details..." for the display text.
19. Select the Actions tab.
20. Select "Procedure Link" from the "Create this as a Link" dropdown.
21. Choose "Key Value" in the "Pass this Data" dropdown.
22. Choose "Ord:Order" as the key to pass.
23. Select "Browseview_Order_Details_Extended" as the procedure link.
24. Set the type of link to List.

25. Press the Image button.


26. Choose "Disk file" from the populate from dropdown list.
ANNOTATED EXAMPLES 117

27. Type "editpencil.gif" as the image file name and press OK.
28. On the Actions tab, verify that the “Generate QBF” box is checked and
that the Browse Orders procedure is listed as the parent browse.
Optionally return to the Controls tab, and specify that all non essential
fields should not be included in the Query by Form by double clicking
the field, and checking the Omit from QBF Page box.
29. Press OK to save the changes and return to the Application Tree.

The UpdateOrder_Details Procedure

1 Open the UpdateOrderDetails procedure to the ASP extension.


2. Select the Actions tab.
3. Set the parent browse to BrowseView_Order_Details. Note: the strategy
in this is as follows: where the information in a View is more user
friendly than the DBMS table you’re interested in updating, set the
browse upon the view, and the update upon the table. When doing so,
you must "connect back" from the form to the browse view, in the event
that there are no records found for the form.

4. Select the Controls tab.


5. Doubleclick the OrderID field, then select the Validation tab. The client
side validation should be set for “Must be in File.” Set the Select
118 CLARION/ASP

procedure to “Select Orders” from the dropdown list and press the OK
button.
6. Doubleclick the ProductID field, then select the Validation tab. The
client side validation should be set for “Must be in File.” Set the Select
procedure to “Select Products” from the dropdown list and press the OK
button.
7. Save the procedure changes and return to the Application Tree.

The UpdateProducts Procedure

1. Select the UpdateProducts procedure.


2. Open the window for this procedure.
3. Select the SupplierID field and delete it. We will replace it with a control
template so that the end user will see a file loaded list box.
4. Select the CategoryID field and delete it. We will also replace this with a
control template so that the end user will see a file loaded list box.
5. Select the Control Templates tool from the Tools palette, choose "File
Drop." When the Select Column dialog appears, locate the new “File
Loaded Drop Box” node, select the “To Do” node beneath it, press the
Insert button, select the Suppliers table from the table list, then back in
the Control Templates dialog, locate the “Update Record on Disk” node,
select the Products table which will be located as its subordinate node,
then select the Products SupplierID field from the right side of the dialog
and press Select.
6. The cursor should change to a cross hair. Click inside the window.
ANNOTATED EXAMPLES 119

7. Locate the Suppliers table node under the File Drop box you added two
steps ago, click it, then add the Suppliers CompanyName field to the list
box, which should then be visible in the right hand pane. Press OK to
return to the window.
8. The List box formatter should now appear containing the PRO:Company
Name column. Press OK.

9. Right click on the newly placed drop down list control and choose
Actions. Set the field to fill from to SUP:SupplierID, the target field to
PRO:SupplierID (from the node under the “Update Record on Disk”
node), and press OK.
11. Back in the window, select the Control Templates tool from the Tools
palette, choose "File Drop." When the Select Column dialog appears,
locate the new “File Loaded Drop Box” node, select the “To Do” node
beneath it, press the Insert button, select the Categories table from the
table list, then back in the Control Templates dialog, locate the “Update
Record on Disk” node, select the Products table which will be located as
its subordinate node, then select the Products CategoryID field from the
right side of the dialog and press Select.
12. The cursor should change to a cross hair. Click inside the window.
13. Locate the Categories table node under the File Drop box you added two
steps ago, click it, then add the CategoryName field to the list box,
which should then be visible in the right hand pane. Press OK to return
to the window.

14. The List box formatter should now appear containing the CAT:Category
Name column. Press OK.
120 CLARION/ASP

15. Right click on the newly placed drop down list control and choose
Actions. Set the field to fill from to CAT:CategoryID, the target field to
PRO:CategoryID (from the node under the “Update Record on Disk”
node), and press OK.

16. Close and save the window changes.


17. Open the ASP form extension.
18. On the Actions tab, uncheck the Delete box. This will disallow anyone
from deleting a product.
16. Click on the Custom Controls tab and press Insert to add a new custom
control.
17. Type "Photo" as the control name.
18. Set the control location to "Above."
19. Set the "Populate from" to "Static Text."
20. Type "Orders..." as the display text.
21. Select the Actions tab.
22. Press the Image button.
23. Choose "Populate from Data Column."
24. Select PRO:ProductID for the ID value column.
25. Click on the ellipsis button next to the “table with image” box. Select
Products from the Update Record on Disk node, press Insert, and choose
viewProductPhotos as the table with image (on the other tables tab; no
relation was described in the dictionary). Note that in this case we're
populating from a related table by providing a unique ID from this table.
26. Select vpp:ProductID as the ID column (in the other table).
27. Select vpp:Photo as the column containing the image.
ANNOTATED EXAMPLES 121

28. Set the Image type to jpg and press OK, and press OK again to close the
Controls dialog.

29. On the Actions tab, check the “Generate QBF” box and specify the
Browse Products procedure as the parent browse. Optionally return to the
Controls tab, and specify that all non essential fields should not be included
in the Query by Form by double clicking the field, and checking the Omit
from QBF Page box.

30. Press OK to close the controls and extension dialogs and return to the
Application Tree.

The UpdateShippers Procedure

1. Select the UpdateShippers procedure.


2. Open the ASP extension.
3. On the Actions tab, uncheck all but the View box. This will disallow
anyone from editing or adding a shipper.
4. Press OK to close the dialog and return to the Application tree.
122 CLARION/ASP

The UpdateSuppliers Procedure

1. Select the UpdateSuppliers procedure.


2. Open the ASP extension.
3. On the Actions tab, uncheck the Delete box. This will disallow anyone
from deleting a supplier.
4. Select the Custom Controls tab, and press the Insert button to insert a
new control.
5. Type "Products" in the control name field. Set the control location to
below, and the "populate from" to static text.
6. Type "View this Supplier's Products" in the "Text to display" box.
7. Select the Actions tab.
8. Choose "Custom Link" from the "Create this as link" dropdown list.
9. Type the following in the custom link box:
<a href='BrowseProductsNoRangeSelectList.asp?WHR=dbo.Suppliers.SupplierID="
& MID(TRIM(oRSSuppliers("SupplierID")),1,50) & "'><img src='IMAGES/
pointingfinger.gif' alt='View This Suppliers Product List'
border='0'></a>

This calls a copy of the Browse Products procedure (note: we haven't


created that copy yet, but we will) with a custom WHERE clause. It fills
the WHERE clause with the supplier ID from the current record, and
displays a pointing finger graphic to signify the link.
ANNOTATED EXAMPLES 123

10. Press OK to close the Controls dialog.


11. Back in the Prompts for ASPForm dialog, on the custom controls tab,
press the Insert button to insert another custom control.
12. Type "AddNewProduct" in the Control Name box.
12. Type "Add a New Product for this Supplier" in the caption box.
13. Choose "below" for the control location.
14. Choose Populate from "static text."
15. Type "Add a New Product for this Supplier" in the display text box.
16. Click the Actions tab.
17. Select "Procedure Link" from the "Create this as a link" dropdown.
18. Choose "Static entry" from the "Pass this data" dropdown.
19. Type 0 in the static entry box; the Add procedure doesn’t use ID1.
20. Type the following in the Additional Parameters box:
Attention: the following code sample works only when the target is an entry
box; but in this case, it’s a list box, therefore the following code will NOT
work. Because we wish to show the “right” way for priming a field first,
we’ve included this code at this point. In the following chapter, which
contains instructions on editing the ASP files post-generation, we will
provide instructions for correcting this case:
&txtProductsSupplierID=" & MID(TRIM(oRSSuppliers("SupplierID")),1,50) & "

This appends a parameter for the form field on the update products form,
supplying the current supplier ID. Note the unmatched double quote at
the end of the line; this is mandatory because the template provides its
“match.” If just entering a string for the parameter, it’s not necessary.
124 CLARION/ASP

21. Choose "Update Products" from the Procedure Link dropdown.


22. Choose Add as the type of procedure.
23. Press OK twice to save the changes and return to the Application tree.

The ViewOrdersQuery Procedure

Note: this update procedure acts upon a view in the database. We do not
intend to actually update this view; only view it. This form is a good
"jumping off point" for links to other procedures, and we will place five
custom controls on it. Remember that just because you have a form doesn’t
mean you have to call the browse... and you can still call any thing else you
want from it. And conversely, there’s no harm in calling an update form for a
view, if it’s in view only mode.

1. Select the UpdateViewOrdersQuery procedure.


2. Open the ASP extension.
3. On the Actions tab, uncheck all but the View box.
ANNOTATED EXAMPLES 125

4. Select the Custom Controls tab, and press the Insert button to insert a
new control.
5. Name the control name "Update."
6. Type "Update Order" in the caption box.
7. Set the control location to "above."
8. Choose "static text" for the "Populate from" option.
9. Type "Update Order" in the "Text to display" box.
10. Select the Actions tab.
11. Create the link as a Procedure link.
12. Specify a "key value" from the "Pass this data" dropdown.
13. Choose VOQ:Order as the key to pass.
14. Choose UpdateOrders from the Procedure Link dropdown.
15. Set the Type of Procedure to Edit.

16. Press the Image button.


17. Choose "Populate from disk file."
18. Type order20x20.gif in the filename box.
19. Press OK to save the Custom Control, and press OK again to close the
Controls dialog. Note these and other “new” images are provided in the
project\asp\images directory.
20. Back on the Prompts for ASPForm dialog, press the Insert button to
insert another custom control.
21. Name the control name "CustomerData."
22. Type "View Customer Data" in the caption box.
126 CLARION/ASP

23. Set the control location to "above."


24. Choose "static text" for the "Populate from" option.
25. Type "View Customer Data" in the "Text to display" box.
26. Select the Actions tab.
27. Create the link as a Procedure link.
28. Specify a "Data column" from the "Pass this data" dropdown.
29. Choose VOQ:CustomerID as the key to pass.
30. Choose UpdateCustomers from the Procedure Link dropdown.
31. Set the Type of Procedure to View.
32. Press the Image button.
33. Choose "Populate from disk file."
34. Type customer20x20.gif in the filename box.
35. Press OK to save the Custom Control, and OK again to close the
Controls dialog.
36. Back on the Prompts for ASPForm dialog, press the Insert button to
insert another custom control.
37. Name the control name "EmployeeData."
38. Type "View Employee Data" in the caption box.
39. Set the control location to "above."
40. Choose "static text" for the "Populate from" option.
41. Type "View Employee Data" in the "Text to display" box.
42. Select the Actions tab.
43. Create the link as a Procedure link.
44. Specify a "Data column" from the "Pass this data" dropdown.
45. Choose VOQ:EmployeeID as the key to pass.
46. Choose UpdateEmployees from the Procedure Link dropdown.
47. Set the Type of Procedure to View.
48. Press the Image button.
ANNOTATED EXAMPLES 127

49. Choose "Populate from disk file."


50. Type employee20x20.gif in the filename box.

51. Press OK to save the Custom Control, and OK again to close the
Controls dialog.
52. Back on the Prompts for ASPForm dialog, press the Insert button to
insert another custom control.
53. Name the control name "ShipperData."
54. Type "View Shipper Data" in the caption box.
55. Set the control location to "above."
56. Choose "static text" for the "Populate from" option.
57. Type "View Shipper Data" in the "Text to display" box.
58. Select the Actions tab.
59. Create the link as a Procedure link.
60. Specify a "Data column" from the "Pass this data" dropdown.
61. Choose VOQ:ShipVia as the key to pass.
62. Choose UpdateShippers from the Procedure Link dropdown.
63. Set the Type of Procedure to View.
64. Press the Image button.
65. Choose "Populate from disk file."
66. Type shipper20x20.gif in the filename box.
67. Press OK to save the Custom Control, and OK again to close the
Controls dialog.
68. Back on the Prompts for ASPForm dialog, press the Insert button to
insert another custom control.
69. Name the control name "OtherOrders."
70. Type "Other Orders for this Customer..." in the caption box.
128 CLARION/ASP

71. Set the control location to "above."


72. Choose "static text" for the "Populate from" option.
73. Type "Other Orders for this Customer..." in the "Text to display" box.
74. Select the Actions tab.
75. Create the link as a Procedure link.
76. Specify a "Data column" from the "Pass this data" dropdown.
77. Choose VOQ:CustomerID as the key to pass.
78. Choose BrowseOrders from the Procedure Link dropdown.
79. Set the Type of Procedure to List and the type to View.
80. Press the Image button.
81. Choose "Populate from disk file."
82. Type order20x20.gif in the filename box.
83. Press OK twice to save the Custom Control.

84. Press OK to save the procedure changes and return to the Application
Tree.

Range Limits and "Duplicate" Browses


We previously set up links to two not-yet existent procedures. A browse may
either be range selected or not, and if range selected, it must be range
selected to a single field. When it’s required that a browse sometimes be
range selected and sometimes not, you must either set a custom ?WHR
clause, or create two copies of the browse with different names, range
selecting one, and not the other.
ANNOTATED EXAMPLES 129

The BrowseOrders Procedure


1. Select the BrowseOrders procedure in the Application Tree and open the
ASP browse Extension.
2. Select the Data Columns tab.
3. Double click the Customer ID field.
4. Select the "Range Limit on this Column" box on the General tab in the
Data Columns dialog and press OK.

5. On the Page tab, press the “Regenerate SQL” button.


5. Press OK to return to the Application Tree.

The BrowseProducts Procedure


1. Select the BrowseProducts procedure in the Application Tree and open
the ASP browse Extension.
2. Select the Data Columns tab.
3. Double click the Supplier ID field.
4. Select the "Range Limit on this Column" box on the General tab in the
Data Columns dialog.
5. On the Page tab, press the “Regenerate SQL” button.
6. Press OK to return to the Application Tree.

The BrowseView_Order_Details_Extended Procedure


1. Select the BrowseView_Order_Details_Extended procedure in the
Application Tree and open the ASP browse Extension.
130 CLARION/ASP

2. Select the Data Columns tab.


3. Double click the Order ID field.
4. Select the "Range Limit on this Column" box on the General tab in the
Data Columns dialog and press OK.
5. On the Page tab, press the Regenerate SQL button.
6. Press OK to return to the Application Tree.

Copy the BrowseOrders Procedure


1. Select the BrowseOrders procedure in the Application Tree.
2. From the development environment menu, choose Procedure > Copy.
3. In the New Procedure dialog, name the new procedure
BrowseOrdersNoRangeSelect.

4. In the Procedure Name Clash dialog, choose "Same." We wish the new
procedure to perform exactly as the current one with only one exception.
As the new procedure is created, several template symbol error messages
will appear. Ignore them.
5. Once the new procedure (BrowseOrdersNoRangeSelect) is added to the
tree, select the BrowseOrdersNoRangeSelect procedure in the
Application Tree and open the ASP browse Extension.
6. Select the Data Columns tab.
7. Double click the Customer ID field.
8. Uncheck the "Range Limit on this Column" box on the General tab in the
Data Columns dialog.
9. Press OK to return to the browse extension dialog.
10. On the Page tab, press the “Regenerate SQL” button.
11. On the Default SQL tab, clear the “Enter a Where clause to filter this
list” box. Note that Clarion/ASP never automatically clears this box
because it’s possible that the developer has manually entered a WHERE
clause. The “Regenerate SQL” button only affects the SQL Select and
the ORDER BY boxes.
12. Press OK to return to the Application Tree.
ANNOTATED EXAMPLES 131

Copy the BrowseProducts Procedure


1. Select the BrowseProducts procedure in the Application Tree.
2. From the development environment menu, choose Procedure > Copy.
3. In the New Procedure dialog, name the new procedure
BrowseProductsNoRangeSelect.

4 In the Procedure Name Clash dialog, choose "Same." We wish the new
procedure to perform exactly as the current one with only one exception.
As the new procedure is created, several template symbol error messages
will appear. Ignore them.
5. Once the new procedure (BrowseProductsNoRangeSelect) is added to
the tree, select the BrowseProductsNoRangeSelect procedure in the
Application Tree and open the ASP browse Extension.
6. Select the Data Columns tab.
7. Double click the Supplier ID field.
8. Uncheck the "Range Limit on this Column" box on the General tab in the
Data Columns dialog and press OK.
9. On the Page tab, press the “Regenerate SQL” button.
10. On the Default SQL tab, clear the “Enter a Where clause to filter this
list” box. Note that Clarion/ASP never automatically clears this box
because it’s possible that the developer has manually entered a WHERE
clause. The “Regenerate SQL” button only affects the SQL Select and
the ORDER BY boxes.
11. Press OK to return to the Application Tree.
At this point you should generate all the procedures, create your virtual
directory, and run the index.htm page to test them.
132 CLARION/ASP
ANNOTATED EXAMPLES 133

7. CUSTOMIZING GENERATED PAGES


This chapter provides examples of modifying the generated files.

In this specific case, we have planned an application which opens onto four
form navigations: Categories, Suppliers, Products, and Orders. From these
four, the end user should be able to view data from related tables and views
based on the linking fields. We wish for two of the opening form nav's,
Categories and Orders, to display both the record for that table (or view in
the latter case), plus the contents of a child browse (products for the former,
order details for the latter). To do so, we edit the ASP generated files. Then,
to display the additional data, we edit the HTML runtime templates.

This provides the step by step instructions.

The Categories Form with Filtered


Products Browse Beneath

1. Open the Clarion\examples\asp\orders\asp directory in Explorer and


copy BrowseProductsList.asp to BrowseProductsList2.asp. Because
you’ll be making changes to the ASP file, we want to have one “regular”
browse, to display only the products, plus this other file, which we’ll
“include” below the categories form.
2. Open BrowseProductsList2.asp in notepad and delete line one (<%@
Language=VBScript %>). This is an ASP statement which may only be
included once within an ASP page.
134 CLARION/ASP

3. In the same file, delete the standard include files, starting at about line
20. Because the file “including” this one has the same includes, you
don’t want to include them twice: it would mean that the variable
declarations would be repeated.
<!-- #include file=AppData.asp-->
<!-- #include file=adovbs.inc-->
<!-- #include file=utils.asp-->

4. Do a search and replace: objCN --> objCN2. This declares a separate


connection object for the browse.
5. Search for the following string on line all by itself and delete it.
Otherwise, it would be a duplicate declaration.
"DIM CategoriesCategoryName"

6. Search for the string "call MergeBrowse." This is part of the name of a
function, and only appears once in the file. It will call this browse's
complementary HTML runtime template, using a variable called
HTML_template as a parameter. Change the name of that parameter to
“html/BrowseProductsList2.htm” -- important -- note that you’re adding
double quotes! Instead of using a variable, you’re using a string as the
parameter. You’ll be making a copy of the template shortly, so don’t
worry that the actual file doesn’t exist yet.
7. Search for the string “test for any value in myOrder”. Insert the
following line before that:
mySQL = mySQL & “ WHERE dbo.Products.CategoryID= “ & myVar

Notes: in the steps below, you’ll define the myVar variable in another
file; the variable will hold the CategoryID, which will filter this browse.
8. Save and close the BrowseProductsList2.asp file.
9. Open UpdateCategoriesView.asp with notepad. Search for “DIM
dbNavBarPrev, dbNavBarNext.” It should be very close to the end of the
file. Add the following code just before that line. Don’t forget to
substitute your table/column name should you be using this as a guide
for changing an application of your own:
DIM myVar
myVar = oRSCategories.Fields("CategoryID").Value

Notes: the code above declares a variable, and places the current
CategoryID number into it. In the “bottom part” of the page, on the
related browse, we’ll use that variable to filter the browse. Because
we’re joining the pages together, the other page will have access to the
variable.
10. Approximately 20 lines below the lines you just inserted, you’ll find a
that starts with “Call MergeUpdateCategoriesTemplate,” with the
runtime variable as a parameter. Now you’ll set the session variable.
Insert the following lines immediately below the line with the Call to the
merge procedure. And yes, the <% and %> are reversed, because you're
ANNOTATED EXAMPLES 135

splitting up an existing block and starting a new one! You’re instructing


that the HTML generation process include the corresponding ASP page
for the child browse. That must be done outside the ASP block, hence we
split that block.
%>
<!-- #include file="BrowseProductsList2.asp" -->
<%

11. Using Explorer, locate the


\C55\examples\asp\orders\asp\html\BrowseProductsList.htm file, and
copy it to BrowseProductsList2.htm.
12. Open BrowseProductsList2.htm, in an HTML editor or Notepad. Delete
every line from the top of the file to the line that says <table
CLASS="Data" CELLSPACING="1">. The reason for this is that you’re
including this file inside another file, and therefore you may not repeat
the “header” information.
13. Open the html/UpdateCategoriesView.htm file. Delete every line below
the </form> tag, which will be close to the bottom of the file. This is the
complementary step to the last step; This file now contains the beginning
of the HTML file, whereas the previous file contained the end.
14. In the same file, search and delete for any occurrences of the following
strings: class = label; class = bg; class = data. Leave everything else on
those lines as is. By doing this, you delete the style sheet formatting tags,
which allow us to let the background image we’ll later insert to “show
through” the table.
15. Note: this and the following step are just for appearance, and could be
done in an HTML editor. In the same file, find this line: <td
class="Input" >@CategoriesPicture@&nbsp;</td> and delete the class=
Input.
16. Find this line: <td class="Input">@ProductsLink@&nbsp;</td> and
delete the class= Input on this line and the line below it.
17. Back in the Clarion development environment, on the ASP extension,
override and turn off HTML generation for UpdateCategories (that
procedure’s Global tab, General subtab).
136 CLARION/ASP

You’ve now set the scene so that when calling the Update Categories View
page, it in turn calls the Products browse page, and together they merge their
output to their respective runtime templates, which you “sewed” together
into what will appear to the end user as a single page.

ViewOrdersQuer y Form with the


view_Order_Details_Extended Browse

Note: Because the layout of the runtime template for the view orders query
form is markedly changed, we've provided an “edited” file in the project
directory. The HTML customizations are outside the scope of this manual.
But there are some points worth considering: inserting a table within a table
allows you to set up the “indents” in the areas such as customer address and
shipping address; the button row on top is simply an extra row into which the
custom control symbols were cut and pasted.
1. Copy Browseview_Order_Details_ExtendedList.asp to
Browseview_Order_Details_ExtendedList2.asp. Just as in the previous
example, we wish to allow the use of the browse by itself, not limiting it
to use as an element in the form view.
2. Open Browseview_Order_Details_ExtendedList2.asp in notepad and
delete line one (<%@ Language=VBScript %>). This statement may
only be present once within an ASP page.
3. In the same file, delete the standard include files, starting at about line
20, which would otherwise be duplicated, resulting in duplicate variable
declarations:
<!-- #include file=AppData.asp-->
<!-- #include file=adovbs.inc-->
<!-- #include file=utils.asp-->
ANNOTATED EXAMPLES 137

4. Do a search and replace: objCN --> objCN2. This declares a separate


connection object for the browse, preventing any clash with the
connection object for the form.
5. Search for the string
"MergeBrowseview_Order_Details_ExtendedListTemplate." It will call
this browse's complementary HTML runtime template, using a variable
called HTML_template as a parameter. Change the name of that
parameter to “html/Browseview_Order_Details_ExtendedList2.htm” --
important -- note that you’re adding double quotes! Instead of using a
variable, you’re using a string as the parameter. You’ll be making a copy
of the template shortly, so don’t worry that the actual file doesn’t exist
yet. This reflects the fact that it should merge with a copy of the runtime
template.
6. Search for the string “& MyWhere.” (Don’t forget the ampersand when
typing the search string). That line should currently start with: “mySQL
= . Change that line to the following (be careful with the white spaces):
mySQL = mySQL & “ WHERE dbo.[Order Details Extended].OrderID=” & myVar

Notes: we’ll set the myVar value to the OrderID in the steps below. The
variable will hold the OrderID, which will filter this browse.
7. Save and close the Browseview_Order_Details_ExtendedList2.asp file.
8. Open UpdateViewOrdersQueryView.asp with notepad. Search for "DIM
dbNavBarPrev, dbNavBarNext." It should be very close to the end of the
file. Add the following code on the lines before that line. Don't forget to
substitute your table/column name should you be using this as a guide
for changing an application of your own:
DIM myVar
myVar = oRSviewOrdersQuery.Fields("OrderID").Value

Notes: the code above declares a variable, and places the current order
number into it. In the next step, we’ll use the OrderID in a custom
WHERE clause for the browse we’ll append to the bottom of this form,
which we stored in the myVar variable.
9. Approximately 20 lines below the lines you just inserted, you’ll find a
that starts with “Call MergeUpdateViewOrdersQueryTemplate,” with the
HTML_Template variable as a parameter. Now you’ll set the session
variable. Insert the following lines immediately below the line with the
Call to the merge procedure. And yes, the <% and %> are reversed,
because you're splitting up an existing block and starting a new one!
You’re instructing that the HTML generation process include the
corresponding ASP page for the child browse. That must be done outside
the ASP block, hence we split that block.
%>
<!-- #include file="Browseview_Order_Details_ExtendedList2.asp" -->
<%
138 CLARION/ASP

10. Using Explorer, locate the


\C55\examples\asp\orders\asp\html\Browseview_Order_Details_ExtendedList.htm
file, and copy it to Browseview_Order_Details_ExtendedList2.htm.
11. Open html/Browseview_Order_Details_ExtendedList2.htm, preferably
in an HTML editor. Delete every line up to the line that says <table
CLASS="Data" CELLSPACING="0">. This eliminates the duplicate
“header” information which would exist when we include this file as the
“bottom” of the file of which the UpdateViewOrdersQueryView form is
the “top.”
12. Open the html/UpdateViewOrdersQueryView.htm file. Delete every line
below the </form> tag. This is the complementary action to the previous
step.
13. Back in the Clarion development environment, on the ASP extension,
override and turn off HTML generation for UpdateViewOrdersQuery
(that procedure’s Global tab, General subtab).

Final note: if editing any of the HTML files that have the closing tags
(everything below </form>) removed, and you're using an HTML editor, you
have to be careful that the editor doesn't reinsert them!

Congratulations. You can now regenerate and run an application which


demonstrates a very large amount of complicated Clarion/ASP behaviors,
and you’ve even customized generated code.

There is still one optional addendum (below), which we thought was very
specialized, hence, we’ve separated it from the exercise. Additionally, you
may refer to the chapter on embedded code in the Users’ Guide for further
customizations which show you the use of embedded code, including code
which places the most recent date of sale and historical sales total on the
customer view form, and a line item total on the order detail.

Through use of embedded code and editing generated code, Clarion/ASP is


extremely extensible. The Orders example was designed to be a showcase for
many different behaviors and a jumping off point to indicate how your
customizations may further extend the system.

Addendum: Priming a Listbox on Add


You may recall that on the Update Suppliers procedure we set field priming
for an Add New Product link. The method provided is for entry boxes only;
however, that particular control was a listbox. Here is how to customize the
generated output to make field priming work with the table loaded drop list.
Editing the generated file (for the target procedure) is required.
1. Open UpdateProductsAdd.asp in notepad.
ANNOTATED EXAMPLES 139

2. Locate a block of three lines which currently looks like:


IF (NOT ISNull(Request.QueryString("txtProductsProductID")) ) THEN
ProductsProductID = Request.QueryString("txtProductsProductID")
END IF

The last parameter (the empty double quoted string) is the value to prime.
You will create an IF/END IF structure including this line, plus a copy of the
same line substituting Request.QueryString("txtProductsSupplierID") for the
empty double quotes, and place a test (to verify that the calling procedure is
actually passing a parameter around the second line. This insures the
procedure will work whether there is a parameter supplied (as from the
Update Suppliers procedure), or if no parameter is supplied. The resulting
block should look like this (beware of word wrapping and smart quotes!):
IF (NOT IsNull(Request.QueryString("txtProductsSupplierID"))) THEN
ProductsSupplierID = getSelectOptions(strQueryProductsSupplierID,
"CompanyName", "SupplierID",
Request.QueryString("txtProductsSupplierID"))
ELSE
ProductsSupplierID = getSelectOptions(strQueryProductsSupplierID,
"CompanyName", "SupplierID", "")
END IF

When you click on the “Add a Product for this Supplier,” the add form will
now correctly show the name of the supplier in the dropdown list box.

Introductory Page
You’re now ready to run the final application. We’ve made a special
“introductory page,” called index.asp. This mimics a Microsoft Access style
“switchboard” entry to an application.

The “switchboard” contains four large buttons, each of which leads to the a
view only navigation form on the first record in the categories, suppliers,
products, and orders tables. The link each of the first records is hardcoded in
the URL, as in ?ID1=1.

To open the page, type http://localhost/orders/index.asp in your browser


address box. Test the application pages by navigating from link to link.

You may note that the illustrations in this book show extra HTML editing on
the form/browse runtime templates, such as background bitmaps. These are
probably less complex edits than a full time web designer might have done.
140 CLARION/ASP
ANNOTATED EXAMPLES 141

8. PUBS EXAMPLE
We’ve included an additional example in your C55\examples\asp\pubs
directory. This application works against the MS SQL Server pubs example
database.

The purpose of this example is to primarily to show you that you can
incorporate an attractive layout via design time template. The “look” of the
application is that of a printed page, with graphic links along the top, and
data appearing in the “body” of the page. Additionally, many of the HTML
runtime templates for this example have been modified. The “base” design
time template incorporates several link icons along the top; many of the
procedures add in additional icons, something like the effect of a toolbar
with addtional tools merged in on a procedure by procedure basis.

You’ll find those pages which were customized in a file called custom.zip in
the project\asp\html directory. Be sure to unzip this file before generation.
142 CLARION/ASP
ANNOTATED EXAMPLES 143

9. ASP CODE WALKTHROUGH


This chapter walks through the ASP code generated for the MyASP sample
application and explains what each section of it does. This is meant to
provide a greater understanding to non-ASP programmers of how the
generated application works.

Each block of ASP code is contained inside a <% %> tag.

Note that the single quote is the VBScript comment identifier (in general,
Clarion/ASP code contains two single quotes to identify begin a comment,
because the code must be contained in the Clarion template, for which the
single quote is the string identifer. Note that when using the embeditor, you
need only a single quote to start a comment for any comment lines that you
write.

Browse
This is a default browse upon the Products table of the Northwind sample
database.

Script Language and Notice


The first block declares the script language and provides instructions to web
designers who may wish to edit the code after generation, and clears the VB
error object, so that if it’s necessary to check for an error, there’s no old error
there.
<%@ Language=VBScript %>
<%
''===================================================================
''------------------ Notice to Web Page Designers! ------------------
''===================================================================
'' Data enabled web pages often require a particular sequence of
'' events to occur for successful execution. Therefore we ask
'' that you not reorder the ASP program logic. Also there should
'' be no changes in the naming of any HTML elements or ASP variables.
''
'' Every effort was made to allow "look and feel" changes to
'' occur by modifying the Cascading Style Sheets supplied with this
'' application
''===================================================================
'' Clear the error object declared in utils.asp
Err.Clear
%>
144 CLARION/ASP

Include Files
Then, the include files are processed.
• AppData contains several global declarations, such as icon sizes and
image names, debug options as set in the global template, and so on.
• ADOVBS contains declarations necessary for accessing ADO.
• Utils contains many helper functions.
<!-- #include file="AppData.asp"-->
<!-- #include file="adovbs.inc"-->
<!-- #include file="utils.asp"-->

Global Overrides
The next block allows you to remove comments and override any of the
global options by setting them to True or False.
<%
'' DebugMode is defined in AppData.asp as FALSE by default
'' debug of this page only by uncommenting the next line
'' DebugMode = [FALSE, TRUE]
''
'' ShowQuery is defined in AppData.asp from the Application level
'' query of this page can be overridden by uncommenting the next line
'' ShowQuery = [FALSE, TRUE]
''
'' ShowDBNav is defined in AppData.asp from the Application level
'' display of the nav bar can be overridden by uncommenting the next line
'' ShowDBNav = [FALSE, TRUE]
''
'' RecordsPerPage is defined in AppData.asp from the Application level
'' display of the number of records can be overridden by uncommenting the
next line
'' RecordsPerPage = ##
''
%>

Variable Declarations
The next block declares all the variables necessary for this page. Note that
many of them describe options for the data from each individual field, which
will be sent to the runtime template by the merge function.

It gathers the information necessary for the connection object from session
variables. This is the reason that Global.ASA stores the runtime user name,
password, etc.

Then, at the end of the block, the recordset is declared (oRSProducts), plus
string variables which will hold the SELECT statement, clause by clause. It
ANNOTATED EXAMPLES 145

also declares the ADO connection object (objCN), sets timeout options for
the application, and opens the application.

The final line calls the CheckError function, which will check the errors
object after each database access, and if an error is found, reports it.
<%
DIM HeaderText, TemplateText, DataRowEmptyText, DataRowFilledText,
FooterText
DIM RemainderText, BrowseProductsRowData, ndxStart, ndxEnd, strLEN
DIM Seq, MaxPages, TotalRecords, iStart, iEnd, TableFooter, ref, counter
DIM PageIndex, RecordsPageSize
DIM ProductsAutomaticDetailLink
DIM ProductsAutomaticDetailLinkSTYLE
DIM ProductsProductNameLABEL
DIM ProductsProductName
DIM ProductsProductNameSTYLE
DIM ProductsProductIDLABEL
DIM ProductsProductID
DIM ProductsProductIDSTYLE
DIM ProductsSupplierIDLABEL
DIM ProductsSupplierID
DIM ProductsSupplierIDSTYLE
DIM ProductsCategoryIDLABEL
DIM ProductsCategoryID
DIM ProductsCategoryIDSTYLE
DIM ProductsQuantityPerUnitLABEL
DIM ProductsQuantityPerUnit
DIM ProductsQuantityPerUnitSTYLE
DIM ProductsUnitPriceLABEL
DIM ProductsUnitPrice
DIM ProductsUnitPriceSTYLE
DIM ProductsUnitsInStockLABEL
DIM ProductsUnitsInStock
DIM ProductsUnitsInStockSTYLE
DIM ProductsUnitsOnOrderLABEL
DIM ProductsUnitsOnOrder
DIM ProductsUnitsOnOrderSTYLE
DIM ProductsReorderLevelLABEL
DIM ProductsReorderLevel
DIM ProductsReorderLevelSTYLE

DIM oRSProducts, mySQL, myWhere, myQuery, myPage, valSQL


'' create the connection object
Dim objCN
Set objCN = Server.CreateObject("ADODB.Connection")
objCN.ConnectionTimeout = Application("MyASP_ConnectionTimeOut")
objCN.CommandTimeout = Application("MyASP_CommandTimeOut")
objCN.CursorLocation = Application("MyASP_CursorLocation")
objCN.Open Application("MyASP_ConnectionString"),
Application("MyASP_RuntimeUserName"),
Application("MyASP_RuntimePassword")
CheckError
%>
146 CLARION/ASP

Debug Information
The next block outputs as much information about the page as possible if the
application is in debug mode. The Response.Write function outputs a string
or variable to the page to be displayed in the browser. The session variables
will have been loaded with options from any previous page, such as column
sorts and where parameters supplied in a URL.
<% IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
beginning of the page
Object: objCN
SESSION("BrowseProducts#BrowseProducts#COL")
ConnectionString: = "<%Response.Write(objCN.ConnectionString)%>"
SESSION("BrowseProducts#COL") =
"<%Response.Write(SESSION("BrowseProducts#COL"))%>"
SESSION("BrowseProducts#SRT") =
"<%Response.Write(SESSION("BrowseProducts#SRT"))%>"
SESSION("BrowseProducts#PreviousColumn") =
"<%Response.Write(SESSION("BrowseProducts#PreviousColumn"))%>"
SESSION("BrowseProducts#PreviousSort") =
"<%Response.Write(SESSION("BrowseProducts#PreviousSort"))%>"
SESSION("BrowseProducts#mySort") =
"<%Response.Write(SESSION("BrowseProducts#mySort"))%>"
SESSION("BrowseProducts#myOrder") =
"<%Response.Write(SESSION("BrowseProducts#myOrder"))%>"
SESSION("BrowseProducts#WHR") =
"<%Response.Write(SESSION("BrowseProducts#WHR"))%>"
END DEBUG INFORMATION -->
<% END IF ' of DebugMode block %>

Prepare RecordSet and Session Variables


The next block is a long one and will be described in smaller sections. The
first section initializes the record set. It then clears the session variables if it
finds that the page was called without parameters, either from a URL
parameter, or from a previous page, including any column sorts (in which
case the previous page was itself).
<%
SET oRSProducts = Server.CreateObject("ADODB.Recordset")
'' reset the where session variables if we find a reset string
IF Request.QueryString("RESETLIST") = "TRUE" THEN
myWhere = ""
SESSION("BrowseProducts#WHR") = ""
SESSION("BrowseProducts#COL") = ""
SESSION("BrowseProducts#SRT") = ""
SESSION("BrowseProducts#PreviousColumn") = ""
SESSION("BrowseProducts#PreviousSort") = ""
SESSION("BrowseProducts#mySort") = ""
SESSION("BrowseProducts#myOrder") = ""
END IF
'' reset the where session variables if we find no querystring AND did NOT
come from a search

IF Request.QueryString = "" THEN


ANNOTATED EXAMPLES 147

IF (Instr(1,LCase(REQUEST.ServerVariables("HTTP_REFERER")),"search.asp")
= 0 ) THEN
myWhere = ""
SESSION("BrowseProducts#WHR") = ""
SESSION("BrowseProducts#COL") = ""
SESSION("BrowseProducts#SRT") = ""
SESSION("BrowseProducts#PreviousColumn") = ""
SESSION("BrowseProducts#PreviousSort") = ""
SESSION("BrowseProducts#mySort") = ""
SESSION("BrowseProducts#myOrder") = ""
END IF
END IF

'' reset the col and srt session variables


IF (REQUEST.QueryString("PageIndex") <> "") THEN
IF ( REQUEST.QueryString("COL") = "" AND REQUEST.QueryString("SRT") = "" AND
REQUEST.Form("SEARCH") = "") THEN
IF (Instr(1,LCase(REQUEST.ServerVariables("HTTP_REFERER")),
REQUEST.ServerVariables("URL")) > 0 ) THEN
SESSION("BrowseProducts#COL") = ""
SESSION("BrowseProducts#SRT") = ""
SESSION("BrowseProducts#PreviousColumn") = ""
SESSION("BrowseProducts#PreviousSort") = ""
SESSION("BrowseProducts#mySort") = ""
SESSION("BrowseProducts#myOrder") = ""
END IF
END IF
END IF

Column Sorts
If the page has been given a column to sort on as a parameter, then it
prepares the session variable which signal what the sort should be, including
placing the Order By clause in a session variable. Remember that in this
example, we did not disable the sorting option for any columns, so there’s
quite a bit of code here for enabling sorting on fields that probably wouldn’t
be sorted on in a real world application.
'' set the url for the column links
myPage = Request.ServerVariables("URL")

IF(REQUEST("COL") <> "") THEN


SESSION("BrowseProducts#PreviousColumn") = REQUEST("COL")
ELSE
SESSION("BrowseProducts#PreviousColumn") = ""
END IF

IF(REQUEST("SRT") <> "") THEN


SESSION("BrowseProducts#PreviousSort") = REQUEST("SRT")
ELSE
SESSION("BrowseProducts#PreviousSort") = ""
END IF

IF ( IsEmpty(SESSION("BrowseProducts#COL")) OR
IsNull(SESSION("BrowseProducts#COL")) ) THEN
148 CLARION/ASP

IF (Request.QueryString("COL") = "" AND SESSION("BrowseProducts#COL") =


"") THEN
SESSION("BrowseProducts#COL") = "ProductName"
END IF
END IF
IF Request("COL") = "ProductName" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.ProductName DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.ProductName ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.ProductName
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "ProductName"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "ProductID" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.ProductID
DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.ProductID
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.ProductID
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "ProductID"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "SupplierID" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.SupplierID DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.SupplierID ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.SupplierID
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "SupplierID"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
ANNOTATED EXAMPLES 149

IF Request("COL") = "CategoryID" THEN


IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.CategoryID DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.CategoryID ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.CategoryID
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "CategoryID"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "QuantityPerUnit" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.QuantityPerUnit DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.QuantityPerUnit ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.QuantityPerUnit ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "QuantityPerUnit"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "UnitPrice" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.UnitPrice
DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.UnitPrice
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.UnitPrice
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "UnitPrice"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "UnitsInStock" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.UnitsInStock DESC"
SESSION("BrowseProducts#mySort") = "DESC"
150 CLARION/ASP

ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.UnitsInStock ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.UnitsInStock ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "UnitsInStock"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "UnitsOnOrder" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.UnitsOnOrder DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.UnitsOnOrder ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.UnitsOnOrder ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "UnitsOnOrder"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF
IF Request("COL") = "ReorderLevel" THEN
IF Request("SRT") = "DESC" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.ReorderLevel DESC"
SESSION("BrowseProducts#mySort") = "DESC"
ELSE
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.ReorderLevel ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
IF ( Request("COL") <> SESSION("BrowseProducts#PreviousColumn") ) THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY
dbo.Products.ReorderLevel ASC"
SESSION("BrowseProducts#mySort") = "ASC"
END IF
SESSION("BrowseProducts#COL") = "ReorderLevel"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF

The Base SELECT Statement


This next section sets the base (i.e., without any WHERE or ORDER by
clauses) for the SQL SELECT statement. Afterwards, the code will test for
those clauses, and append anything applicable to the myQuery variable:
'' Set The SQL Statement From The Browse Template
ANNOTATED EXAMPLES 151

myQuery = "SELECT dbo.Products.ProductID, dbo.Products.ProductName,


dbo.Products.SupplierID, dbo.Products.CategoryID,
dbo.Products.QuantityPerUnit, dbo.Products.UnitPrice,
dbo.Products.UnitsInStock, dbo.Products.UnitsOnOrder,
dbo.Products.ReorderLevel FROM dbo.Products"

Appending WHERE and ORDER BY Clauses


The next section begins by testing for a WHERE clause. This may come
from a URL (as a ?WHR parameter), or from a session variable (as stored by
a locator or from if there had been a range select option on the browse).
'' test for a WHR parameter, URL or SESSION
IF LEN(Request.QueryString("WHR")) THEN
myWhere = Request("WHR")
SESSION("BrowseProducts#WHR") = Request("WHR")
ELSEIF LEN(SESSION("BrowseProducts#WHR")) THEN
myWhere = SESSION("BrowseProducts#WHR")
END IF

Checking for Reset or Locate Flags


Next, the code checks for a ?RESETLIST parameter. This flag is true if an
end user had clicked on an “All Data” link to clear a filter after
implementing a locator. If it finds it, it clears any WHERE clause (which
would have been stored in the myWhere variable. Then it checks for a
?LOCATE parameter, which indicates that a locator control was activated,
and therefore a LIKE % must be added to the WHERE clause.

IF Request.QueryString("RESETLIST") = "TRUE" THEN


myWhere = ""
SESSION("BrowseProducts#WHR") = ""
END IF
IF myWhere = "" THEN
IF Request("LOCATE") = "TRUE" THEN
myWhere = Request("FIELD") & " LIKE " & CHR(39) &
Request("SearchValue") & "%" & CHR(39)
SESSION("BrowseProducts#WHR") = myWhere
END IF
ELSE
IF Request("LOCATE") = "TRUE" THEN
myWhere = myWhere & " AND "
myWhere = myWhere & Request("FIELD") & " LIKE " & CHR(39) &
Request("SearchValue") & "%" & CHR(39)
SESSION("BrowseProducts#WHR") = myWhere
END IF
END IF
152 CLARION/ASP

Building the WHERE Clause


The code then gathers the next items necessary for the WHERE clause,
concatenates it and continues building the SQL SELECT statement (fieldlist,
FROM clause and WHERE clause) using the mySQL variable which it had
filled before.

mySQL = myQuery
'' test for any value in the myWhere, if valid concatenate the clause
IF myWHERE <> "" THEN
mySQL = mySQL & " WHERE " & myWhere
END IF

Finishing the WHERE Clause


The following section checks the session variables for any ORDER BY
clause and appends it to the SELECT statement:

'' test for any value in myOrder, if empty set default


IF SESSION("BrowseProducts#myOrder") = "" THEN
SESSION("BrowseProducts#myOrder") = "ORDER BY dbo.Products.ProductName
ASC"
SESSION("BrowseProducts#mySort") = "ASC"
SESSION("BrowseProducts#COL") = "ProductName"
SESSION("BrowseProducts#SRT") = SESSION("BrowseProducts#mySort")
END IF

'' test for any value in myOrder, if valid concenate into the SQL statement
IF SESSION("BrowseProducts#myOrder") <> "" THEN
mySQL = mySQL & " " & SESSION("BrowseProducts#myOrder")
END IF

Open the RecordSet


The code then opens up the record set, which is called oRSProducts, using
the Open method, specifying the cursor and isolation types, and then calls the
check error routine.

oRSProducts.Open mySQL , objCN, adOpenStatic, adLockReadOnly


CheckError

If the ?RESETLIST parameter is true, it “cleans out” the WHERE clause:

IF Request.QueryString("RESETLIST") = "TRUE" THEN


myWhere = ""
SESSION("BrowseCustomers#WHR") = ""
END IF
ANNOTATED EXAMPLES 153

%>

More Debug Information


The next block provides additional debug information, now that the record
set is open:

<% IF DebugMode THEN %>


<!-- BEGIN DEBUG INFORMATION
After opening the RS
Object: objCN
ConnectionString: = "<%Response.Write(objCN.ConnectionString)%>"
SESSION("BrowseProducts#COL") =
"<%Response.Write(SESSION("BrowseProducts#COL"))%>"
SESSION("BrowseProducts#SRT") =
"<%Response.Write(SESSION("BrowseProducts#SRT"))%>"
SESSION("BrowseProducts#PreviousColumn") =
"<%Response.Write(SESSION("BrowseProducts#PreviousColumn"))%>"
SESSION("BrowseProducts#PreviousSort") =
"<%Response.Write(SESSION("BrowseProducts#PreviousSort"))%>"
SESSION("BrowseProducts#mySort") =
"<%Response.Write(SESSION("BrowseProducts#mySort"))%>"
SESSION("BrowseProducts#myOrder") =
"<%Response.Write(SESSION("BrowseProducts#myOrder"))%>"
SESSION("BrowseProducts#WHR") =
"<%Response.Write(SESSION("BrowseProducts#WHR"))%>"
END DEBUG INFORMATION -->
<% END IF ' of DebugMode block %>

Finish Up and Output


The next block is the “remainder” of the ASP code for the page (the
functions, similar to ROUTINEs follow, and are commented below). First,
the code calculates the how many pages there will be, so that it can provide a
“page # of #” label for the navigation bar. it then calls the Merge routine
(Call MergeBrowseProductsListTemplate), explained further down, which is
something like a mail merge: all the data meant to display on the page is
output in its proper place, according to where its symbol resides in the
HTML runtime template. If there are no records, then a “no records”
message is output. If in debug mode, further debug information is output. It
then closes the connection object, since it has all the data.

<%
RecordsPageSize = RecordsPerPage

PageIndex = Request("PageIndex")
IF PageIndex = "" THEN
PageIndex = 1
END IF
IF (oRSProducts.State = 1) THEN
IF( (NOT oRSProducts.BOF = TRUE) AND (NOT oRSProducts.EOF = TRUE) ) THEN
154 CLARION/ASP

IF oRSProducts.RecordCount > 0 THEN


oRSProducts.PageSize = RecordsPageSize 'Total Number of
records to show
oRSProducts.AbsolutePosition = 1 'To stat showing record
in page size
oRSProducts.AbsolutePage = PageIndex 'To go on group number
made by page size
MaxPages = oRSProducts.PageCount
TotalRecords = oRSProducts.RecordCount
Call MergeBrowseProductsListTemplate("HTML/
BrowseProductsList.htm")
ELSE
Call NoRecordsFound()
END IF
ELSE
Call NoRecordsFound()
END IF
ELSE
Call NoRecordsFound()
END IF

IF DebugMode THEN
Response.Write("QueryString: " & Request.QueryString)
END IF

set oRSProducts = Nothing


'' close and destroy the connection object
objCN.Close
SET objCN = NOTHING

Function: NoRecordsFound
The functions now follow. The first, “NoRecordsFound” simply outputs a
message saying that the SELECT statement didn’t return any rows of data:
'============================================================================='
FUNCTION NoRecordsFound
'============================================================================='
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")
TemplateText = Server.MapPath("HTML/blank.htm")
Set InStream = FileObject.OpenTextFile (TemplateText, 1, False, False)
TemplateText = Empty
While not InStream.AtEndOfStream
TemplateText = TemplateText & InStream.ReadLine & vbcrlf
Wend
Set Instream = Nothing
TemplateText = Replace(TemplateText,"@ClarionData@","<A
HREF='JAVASCRIPT:history.back();'>No records were found</A>")
Response.Write(TemplateText)
Set FileObject = Nothing

END FUNCTION
'---------------------------------------------------------------------------
--'
ANNOTATED EXAMPLES 155

Function:MergeBrowseProductsListTemplate
The next function, MergeBrowseProductsListTemplate, is the heart of the
“display” process. It creates a file system object in order to open the runtime
HTML template. It reads it, and calls additional functions as necessary in
order to output the HTML it finds in the template, subsituting column names,
data, and footer from the variables it’s assembled previously:
'============================================================================='
Function MergeBrowseProductsListTemplate(templatepath)
' Merge Runtime HTML Template Function '
'============================================================================='
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")
TemplateText = Server.MapPath(templatepath)
Set InStream = FileObject.OpenTextFile (TemplateText, 1, False, False)
TemplateText = Empty
While not InStream.AtEndOfStream
TemplateText = TemplateText & InStream.ReadLine & vbcrlf
Wend
Set Instream = Nothing
TemplateText =
Replace(TemplateText,"@TableRowData@",BrowseProductsRowData)

'' start iterating the symbols and assigning the values


HeaderText = Empty
HeaderText = Mid(TemplateText,1, (Instr(1,UCASE(TemplateText),"<!--BEGIN
ROWDATA-->",1) -1))
Call buildColumnLabels

'' get the default data row text


ndxStart = (Instr(1,UCASE(TemplateText),"<!--BEGIN ROWDATA-->",1) +20)
ndxEnd = (Instr(1,UCASE(TemplateText),"<!--END ROWDATA-->",1) -1)
strLEN = (ndxEnd - ndxStart)
DataRowFilledText = Empty
DataRowEmptyText = Empty
DataRowEmptyText = Mid(TemplateText, ndxStart, strLen )
Call buildDataRows

'' get the footer text


ndxStart = (Instr(1,UCASE(TemplateText),"<!--BEGIN FOOTER-->",1) +19)
ndxEnd = (Instr(1,UCASE(TemplateText),"<!--END FOOTER-->",1) -1)
strLEN = (ndxEnd - ndxStart)
FooterText = Empty
FooterText = Mid(TemplateText, ndxStart, strLen )
call buildFooter

'' remainder of page


ndxStart = (Instr(1,UCASE(TemplateText),"<!--END FOOTER-->",1) +17)
ndxEnd = (Instr(1,UCASE(TemplateText),"</HTML>",1) +7)
strLEN = (ndxEnd - ndxStart)

RemainderText = Empty
RemainderText = Mid(TemplateText, ndxStart, strLen)

TemplateText = Empty

IF varType(HeaderText) > 1 THEN


156 CLARION/ASP

TemplateText = HeaderText
END IF
IF varType(DataRowFilledText) > 1 THEN
TemplateText = TemplateText & DataRowFilledText
END IF
IF varType(FooterText) > 1 THEN
TemplateText = TemplateText & FooterText
END IF
IF varType(RemainderText) > 1 THEN
TemplateText = TemplateText & RemainderText
END IF

TemplateText = Replace(TemplateText,"@TableFooter@", FooterText)

Response.Write(TemplateText)
END Function
'---------------------------------------------------------------------------
--'

Function: buildColumnLabels
The next function is long, but does only one thing: build the column labels.
The column labels have to be links, so that the end user can click on them to
do the sorting. Additionally, if the column is the current sort, it has to display
the proper icon to indicate it’s the sorted column, and the direction of the
sort. Note that it determines if it’s the sorted column by checking the session
variable. It also places a Class tag to indicate the Cascading Style Sheet style
for each “cell.”

'============================================================================='
FUNCTION buildColumnLabels
' buildColumnLabels Function '
'============================================================================='
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=ProductName"
IF ( SESSION("BrowseProducts#PreviousColumn") = "ProductName")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "ProductName") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Product Name</A>"
ANNOTATED EXAMPLES 157

ProductNameLABEL = myLink
IF (Request("COL") = "ProductName") OR
(SESSION("BrowseProducts#COL") = "ProductName") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
ProductNameLABEL = ProductNameLABEL & "<IMG ALT='ASC' SRC="
& IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
ProductNameLABEL = ProductNameLABEL & "<IMG ALT='DESC' SRC="
& IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=ProductID"
IF ( SESSION("BrowseProducts#PreviousColumn") = "ProductID")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "ProductID") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Product ID</A>"
ProductIDLABEL = myLink
IF (Request("COL") = "ProductID") OR (SESSION("BrowseProducts#COL")
= "ProductID") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
ProductIDLABEL = ProductIDLABEL & "<IMG ALT='ASC' SRC=" &
IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
ProductIDLABEL = ProductIDLABEL & "<IMG ALT='DESC' SRC=" &
IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
158 CLARION/ASP

<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=SupplierID"
IF ( SESSION("BrowseProducts#PreviousColumn") = "SupplierID")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "SupplierID") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Supplier ID</A>"
SupplierIDLABEL = myLink
IF (Request("COL") = "SupplierID") OR (SESSION("BrowseProducts#COL")
= "SupplierID") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
SupplierIDLABEL = SupplierIDLABEL & "<IMG ALT='ASC' SRC=" &
IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
SupplierIDLABEL = SupplierIDLABEL & "<IMG ALT='DESC' SRC=" &
IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=CategoryID"
IF ( SESSION("BrowseProducts#PreviousColumn") = "CategoryID")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "CategoryID") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
ANNOTATED EXAMPLES 159

END IF
myLink = myLink & "'>Category ID</A>"
CategoryIDLABEL = myLink
IF (Request("COL") = "CategoryID") OR (SESSION("BrowseProducts#COL")
= "CategoryID") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
CategoryIDLABEL = CategoryIDLABEL & "<IMG ALT='ASC' SRC=" &
IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
CategoryIDLABEL = CategoryIDLABEL & "<IMG ALT='DESC' SRC=" &
IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=QuantityPerUnit"
IF ( SESSION("BrowseProducts#PreviousColumn") =
"QuantityPerUnit") THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "QuantityPerUnit") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Quantity Per Unit</A>"
QuantityPerUnitLABEL = myLink
IF (Request("COL") = "QuantityPerUnit") OR
(SESSION("BrowseProducts#COL") = "QuantityPerUnit") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
QuantityPerUnitLABEL = QuantityPerUnitLABEL & "<IMG
ALT='ASC' SRC=" & IconAsc & " BORDER=" & IconBorder & " height=14
width=16>"
ELSE
QuantityPerUnitLABEL = QuantityPerUnitLABEL & "<IMG
ALT='DESC' SRC=" & IconDesc & " BORDER=" & IconBorder & " height=14
width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
160 CLARION/ASP

Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=UnitPrice"
IF ( SESSION("BrowseProducts#PreviousColumn") = "UnitPrice")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "UnitPrice") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Unit Price</A>"
UnitPriceLABEL = myLink
IF (Request("COL") = "UnitPrice") OR (SESSION("BrowseProducts#COL")
= "UnitPrice") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
UnitPriceLABEL = UnitPriceLABEL & "<IMG ALT='ASC' SRC=" &
IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
UnitPriceLABEL = UnitPriceLABEL & "<IMG ALT='DESC' SRC=" &
IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=UnitsInStock"
IF ( SESSION("BrowseProducts#PreviousColumn") = "UnitsInStock")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "UnitsInStock") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ANNOTATED EXAMPLES 161

END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Units In Stock</A>"
UnitsInStockLABEL = myLink
IF (Request("COL") = "UnitsInStock") OR
(SESSION("BrowseProducts#COL") = "UnitsInStock") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
UnitsInStockLABEL = UnitsInStockLABEL & "<IMG ALT='ASC'
SRC=" & IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
UnitsInStockLABEL = UnitsInStockLABEL & "<IMG ALT='DESC'
SRC=" & IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=UnitsOnOrder"
IF ( SESSION("BrowseProducts#PreviousColumn") = "UnitsOnOrder")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "UnitsOnOrder") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Units On Order</A>"
UnitsOnOrderLABEL = myLink
IF (Request("COL") = "UnitsOnOrder") OR
(SESSION("BrowseProducts#COL") = "UnitsOnOrder") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
UnitsOnOrderLABEL = UnitsOnOrderLABEL & "<IMG ALT='ASC'
SRC=" & IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
UnitsOnOrderLABEL = UnitsOnOrderLABEL & "<IMG ALT='DESC'
SRC=" & IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
162 CLARION/ASP

<!-- BEGIN DEBUG INFORMATION


Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
myLink = "<A HREF='" & myPage & "?"
myLink = myLink & "COL=ReorderLevel"
IF ( SESSION("BrowseProducts#PreviousColumn") = "ReorderLevel")
THEN
IF Request("SRT") = "ASC" THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
ELSE
IF( SESSION("BrowseProducts#COL") = "ReorderLevel") THEN
myLink = myLink & "&SRT=DESC"
ELSE
myLink = myLink & "&SRT=ASC"
END IF
END IF
IF Request.QueryString("ID1") <> "" THEN
myLink = myLink & "&ID1=" & Request.QueryString("ID1")
END IF
myLink = myLink & "'>Reorder Level</A>"
ReorderLevelLABEL = myLink
IF (Request("COL") = "ReorderLevel") OR
(SESSION("BrowseProducts#COL") = "ReorderLevel") THEN
IF (Request("SRT") = "ASC") OR (SESSION("BrowseProducts#SRT") =
"ASC") THEN
ReorderLevelLABEL = ReorderLevelLABEL & "<IMG ALT='ASC'
SRC=" & IconAsc & " BORDER=" & IconBorder & " height=14 width=16>"
ELSE
ReorderLevelLABEL = ReorderLevelLABEL & "<IMG ALT='DESC'
SRC=" & IconDesc & " BORDER=" & IconBorder & " height=14 width=16>"
END IF
END IF
%>
<%IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: myLink - submitted column sort link
Value: "<%Response.Write(myLink)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%
HeaderText = Replace(HeaderText,"@ProductNameLABEL@", ProductNameLABEL)
HeaderText = Replace(HeaderText,"@ProductIDLABEL@", ProductIDLABEL)
HeaderText = Replace(HeaderText,"@SupplierIDLABEL@", SupplierIDLABEL)
HeaderText = Replace(HeaderText,"@CategoryIDLABEL@", CategoryIDLABEL)
HeaderText = Replace(HeaderText,"@QuantityPerUnitLABEL@",
QuantityPerUnitLABEL)
HeaderText = Replace(HeaderText,"@UnitPriceLABEL@", UnitPriceLABEL)
HeaderText = Replace(HeaderText,"@UnitsInStockLABEL@", UnitsInStockLABEL)
HeaderText = Replace(HeaderText,"@UnitsOnOrderLABEL@", UnitsOnOrderLABEL)
HeaderText = Replace(HeaderText,"@ReorderLevelLABEL@", ReorderLevelLABEL)
END FUNCTION
'
ANNOTATED EXAMPLES 163

Function: buildDataRows
The next function takes the data from the data set, places it in the proper
variables, and loops through however many rows it takes to assemble the
HTML table with data. If any of the “cells” contain links, whether an
automatic link to an edit form, or a link to a separate procedure, it has to
include the link tag.

'============================================================================='
FUNCTION buildDataRows
' buildDataRows Function '
'============================================================================='
Seq = 1
DO WHILE NOT oRSProducts.eof AND Seq <= RecordsPageSize
DataRowFilledText = DataRowFilledtext & DataRowEmptyText

Style = "One"
ProductsAutomaticDetailLinkSTYLE = "TableRow" & style
myLink = ""
myLink = "<A HREF=UpdateProductsView.asp?ID1="
ProductsAutomaticDetailLink = myLink
ProductsAutomaticDetailLink = ProductsAutomaticDetailLink &
Server.URLEncode(TRIM(Cstr(oRSProducts.Fields("ProductID").Value)))
DIM tmpIMG
tmpIMG = "<IMG SRC=images/Editpencil.Gif Border=0 ALT=>"
ProductsAutomaticDetailLink = ProductsAutomaticDetailLink &
">" & tmpIMG & "</A>"
Style = "One"
ProductsProductNameSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("ProductName").Value) THEN
ProductsProductName = ""
ELSE

ProductsProductName = oRSProducts.Fields("ProductName").Value
END IF
Style = "One"
ProductsProductIDSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("ProductID").Value) THEN
ProductsProductID = ""
ELSE

ProductsProductID = oRSProducts.Fields("ProductID").Value
END IF
Style = "One"
ProductsSupplierIDSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("SupplierID").Value) THEN
ProductsSupplierID = ""
ELSE

ProductsSupplierID = oRSProducts.Fields("SupplierID").Value
END IF
Style = "One"
164 CLARION/ASP

ProductsCategoryIDSTYLE = "TableRow" & Style


IF ISNULL(oRSProducts.Fields("CategoryID").Value) THEN
ProductsCategoryID = ""
ELSE

ProductsCategoryID = oRSProducts.Fields("CategoryID").Value
END IF
Style = "One"
ProductsQuantityPerUnitSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("QuantityPerUnit").Value) THEN
ProductsQuantityPerUnit = ""
ELSE

ProductsQuantityPerUnit = oRSProducts.Fields("QuantityPerUnit").Value
END IF
Style = "One"
ProductsUnitPriceSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("UnitPrice").Value) THEN
ProductsUnitPrice = ""
ELSE

ProductsUnitPrice = oRSProducts.Fields("UnitPrice").Value
END IF
Style = "One"
ProductsUnitsInStockSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("UnitsInStock").Value) THEN
ProductsUnitsInStock = ""
ELSE

ProductsUnitsInStock = oRSProducts.Fields("UnitsInStock").Value
END IF
Style = "One"
ProductsUnitsOnOrderSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("UnitsOnOrder").Value) THEN
ProductsUnitsOnOrder = ""
ELSE

ProductsUnitsOnOrder = oRSProducts.Fields("UnitsOnOrder").Value
END IF
Style = "One"
ProductsReorderLevelSTYLE = "TableRow" & Style
IF ISNULL(oRSProducts.Fields("ReorderLevel").Value) THEN
ProductsReorderLevel = ""
ELSE

ProductsReorderLevel = oRSProducts.Fields("ReorderLevel").Value
END IF
Seq = Seq + 1
oRSProducts.MoveNext
CheckError
DataRowFilledtext =
Replace(DataRowFilledtext,"@ProductsAutomaticDetailLink@",
ProductsAutomaticDetailLink)
ANNOTATED EXAMPLES 165

DataRowFilledtext =
Replace(DataRowFilledtext,"@ProductsAutomaticDetailLinkSTYLE@",
ProductsAutomaticDetailLinkSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductName@",
ProductsProductName)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductNameSTYLE@",
ProductsProductNameSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductID@",
ProductsProductID)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductIDSTYLE@",
ProductsProductIDSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsSupplierID@",
ProductsSupplierID)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsSupplierIDSTYLE@",
ProductsSupplierIDSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsCategoryID@",
ProductsCategoryID)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsCategoryIDSTYLE@",
ProductsCategoryIDSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsQuantityPerUnit@",
ProductsQuantityPerUnit)
DataRowFilledtext =
Replace(DataRowFilledtext,"@ProductsQuantityPerUnitSTYLE@",
ProductsQuantityPerUnitSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitPrice@",
ProductsUnitPrice)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitPriceSTYLE@",
ProductsUnitPriceSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsInStock@",
ProductsUnitsInStock)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsInStockSTYLE@",
ProductsUnitsInStockSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsOnOrder@",
ProductsUnitsOnOrder)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsOnOrderSTYLE@",
ProductsUnitsOnOrderSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsReorderLevel@",
ProductsReorderLevel)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsReorderLevelSTYLE@",
ProductsReorderLevelSTYLE)

LOOP ' of oRSProducts DO WHILE


IF Seq < RecordsPageSize THEN
Seq = (RecordsPageSize - Seq)
DO UNTIL Seq < 0
DataRowFilledText = DataRowFilledtext & DataRowEmptyText
Style = "One"
ProductsAutomaticDetailLinkSTYLE = "TableRow" & style
DataRowFilledtext =
Replace(DataRowFilledtext,"@ProductsAutomaticDetailLink@", "&nbsp;")
DataRowFilledtext =
Replace(DataRowFilledtext,"@ProductsAutomaticDetailLinkSTYLE@",
ProductsAutomaticDetailLinkSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductName@",
"&nbsp;")
ProductsProductNameSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductNameSTYLE@",
ProductsProductNameSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductID@",
"&nbsp;")
166 CLARION/ASP

ProductsProductIDSTYLE = "TableRow" & style


DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsProductIDSTYLE@",
ProductsProductIDSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsSupplierID@",
"&nbsp;")
ProductsSupplierIDSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsSupplierIDSTYLE@",
ProductsSupplierIDSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsCategoryID@",
"&nbsp;")
ProductsCategoryIDSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsCategoryIDSTYLE@",
ProductsCategoryIDSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsQuantityPerUnit@",
"&nbsp;")
ProductsQuantityPerUnitSTYLE = "TableRow" & style
DataRowFilledtext =
Replace(DataRowFilledtext,"@ProductsQuantityPerUnitSTYLE@",
ProductsQuantityPerUnitSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitPrice@",
"&nbsp;")
ProductsUnitPriceSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitPriceSTYLE@",
ProductsUnitPriceSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsInStock@",
"&nbsp;")
ProductsUnitsInStockSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsInStockSTYLE@",
ProductsUnitsInStockSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsOnOrder@",
"&nbsp;")
ProductsUnitsOnOrderSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsUnitsOnOrderSTYLE@",
ProductsUnitsOnOrderSTYLE)
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsReorderLevel@",
"&nbsp;")
ProductsReorderLevelSTYLE = "TableRow" & style
DataRowFilledtext = Replace(DataRowFilledtext,"@ProductsReorderLevelSTYLE@",
ProductsReorderLevelSTYLE)
Seq = (Seq - 1)
LOOP
END IF
END FUNCTION
'---------------------------------------------------------------------------
--'

Function: BuildFooter
This function contains the navigation bar (hence the link tags) and the label
indicating page # of #, and is the last function in the browse ASP file:

'============================================================================='
FUNCTION buildFooter
' buildFooter Function '
'============================================================================='
iStart = (((PageIndex - 1 ) * RecordsPageSize ) + 1)
iEnd = (PageIndex) *(RecordsPageSize)
ANNOTATED EXAMPLES 167

IF iEnd < oRSProducts.RecordCount THEN


iEnd = iEnd
ELSE
iEnd = oRSProducts.RecordCount
END IF
'' okay this bit is for the db Navigation bar
ref = ""
IF ShowDBNav THEN
SearchPage = "UpdateProductsSearch.asp"

TableFooter = TableFooter & CSTR(iStart) & " - " & CSTR(iEnd)& " of " &
TotalRecords &"<BR>"
'' okay this is the First Page
ref = ""
counter = PageIndex
IF CINT(counter) > 1 THEN
IF Request.QueryString("ID1") <> "" THEN
ref= ref & "<A HREF=" & myPage & "?PageIndex=1&ID1=" &
Request.QueryString("ID1") &"><IMG SRC='" & IconFirst & "' BORDER='"
& IconBorder &"' HEIGHT='" & IconHeight & "' WIDTH='" & IconWidth &
"' ALT='First page'></A>"
ELSE
ref= ref & "<A HREF=" & myPage & "?PageIndex=1><IMG SRC='" &
IconFirst & "' BORDER='" & IconBorder &"' HEIGHT='" & IconHeight &
"' WIDTH='" & IconWidth & "' ALT='First page'></A>"
END IF
ELSE
ref = "<IMG SRC='" & IconFirstDisabled & "' ALT='First page'
BORDER='" & IconBorder & "' HEIGHT='" & IconHeight & "' WIDTH='" &
IconWidth & "' >"
END IF
TableFooter = TableFooter & ref
'' okay this is the Prior Page
ref = ""
counter = PageIndex
IF CINT(counter) > 1 THEN
IF Request.QueryString("ID1") <> "" THEN
ref= ref & "<A HREF='" & myPage & "?PageIndex=" & (counter - 1) &
"&ID1=" & Request.QueryString("ID1") &"'><IMG SRC='" & IconPrior &
"' BORDER='" & IconBorder &"' HEIGHT='" & IconHeight & "' WIDTH='" &
IconWidth & "' ALT='Prior page'></A>"
ELSE
ref= ref & "<A HREF='" & myPage & "?PageIndex=" & (counter - 1)
&"'><IMG SRC='" & IconPrior & "' BORDER='" & IconBorder &"'
HEIGHT='" & IconHeight & "' WIDTH='" & IconWidth & "' ALT='Prior
page'></A>"
END IF
ELSE
ref = "<IMG SRC='" & IconPriorDisabled & "' ALT='Prior page'
BORDER='" & IconBorder &"' HEIGHT='" & IconHeight & "' WIDTH='" &
IconWidth & "'>"
END IF
TableFooter = TableFooter & ref
'' test to see if query is enabled
IF ShowQuery THEN
'' okay now the Query button
ref = ""
ref = ref & "<A HREF=UpdateProducts" & "Search.asp><IMG SRC='" &
IconQuery & "' BORDER='" & IconBorder & "' HEIGHT='" & IconHeight &
"' WIDTH='" & IconWidth & "' ALT='Search'></A>"
168 CLARION/ASP

TableFooter = TableFooter & ref


END IF
IF ShowAdd THEN
'' okay now the Add button
ref = ""
ref = ref & "<A HREF=UpdateProducts" & "Add.asp><IMG SRC='" &
IconAdd & "' BORDER='" & IconBorder & "' HEIGHT='" & IconHeight & "'
WIDTH='" & IconWidth & "' ALT='Insert record'></A>"
TableFooter = TableFooter & ref
END IF
'' okay now the Next Page
ref = ""
counter = PageIndex
IF CINT(counter) < CINT(MaxPages) THEN
IF Request.QueryString("ID1") <> "" THEN
ref= ref & "<A HREF=" & myPage & "?PageIndex=" & (counter + 1) &
"&ID1=" & Request.QueryString("ID1") &"><IMG SRC='" & IconNext & "'
BORDER='" & IconBorder & "' HEIGHT='" & IconHeight & "' WIDTH='" &
IconWidth & "' ALT='Next page'></A>"
ELSE
ref= ref & "<A HREF=" & myPage & "?PageIndex=" & (counter + 1) &
"><IMG SRC='" & IconNext & "' BORDER='" & IconBorder & "' HEIGHT='"
& IconHeight & "' WIDTH='" & IconWidth & "' ALT='Next page'></A>"
END IF
ELSE
ref = "<IMG SRC='" & IconNextDisabled & "' ALT='Next page'
BORDER='" & IconBorder & "' HEIGHT='" & IconHeight & "' WIDTH='" &
IconWidth & "'>"
END IF
TableFooter = TableFooter & ref
'' okay now the Last Page
ref = ""
counter = PageIndex
IF CINT(counter) < CINT(MaxPages) THEN
IF Request.QueryString("ID1") <> "" THEN
ref= ref & "<A HREF=" & myPage & "?PageIndex=" & MaxPages &
"&ID1=" & Request.QueryString("ID1") &"><IMG SRC='" & IconLast & "'
BORDER='" & IconBorder & "' HEIGHT='" & IconHeight & "' WIDTH='" &
IconWidth & "' ALT='Last page'></A>"
ELSE
ref= ref & "<A HREF=" & myPage & "?PageIndex=" & MaxPages &
"><IMG SRC='" & IconLast & "' BORDER='" & IconBorder &"' HEIGHT='" &
IconHeight & "' WIDTH='" & IconWidth & "' ALT='Last page'></A>"
END IF
ELSE
ref = "<IMG SRC='" & IconLastDisabled & "' ALT='Last page' BORDER='"
& IconBorder & "' HEIGHT='" & IconHeight & "' WIDTH='" & IconWidth &
"'>"
END IF
TableFooter = TableFooter & ref
FooterText = Replace(FooterText,"@TableFooter@", TableFooter)
%>
<%
END IF ' of ShowDBNav
END FUNCTION
'---------------------------------------------------------------------------
--'
%>
ANNOTATED EXAMPLES 169

Edit/Update Page
Clarion/ASP update pages come in four “flavors:” add a blank record, edit
an existing record, delete an existing record, and view (no edit) an existing
record. This annotates editing an existing record, which displays the most
complicated functionality of the four.

The update is divided into the edit page, which gets and formats the data, and
the processor page, which actually submits the update. First we’ll explain the
former:

Script Language and Notice


The first block declares the script language and provides instructions to web
designers who may wish to edit the code after generation, and clears the VB
error object, so that if it’s necessary to check for an error, there’s no old error
there.
<%@ Language=VBScript %>
<%
''===================================================================
''------------------ Notice to Web Page Designers! ------------------
''===================================================================
'' Data enabled web pages often require a particular sequence of
'' events to occur for successful execution. Therefore we ask
'' that you not reorder the ASP program logic. Also there should
'' be no changes in the naming of any HTML elements or ASP variables.
''
'' Every effort was made to allow "look and feel" changes to
'' occur by modifying the Cascading Style Sheets supplied with this
'' application
''===================================================================
'' Clear the error object declared in utils.asp
Err.Clear
%>

Include Files and Declarations


Because most of the “real work” is done in the processor page, the only
declarations are the variables for the buttons on the form:
<!-- #include file="AppData.asp"-->
<!-- #include file="adovbs.inc"-->
<!-- #include file="utils.asp"-->
<%
'' DebugMode is defined in AppData.asp as FALSE by default
'' debug of this page only by uncommenting the next line
'' DebugMode = TRUE
''
%>
<%
''# this next block creates each of the temporary variables for the merge
process
170 CLARION/ASP

DIM DeleteButton

DIM UpdateProductsFormAction

The MergeTemplate Function


This function opens the HTML runtime template containing the HTML form,
and populates the controls with the data and any formatting options
necessary:
'============================================================================='
'' MergeTemplate
'============================================================================='
Function MergeTemplate(templatepath)
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")
TemplateText = Server.MapPath(templatepath)
Set InStream = FileObject.OpenTextFile (TemplateText, 1, False, False)
TemplateText = Empty
While not InStream.AtEndOfStream
TemplateText = TemplateText & InStream.ReadLine & vbcrlf
Wend
TemplateText = Replace(TemplateText,"@DeleteButton@",DeleteButton)
TemplateText =
Replace(TemplateText,"@UpdateProductsFormAction@",UpdateProductsFormAction)
Set Instream = Nothing
TemplateText = Replace(TemplateText, "@ProductsProductName@",
ProductsProductName)
TemplateText = Replace(TemplateText, "@ProductsProductID@",
ProductsProductID)
TemplateText = Replace(TemplateText, "@ProductsSupplierID@",
ProductsSupplierID)
TemplateText = Replace(TemplateText, "@ProductsCategoryID@",
ProductsCategoryID)
TemplateText = Replace(TemplateText, "@ProductsQuantityPerUnit@",
ProductsQuantityPerUnit)
TemplateText = Replace(TemplateText, "@ProductsUnitPrice@",
ProductsUnitPrice)
TemplateText = Replace(TemplateText, "@ProductsUnitsInStock@",
ProductsUnitsInStock)
TemplateText = Replace(TemplateText, "@ProductsUnitsOnOrder@",
ProductsUnitsOnOrder)
TemplateText = Replace(TemplateText, "@ProductsReorderLevel@",
ProductsReorderLevel)
TemplateText = Replace(TemplateText, "@ProductsDiscontinued@",
ProductsDiscontinued)
TemplateText = Replace(TemplateText, "@ID1@", ID1)

Response.Write(TemplateText)
END Function

Open the Record Set


The next section opens the record set and checks for errors. It also verifies
that it was properly passed a parameter identifying the record.
'' create the connection object
Dim objCN
ANNOTATED EXAMPLES 171

Set objCN = Server.CreateObject("ADODB.Connection")


objCN.ConnectionTimeout = Application("MyASP_ConnectionTimeOut")
objCN.CommandTimeout = Application("MyASP_CommandTimeOut")
objCN.CursorLocation = Application("MyASP_CursorLocation")
objCN.Open Application("MyASP_ConnectionString"),
Application("MyASP_RuntimeUserName"),
Application("MyASP_RuntimePassword")
DIM oRSProducts, ClarionData
set oRSProducts = Server.CreateObject("ADODB.Recordset")
CheckError
%>
<% IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: objCN
ConnectionString: "<%Response.Write(objCN.ConnectionString)%>"
END DEBUG INFORMATION -->
<% END IF ' of DebugMode block %>
<%
'' this bit ensures that we got to this page correctly
IF REQUEST("ID1") = "" THEN
CALL displayBadRecord
END IF
ID1 = REQUEST("ID1")

Function: displayBadRecord
This function places a message on a new page if no record was obtainable:
FUNCTION displayBadRecord
ClarionData = ClarionData & "<div class='bg'>" & vbCRLF
ClarionData = ClarionData & "<table class='Data' border=0 cellspacing=0
cellpadding=0>" & vbCRLF
ClarionData = ClarionData & " <tr><td width='80%' class='Header'>Status</
td>"
ClarionData = ClarionData & "<td align='right' class='Header'>&nbsp;<A
href='JAVASCRIPT:history.back();'><IMG alt='Back' src='images/
Back.Gif' border=0></A></td>"
ClarionData = ClarionData & "</tr>" & vbCRLF
ClarionData = ClarionData & "<tr><td class='Input' colspan='2'>The requested
record could not be found<br>" & vbCRLF
ClarionData = ClarionData & "</td></tr>" & vbCRLF
ClarionData = ClarionData & "</table>" & vbCRLF
ClarionData = ClarionData & "</div>" & vbCRLF
Call MergeEditTemplate("HTML/blank.htm")
Response.End
END FUNCTION

MergeEditTemplate Function
This function opens the runtime HTML template and performs the symbol
substitution necessary to place the proper data in the HTML controls on the
HTML form.
'' #########################################################
'' MergeTemplate
'' #########################################################
FUNCTION MergeEditTemplate(templatepath)
172 CLARION/ASP

Set FileObject = Server.CreateObject("Scripting.FileSystemObject")


TemplateText = Server.MapPath(templatepath)
Set InStream = FileObject.OpenTextFile (TemplateText, 1, False, False)
TemplateText = Empty
While not InStream.AtEndOfStream
TemplateText = TemplateText & InStream.ReadLine & vbcrlf
Wend
Set Instream = Nothing
TemplateText = Replace(TemplateText,"@ClarionData@",ClarionData)
Response.Write(TemplateText)
END FUNCTION

Get the Record


The next section provides the SQL SELECT statement, opens the record set,
checks for any database error, loads the record (the MoveFirst method; this is
necessary even if there’s only one record), and checks for a database error
again. Then, if in debug mode, debug information is output:
strSQL = "SELECT dbo.Products.ProductName, dbo.Products.ProductID,
dbo.Products.SupplierID, dbo.Products.CategoryID,
dbo.Products.QuantityPerUnit, dbo.Products.UnitPrice,
dbo.Products.UnitsInStock, dbo.Products.UnitsOnOrder,
dbo.Products.ReorderLevel, dbo.Products.Discontinued FROM
dbo.Products WHERE dbo.Products.ProductID = " &
CSTR(Request("ID1"))
oRSProducts.Open strSQL, objCN, adOpenStatic, adLockOptimistic
CheckError
oRSProducts.MoveFirst
CheckError
%>
<% IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Application: <%Response.Write(Request.ServerVariables("URL"))%>
Server:
<%Response.Write(Request.ServerVariables("SERVER_NAME"))%>
PageLevel: <%Response.Write(PageLevel)%>
DebugMode: <%Response.Write(DebugMode)%>
ShowQuery: <%Response.Write(ShowQuery)%>
ShowDBNav: <%Response.Write(ShowDBNav)%>
END DEBUG INFORMATION -->
<% END IF ' of DebugMode block%>

<%IF DebugMode THEN %>


<!-- BEGIN DEBUG INFORMATION
Object: oRSProducts
Query: "<%Response.Write(strSQL)%>"
END DEBUG INFORMATION -->
<% END IF %>
<%

Set the Form Action


This section “instructs” the form button what page to post the form data to
when the end user presses the submit button; in other words, this is the part
ANNOTATED EXAMPLES 173

that invokes the processor page, passing the unique value to identify the
record:
UpdateProductsFormAction = "UpdateProductsEditX.asp"
oRSProductsProductID = oRSProducts.Fields("Pro:ProductID").Value
ID1 = REQUEST("ID1")

Get the Field Values


The following section declares a variable for each form field, and gets it
from the record set. We don’t want to “dump” the values directly into the
HTML form, because we must check for nulls, do any necessary formatting,
etc.
DIM ProductsProductName
IF IsNULL(oRSProducts.Fields("ProductName").Value) THEN
ProductsProductName = ""
ELSE
ProductsProductName = TRIM(oRSProducts.Fields("ProductName").Value)
END IF
DIM ProductsProductID
IF IsNULL(oRSProducts.Fields("ProductID").Value) THEN
ProductsProductID = ""
ELSE
ProductsProductID = oRSProducts.Fields("ProductID").Value
END IF
DIM ProductsSupplierID
IF IsNULL(oRSProducts.Fields("SupplierID").Value) THEN
ProductsSupplierID = ""
ELSE
ProductsSupplierID = oRSProducts.Fields("SupplierID").Value
END IF
DIM ProductsCategoryID
IF IsNULL(oRSProducts.Fields("CategoryID").Value) THEN
ProductsCategoryID = ""
ELSE
ProductsCategoryID = oRSProducts.Fields("CategoryID").Value
END IF
DIM ProductsQuantityPerUnit
IF IsNULL(oRSProducts.Fields("QuantityPerUnit").Value) THEN
ProductsQuantityPerUnit = ""
ELSE
ProductsQuantityPerUnit = TRIM(oRSProducts.Fields("QuantityPerUnit").Value)
END IF
DIM ProductsUnitPrice
IF IsNULL(oRSProducts.Fields("UnitPrice").Value) THEN
ProductsUnitPrice = ""
ELSE
ProductsUnitPrice = oRSProducts.Fields("UnitPrice").Value
END IF
DIM ProductsUnitsInStock
IF IsNULL(oRSProducts.Fields("UnitsInStock").Value) THEN
ProductsUnitsInStock = ""
ELSE
ProductsUnitsInStock = oRSProducts.Fields("UnitsInStock").Value
END IF
DIM ProductsUnitsOnOrder
174 CLARION/ASP

IF IsNULL(oRSProducts.Fields("UnitsOnOrder").Value) THEN
ProductsUnitsOnOrder = ""
ELSE
ProductsUnitsOnOrder = oRSProducts.Fields("UnitsOnOrder").Value
END IF
DIM ProductsReorderLevel
IF IsNULL(oRSProducts.Fields("ReorderLevel").Value) THEN
ProductsReorderLevel = ""
ELSE
ProductsReorderLevel = oRSProducts.Fields("ReorderLevel").Value
END IF
DIM ProductsDiscontinued
IF IsNULL(oRSProducts.Fields("Discontinued").Value) THEN
ProductsDiscontinued = ""
ELSE
IF (oRSProducts.Fields("Discontinued").Value) THEN
ProductsDiscontinued = "CHECKED"
ELSE
ProductsDiscontinued = ""
END IF
END IF

Display (or Not) the Delete Button


If a delete is allowed, we display a button, if not, we don’t:
IF (SESSION("UserLevel") >= DeleteLevel) THEN
DeleteButton = "<FORM METHOD='post' ACTION='UpdateProductsDel.asp'
ID='form1' NAME='form1'>"
DeleteButton = DeleteButton & "<input TYPE='hidden' ID='ID1' NAME='ID1'
VALUE='@ID1@'>"
DeleteButton = DeleteButton & "<INPUT TYPE='submit' VALUE='Delete'
TITLE='Delete this record' ID='submit1' NAME='submit1'>"
DeleteButton = DeleteButton & "</FORM>"
ELSE
DeleteButton = ""
End IF

Call the Merge Function and End


The final section calls the merge template function, explained above, and
closes the connection. At this point, everything awaits user input, and
pressing the Submit button will forward it to the edit Processor page.
CALL MergeTemplate("HTML/UpdateProductsEdit.htm")
SET oRSProducts = Nothing
'' close and destroy the connection object
objCN.Close
SET objCN = NOTHING
%>

The Edit Processor Page


The processor page does the actual work of updating the data, and is called
by the edit page when the end user presses the Submit button.
ANNOTATED EXAMPLES 175

Script Language and Notice


The first block declares the script language and provides instructions to web
designers who may wish to edit the code after generation, and clears the VB
error object, so that if it’s necessary to check for an error, there’s no old error
there.
<%@ Language=VBScript %>
<%
''===================================================================
''------------------ Notice to Web Page Designers! ------------------
''===================================================================
'' Data enabled web pages often require a particular sequence of
'' events to occur for successful execution. Therefore we ask
'' that you not reorder the ASP program logic. Also there should
'' be no changes in the naming of any HTML elements or ASP variables.
''
'' Every effort was made to allow "look and feel" changes to
'' occur by modifying the Cascading Style Sheets supplied with this
'' application
''===================================================================
'' Clear the error object declared in utils.asp
Err.Clear
%>

Include Files
Then, the include files are processed.
• AppData contains several global declarations, such as icon sizes and
image names, debug options as set in the global template, and so on.
• ADOVBS contains declarations necessary for accessing ADO.
• Utils contains many helper functions.
<!-- #include file="AppData.asp"-->
<!-- #include file="adovbs.inc"-->
<!-- #include file="utils.asp"-->

Variable Declarations and Open the Record Set


So far the code has been identical to the browse code. Next, the code
declares the connection object, gets the necessary information for the
connection from the session variables, opens the connection and initializes
the record set. It calls the CheckError function after the database access.

<%
'' create the connection object
Dim objCN
176 CLARION/ASP

Set objCN = Server.CreateObject("ADODB.Connection")


objCN.ConnectionTimeout = Application("MyASP_ConnectionTimeOut")
objCN.CommandTimeout = Application("MyASP_CommandTimeOut")
objCN.CursorLocation = Application("MyASP_CursorLocation")
objCN.Open Application("MyASP_ConnectionString"),
Application("MyASP_RuntimeUserName"),
Application("MyASP_RuntimePassword")
Dim oRSProducts, myError, myStatus
Set oRSProducts = Server.CreateObject("ADODB.Recordset")
CheckError

The MergeTemplate Function


The MergeTemplate function opens the runtime HTML template so that the
rest of the code can evaluate whatever is necessary for the HTML page and
the HTML form it contains, replace the symbols in the template with the
necessary data, and output it to the browser client:
'============================================================================='
'' MergeTemplate
'============================================================================='
Function MergeEditTemplate(templatepath)
Set FileObject = Server.CreateObject("Scripting.FileSystemObject")
TemplateText = Server.MapPath(templatepath)
Set InStream = FileObject.OpenTextFile (TemplateText, 1, False, False)
TemplateText = Empty
While not InStream.AtEndOfStream
TemplateText = TemplateText & InStream.ReadLine & vbcrlf
Wend
Set Instream = Nothing
TemplateText = Replace(TemplateText,"@ClarionData@",ClarionData)
Response.Write(TemplateText)
END Function

%>

Check for Not Found


Because it’s an update form, the code has to verify that it received a
parameter with a unique ID. This section initializes a flag, checks the ?ID1
parameter, and then outputs a “No Record Found” page if it didn’t receive a
unique value to identify the record:
<% IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Object: objCN
ConnectionString: "<%Response.Write(objCN.ConnectionString)%>"
END DEBUG INFORMATION -->
<% END IF ' of DebugMode block %>

<%
'' this bit ensures that we got to this page correctly
DIM bolNotFound
ANNOTATED EXAMPLES 177

boLNotFound = False

IF REQUEST("ID1") = "" THEN


bolNotFound = True
END IF

IF bolNotFound = True THEN


ClarionData = ClarionData & "<div class='bg'>" & vbCRLF
ClarionData = ClarionData & "<table class='Data' border=0 cellspacing=0
cellpadding=0>" & vbCRLF
ClarionData = ClarionData & " <tr><td width='80%' class='Header'>Status</
td>"
ClarionData = ClarionData & "<td align='right' class='Header'>&nbsp;<A
href='JAVASCRIPT:history.back();'><IMG alt='Back' src='images/
Back.Gif' border=0></A></td>"
ClarionData = ClarionData & "</tr>" & vbCRLF
ClarionData = ClarionData & "<tr><td colspan='2' class='Input'>The requested
record could not be found<br>" & vbCRLF
ClarionData = ClarionData & "</td></tr>" & vbCRLF
ClarionData = ClarionData & "</table>" & vbCRLF
ClarionData = ClarionData & "</div>" & vbCRLF
Call MergeEditTemplate("HTML/blank.htm")
Response.End
END IF

Get the Record


The next section provides the SQL SELECT statement, opens the record set,
checks for any database error, loads the record (the MoveFirst method; this is
necessary even if there’s only one record), and checks for a database error
again. Then, if in debug mode, debug information is output:
strSQL = "SELECT dbo.Products.ProductName, dbo.Products.ProductID,
dbo.Products.SupplierID, dbo.Products.CategoryID,
dbo.Products.QuantityPerUnit, dbo.Products.UnitPrice,
dbo.Products.UnitsInStock, dbo.Products.UnitsOnOrder,
dbo.Products.ReorderLevel, dbo.Products.Discontinued FROM
dbo.Products WHERE dbo.Products.ProductID = " &
CSTR(Request("ID1"))
oRSProducts.Open strSQL, objCN, adOpenStatic, adLockOptimistic
CheckError
oRSProducts.MoveFirst
CheckError
%>
<% IF DebugMode THEN %>
<!-- BEGIN DEBUG INFORMATION
Application: <%Response.Write(Request.ServerVariables("URL"))%>
Server:
<%Response.Write(Request.ServerVariables("SERVER_NAME"))%>
PageLevel: <%Response.Write(PageLevel)%>
DebugMode: <%Response.Write(DebugMode)%>
ShowQuery: <%Response.Write(ShowQuery)%>
ShowDBNav: <%Response.Write(ShowDBNav)%>
END DEBUG INFORMATION -->
<% END IF ' of DebugMode block%>

<%IF DebugMode THEN %>


<!-- BEGIN DEBUG INFORMATION
178 CLARION/ASP

Object: oRSProducts
Query: "<%Response.Write(strSQL)%>"
END DEBUG INFORMATION -->
<% END IF %>

Placing the Fields


The following is repeated for each field (see below), but this section
describes the first field (the product name) on the form. First it tests if the
field was required, and if its value is NULL, then a message is prepared
indicating the value was missing. The code then tests the record set to verify
that the field is updatable (else there would be no reason to put it in an edit
control). It gets the actual value from the record set. It then checks the data
type, and sets a null value to either 0 or an empty string, depending on the
type, so that it can display the value in the edit box. It repeats this for each
field.
<%

flgMissing = 0
myStatus = ""

'' Test for Required column


IF( Request.Form("txtProductsProductName") = "" OR
IsNUll(Request.Form("txtProductsProductName")) ) THEN
IF myStatus = "" THEN
myStatus = "<STRONG>Some data was missing</STRONG><BR><HR>"
END IF
flgMissing = 1
myStatus = myStatus & " <STRONG>Product Name</
STRONG> " & ": Required field <HR>" & vbCRLF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("ProductName").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("ProductName").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsProductName") > "" THEN
oRSProducts.Fields("ProductName").Value =
MID(Request.Form("txtProductsProductName"),1,oRSProducts.Fields("ProductName").DefinedSize)
ELSE
IF ( (oRSProducts.Fields("ProductName").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("ProductName").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("ProductName").Type
CASE 7,14,131,139 oRSProducts.Fields("ProductName").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("ProductName").Value =
""
END SELECT
END IF
END IF
END IF

(from here the code repeats the previous code for each field on the page)
'' Test for Required column
ANNOTATED EXAMPLES 179

IF( Request.Form("txtProductsProductID") = "" OR


IsNUll(Request.Form("txtProductsProductID")) ) THEN
IF myStatus = "" THEN
myStatus = "<STRONG>Some data was missing</STRONG><BR><HR>"
END IF
flgMissing = 1
myStatus = myStatus & " <STRONG>Product ID</STRONG>
" & ": Required field <HR>" & vbCRLF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("ProductID").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("ProductID").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsProductID") > "" THEN
oRSProducts.Fields("ProductID").Value =
Request.Form("txtProductsProductID")
ELSE
IF ( (oRSProducts.Fields("ProductID").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("ProductID").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("ProductID").Type
CASE 7,14,131,139 oRSProducts.Fields("ProductID").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("ProductID").Value = ""
END SELECT
END IF
END IF
END IF
'' Test for Required column
IF( Request.Form("txtProductsSupplierID") = "" OR
IsNUll(Request.Form("txtProductsSupplierID")) ) THEN
IF myStatus = "" THEN
myStatus = "<STRONG>Some data was missing</STRONG><BR><HR>"
END IF
flgMissing = 1
myStatus = myStatus & " <STRONG>Supplier ID</STRONG> " &
": Must be in file "
myStatus = myStatus & "<HR>" & vbCRLF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("SupplierID").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("SupplierID").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsSupplierID") > "" THEN
oRSProducts.Fields("SupplierID").Value =
Request.Form("txtProductsSupplierID")
ELSE
IF ( (oRSProducts.Fields("SupplierID").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("SupplierID").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("SupplierID").Type
CASE 7,14,131,139 oRSProducts.Fields("SupplierID").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("SupplierID").Value =
""
END SELECT
END IF
END IF
180 CLARION/ASP

END IF
'' Test for Required column
IF( Request.Form("txtProductsCategoryID") = "" OR
IsNUll(Request.Form("txtProductsCategoryID")) ) THEN
IF myStatus = "" THEN
myStatus = "<STRONG>Some data was missing</STRONG><BR><HR>"
END IF
flgMissing = 1
myStatus = myStatus & " <STRONG>Category ID</STRONG> " &
": Must be in file "
myStatus = myStatus & "<HR>" & vbCRLF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("CategoryID").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("CategoryID").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsCategoryID") > "" THEN
oRSProducts.Fields("CategoryID").Value =
Request.Form("txtProductsCategoryID")
ELSE
IF ( (oRSProducts.Fields("CategoryID").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("CategoryID").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("CategoryID").Type
CASE 7,14,131,139 oRSProducts.Fields("CategoryID").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("CategoryID").Value =
""
END SELECT
END IF
END IF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("QuantityPerUnit").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("QuantityPerUnit").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsQuantityPerUnit") > "" THEN
oRSProducts.Fields("QuantityPerUnit").Value =
MID(Request.Form("txtProductsQuantityPerUnit"),1,oRSProducts.Fields("QuantityPerUnit").DefinedSize)
ELSE
IF ( (oRSProducts.Fields("QuantityPerUnit").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("QuantityPerUnit").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("QuantityPerUnit").Type
CASE 7,14,131,139 oRSProducts.Fields("QuantityPerUnit").Value = 0
CASE 8,129,203,202,200,130
oRSProducts.Fields("QuantityPerUnit").Value = ""
END SELECT
END IF
END IF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("UnitPrice").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("UnitPrice").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsUnitPrice") > "" THEN
ANNOTATED EXAMPLES 181

oRSProducts.Fields("UnitPrice").Value =
Request.Form("txtProductsUnitPrice")
ELSE
IF ( (oRSProducts.Fields("UnitPrice").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("UnitPrice").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("UnitPrice").Type
CASE 7,14,131,139 oRSProducts.Fields("UnitPrice").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("UnitPrice").Value = ""
END SELECT
END IF
END IF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("UnitsInStock").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("UnitsInStock").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsUnitsInStock") > "" THEN
oRSProducts.Fields("UnitsInStock").Value =
Request.Form("txtProductsUnitsInStock")
ELSE
IF ( (oRSProducts.Fields("UnitsInStock").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("UnitsInStock").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("UnitsInStock").Type
CASE 7,14,131,139 oRSProducts.Fields("UnitsInStock").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("UnitsInStock").Value =
""
END SELECT
END IF
END IF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("UnitsOnOrder").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("UnitsOnOrder").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsUnitsOnOrder") > "" THEN
oRSProducts.Fields("UnitsOnOrder").Value =
Request.Form("txtProductsUnitsOnOrder")
ELSE
IF ( (oRSProducts.Fields("UnitsOnOrder").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("UnitsOnOrder").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("UnitsOnOrder").Type
CASE 7,14,131,139 oRSProducts.Fields("UnitsOnOrder").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("UnitsOnOrder").Value =
""
END SELECT
END IF
END IF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
182 CLARION/ASP

IF ( (oRSProducts.Fields("ReorderLevel").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("ReorderLevel").Attributes AND
&H00000008)=&H00000008) THEN
IF Request.Form("txtProductsReorderLevel") > "" THEN
oRSProducts.Fields("ReorderLevel").Value =
Request.Form("txtProductsReorderLevel")
ELSE
IF ( (oRSProducts.Fields("ReorderLevel").Attributes AND
&H00000020)=&H00000020) THEN
oRSProducts.Fields("ReorderLevel").Value = NULL
ELSE
SELECT CASE oRSProducts.Fields("ReorderLevel").Type
CASE 7,14,131,139 oRSProducts.Fields("ReorderLevel").Value = 0
CASE 8,129,203,202,200,130 oRSProducts.Fields("ReorderLevel").Value =
""
END SELECT
END IF
END IF
END IF
'' test for updateable column 4 updatable 8 for unknown updateable
IF ( (oRSProducts.Fields("Discontinued").Attributes AND
&H00000004)=&H00000004 OR
(oRSProducts.Fields("Discontinued").Attributes AND
&H00000008)=&H00000008) THEN
IF(Request.Form("txtProductsDiscontinued") <> "") THEN
oRSProducts.Fields("Discontinued").Value = 1
ELSE
oRSProducts.Fields("Discontinued").Value = 0
END IF
END IF

Send the Data to the Merge


The final section calls the MergeEditTemplate function (explained above). It
also ouputs a “Your update succeeded” succeeded message (after returning
from the processor page, and closes the database connection
ı IF ( flgMissing = 0 ) THE
ı oRSProducts.Updat
ı CheckErro
ı oRSProducts.Clos
ı myStatus = "Your update succeeded <BR><BR>
ıEND I
ıResponse.Clea
ımyError = ProcessErrors(
ıIF myError > "" THE
ı myStatus = myErro
ıELS
ı IF myStatus = "" THE
ı myStatus = "Your update succeeded <br><br>
ı END I
ıEND I
ıClarionData = ClarionData & "<div class='bg'>" & vbCRL
ıClarionData = ClarionData & "<table class='Data' border=0 cellspacing=
cellpadding=0>" & vbCRL
ANNOTATED EXAMPLES 183

ClarionData = ClarionData & " <tr><td width='80%' class='Header'>Status</


td>"
ClarionData = ClarionData & "<td align='right' class='Header'>&nbsp;<A
href='JAVASCRIPT:history.back();'><IMG alt='Back' src='images/
Back.Gif' border=0></A></td>"
ClarionData = ClarionData & "</tr>" & vbCRLF
ClarionData = ClarionData & " <tr><td class='Input' colspan='2'>" &
myStatus & "<br></td></tr>" & vbCRLF
ClarionData = ClarionData & "</table>" & vbCRLF
ClarionData = ClarionData & "</div>" & vbCRLF
Call MergeEditTemplate("HTML/blank.htm")

set oRSProducts = nothing


'' close and destroy the connection object
objCN.Close
SET objCN = NOTHING
%>
184 CLARION/ASP
2769 East Atlantic Boulevard
Pompano Beach, Florida 33062
(954) 785-4555
Fax: (954) 946-1650
www.softvelocity.com

You might also like