Professional Documents
Culture Documents
Annotated Examples
ANNOTATED EXAMPLES 1
CLARION/
ASP
Annotated
Examples
2 CLARION/ASP
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.
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.
Contents
INTRODUCTION 7
PRELIMINARY: SETUP 9
SQL Server 9
The Dictionary Changes 10
The /images Virtual Directory 11
1. INTRODUCTION
This Annotated Examples manual consists of the following sections:
• 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.
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.
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.
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.
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
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.
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. 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 should now have only the Application Tree dialog open. You are now
ready to apply the Browse extension.
3. Choose ASP Browse from the Select Extension dialog and press the
Select button.
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.
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).
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
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.
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.
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.
Begin with your application tree open to the application created in the
previous section. To apply the Global template:
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.
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.
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
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.
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. 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
You may now press the OK button to close the Connection Properties dialog.
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.
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
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.
The Clarion/ASP browse extension template is now applied, and may now be
customized.
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.
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
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.
in order to illustrate that you may customize the header text in this
dialog.
11. Press OK twice to close the Data Columns and Extensions dialog and
return to the Application Tree. You’ve now configured the browse.
1. Right click the procedure and choose Extensions to open the Extensions
and Control Templates dialog.
40 CLARION/ASP
The Clarion/ASP form extension template is now applied, and may now be
customized.
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.
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
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.
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.
To generate your project, with only the Application Tree window open,
choose Project > Generate All from the development environment menu.
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.
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.
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).
• 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 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>
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.
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
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.
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 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
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).
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.
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.
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 “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.
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
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
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.
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
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.
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
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
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).
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
The ProductPhotos browse is now complete, and now it’s time to move on to
the update forms.
The Clarion/ASP form extension template is now applied, and may now be
customized.
ANNOTATED EXAMPLES 75
The Clarion/ASP form extension template is now applied, and may now be
customized.
The Clarion/ASP form extension template is now applied, and may now be
customized.
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.
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..
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.
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
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' >"
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.
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.
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.
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
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.
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
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
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.
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.
3. Set the User Table to aspusers (or whichever security table you use).
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.
• SelectProducts
• UpdateCategories
• UpdateCustomers
• UpdateEmployees
• UpdateOrders
• UpdateOrder_Details
• UpdateProducts
• UpdateShippers
• UpdateSuppliers
• UpdateViewOrdersQuery
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."
• 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.
8. Doubleclick the Postal Code column. Check the "Include with Prior
Column" box. Enter 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.
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!).
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 <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 in the "preceding text" box.
23. Doubleclick the Ship Postal Code column. Check the "Include with Prior
Column" box. Enter in the "preceding text" box.
24. Click the Page tab and press the Regenerate SQL button.
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.
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>
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.
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.
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.
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
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.
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.
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.
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.
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
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.
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.
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
84. Press OK to save the procedure changes and return to the Application
Tree.
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
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
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.
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-->
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
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.
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
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
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!
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.
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.
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
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.
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
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 %>
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
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 ( IsEmpty(SESSION("BrowseProducts#COL")) OR
IsNull(SESSION("BrowseProducts#COL")) ) THEN
148 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
mySQL = myQuery
'' test for any value in the myWhere, if valid concatenate the clause
IF myWHERE <> "" THEN
mySQL = mySQL & " WHERE " & myWhere
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
%>
<%
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 DebugMode THEN
Response.Write("QueryString: " & Request.QueryString)
END IF
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)
RemainderText = Empty
RemainderText = Mid(TemplateText, ndxStart, strLen)
TemplateText = Empty
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
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
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
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)
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
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
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:
DIM DeleteButton
DIM UpdateProductsFormAction
Response.Write(TemplateText)
END Function
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'> <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
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")
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
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"-->
<%
'' create the connection object
Dim objCN
176 CLARION/ASP
%>
<%
'' this bit ensures that we got to this page correctly
DIM bolNotFound
ANNOTATED EXAMPLES 177
boLNotFound = False
Object: oRSProducts
Query: "<%Response.Write(strSQL)%>"
END DEBUG INFORMATION -->
<% END IF %>
flgMissing = 0
myStatus = ""
(from here the code repeats the previous code for each field on the page)
'' Test for Required column
ANNOTATED EXAMPLES 179
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