Advanced
Database Example
This chapter will demonstrate advanced example of using ASP Express
components to build web page for tables Vendors and Parts
with support for master-detail data editing. We are going to use TASPXFindView,
TASPXShoppingCartView, TASPXEditView, TASPXReconcileView
and TASPXTabbedView components to develop application user
interface.
The major goal of this sample is to explain the basic principles of
implementing data retrieval and updates with ASP Express.
Create a new ActiveX Library project and add two MTS Data
Modules in it. Save all project files in some directory using the
following naming convention:
File
|
Module/Object
|
Description
|
VendorServer.dpr
|
library
VendorServer
|
Main
program file.
|
Unit1.pas
|
TBusinessServices
|
Implements
IBusinessServices interface.
|
Unit2.pas
|
TPresentaionServices
|
Implements
IPresentationSevices interface.
|
VendorServer_TLB.pas
|
Object
Pascal declarations of type library content
|
Generated
by Delphi IDE automatically each time when you update Type Library
content.
|
Application Business
Services
Put TADOConnection, two TADODataSet components, TDataSource,
TXMLProvider and TXMLADOResolver on the design window of BusinessServices
data module. Set their properties according to this table:
Component
|
Property
|
Value
|
Description
|
ADOConnection1 333j922d
|
Name
|
DB
|
|
DB
|
LoginPrompt
|
False
|
|
DB
|
ConnectionString
|
Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=D:\Program Files\Common Files\Borland Shared\Data\dbdemos.mdb
|
Location
of dbdemos.mdb database may be different on your computer.
|
ADODataSet1
|
Name
|
Vendors
|
|
Vendors
|
Connection
|
DB
|
|
Vendors
|
CommandText
|
select
* from vendors
|
|
Vendors
|
Fields
|
Create
persistent fields for Vendors component. Set ProviderFlags
property of all fields to [pfInUpdate]. Set ProviderFlags
property of field VendorNo to [pfInUpdate, pfInWhere, pfInKey].
|
Double-click
component icon and right-click Field Editor window. Select Add
all fields option to create persistent fields.
|
DataSource1
|
Name
|
VendorSource
|
|
VendorSource
|
DataSet
|
Vendors
|
|
ADODataSet2
|
Name
|
Parts
|
|
Parts
|
Connection
|
DB
|
|
Parts
|
DataSource
|
Vendors
|
|
Parts
|
CommandText
|
select
* from parts
|
|
Parts
|
Fields
|
Create
persistent fields for Parts component. Set ProviderFlags
property of all fields to [pfInUpdate]. Set ProviderFlags
property of field PartNo to [pfInUpdate, pfInWhere, pfInKey].
Set currency property to True for Cost and ListPrice
field components.
|
Double-click
component icon and right-click Field Editor window. Select Add
all fields option to create persistent fields.
|
XMLProvider1
|
Name
|
VendorProvider
|
|
VendorProvider
|
DataSet
|
Vendors
|
|
VendorProvider
|
Dictionary
|
|
Add
two items to the Dictionary collection.
|
CustomerProvider.Dictionary[0]
|
DataSet
|
Vendors
|
|
CustomerProvider.Dictionary[0]
|
Generator
|
vendor_gen
|
|
CustomerProvider.Dictionary[0]
|
TableName
|
VENDORS
|
|
CustomerProvider.Dictionary[1]
|
DataSet
|
Parts
|
|
CustomerProvider.Dictionary[1]
|
Generator
|
part_gen
|
|
CustomerProvider.Dictionary[1]
|
TableName
|
PARTS
|
|
XMLADOResolver1
|
Name
|
Resolver
|
|
Resolver
|
Connection
|
DB
|
|
This is how your data module BusinessServices will look like
after you have completed the instructions above:
Right-click VendorProvider component and select Save XML
option. Enter Vendors in the Save As dialog and Vendors.XML
file with Vendor-Parts data will be saved in the specified location. Set DB.Connected
property to False.
BusinessServices component shell provide the following services
for our application:
- Search against Vendors
table;
- Retrieval of any particular
Vendor information including all Parts supplied by this
vendor;
- Method to save
modifications of Vendors-Parts data to the database.
For both search and retrieval we are going to use the same Vendors,
VendorSource and Parts components changing their properties
accordingly to archive desired functionality.
Implement IBusinessServices.GetVendor method as shown below:
This method will return one Vendor record and all Parts
which it supplies.
Implement IBusinessServices.FindVendors as follows:
FindVendors performs case-insensitive search against Vendors
table by VendorName and/or City fields. If neither parameter
was provided then exception is raised. This method temporarily disconnects Parts
dataset and the result of FindVendors will include located vendors
only.
Implementation of IBusinessServices.SaveChanges method is almost
trivial and pretty much the same for the majority of projects:
Next, you will build presentation services of application that will use
methods GetVendor, FindVendor and SaveChanges.
Application Presentation
Services: Find
Put TASPXEngine, TASPXPersistentSession, TASPXReconcileView,
TXMLData and TASPXFindView components on the PresentationServices
data module. Setup their properties:
Component
|
Property
|
Value
|
ASPXEngine1
|
Name
|
Engine
|
ASPXPersistentSession1
|
Name
|
UserSession
|
UserSession
|
Repository
|
Default
|
ASPXReconcileView1
|
Name
|
viewReconcile
|
viewReconcile
|
Header
|
<div
class="viewHeader">Reconcile Errors</div>
|
XMLData1
|
Name
|
dataFindVendors
|
dataFindVendors
|
DesignFile
|
Path
to the file Vendors.xml
|
ASPXFindView1
|
Name
|
viewFindVendors
|
viewFindVendors
|
Session
|
UserSession
|
viewFindVendors
|
Data
|
dataFindVendors
|
viewFindVendors
|
Header
|
<div
class="viewHeader">Find Vendors</div>
|
viewFindVendors
|
DisplayName
|
Find
Vendors
|
Design form for the viewFindVendors component. Select viewFindVendors.Form
property in Object Inspector and click on a (...) button to bring up
Web Form Designer.
Drag and drop two TLabelElement components, two TTextElement components
and one TSubmitElement component on the form. Set component
properties according to the table:
Component
|
Property
|
Value
|
LabelElement1
|
Caption
|
Company:
|
TextElement1
|
Name
|
CompanyParam
|
LabelElement2
|
Caption
|
City:
|
TextElement2
|
Name
|
CityParam
|
CityParam
|
Size
|
|
SubmitElment1
|
Caption
|
Find
|
This is how your form may look like:
Setup viewFindVendors.Columns property as follows:
Object
|
Property
|
Value
|
Columns[0]
|
LinkFields
|
VendorNo
|
Columns[0]
|
SortOrder
|
soAscending
|
Columns[6]
|
CellAttributes.Align
|
haCenter
|
Implement viewFindVendors.OnPerformFind event handler:
Implement IPresentationServices.DisplayFindVendors method ...
... and install both BusinessServices and PresentationServices
components in package/application MyASPXSamples. Generate test ASP
script to test IPresentationServices.DisplayFindVendors method using
Page
Wizard. Navigate to the script in a web browser and make sure that
everything works fine:
Application Presentation
Services: Vendor Shopping Cart
On this phase we are going to provide user with a ability to place
arbitrary vendors with their parts in some sort of a shopping cart. This
will allow user to perform multiple searches against vendor database and
maintain a list of selected vendors at the same time.
When user clicks on a link in Find Vendors section a shopping
cart component will retrieve picked vendor and
corresponding parts information from the database and preserve
this data in user session. The shopping cart content will be
displayed on the same page with Find Vendors section.
Put TXMLData and TASPXShoppingCartView components on the PresentationServices
data module. Setup their properties:
Component
|
Property
|
Value
|
XMLData1
|
Name
|
dataVendors
|
dataVendors
|
DesignFile
|
Path
to the file Vendors.xml
|
ASPXShoppingCartView1
|
Name
|
viewVendorsSC
|
viewVendorsSC
|
Session
|
UserSession
|
viewVendorsSC
|
Data
|
dataVendors
|
viewVendorsSC
|
CartUniqueField
|
VendorNo
|
viewVendorsSC
|
Header
|
<div
class="viewHeader">Selected Vendors</div>
|
viewVendorsSC
|
DisplayName
|
Selected
Vendors
|
viewVendorsSC
|
QuantityCol
|
|
Build columns for viewVendorSC component:
Setup viewVendorsSC.ToolBar.Buttons collection:
Implement dataVendors.OnSessionInit and viewVendorsSC.OnPutItemInCar
event handler and IPresentationServices.DisplayVendorCartAndFindSections
interface method as explained below:
First event handler will initialize dataVendors with empty XML
data packet upon UserSession request. Second event
handler is called whenever viewVendorsSC detects that new Vendor
record should be placed in vendors cart. New interface method will
display shopping cart content and current state of find view if called from
ASP script.
Create ASP script to test DisplayVendorCartAndFindSecitons using Page Wizard:
Navigate to the page in a web browser and play with it for awhile:
Application Presentation
Services: Tabbed View
Shopping cart contains vendor and relates parts records
that can be displayed in any other view-type components.
We don't have enough empty space on our latest version of User Interface
to display more views. The common solution to this problem is to use
another HTML page or implement tabbed presentation of information.
Lets place TASPXTabbedView component on the PresentationServices
data module. Change properties of this component as described below:
Component
|
Property
|
Value
|
ASPXTabbedView1
|
Name
|
viewVendorTabs
|
viewVendorTabs
|
Tabs
|
Create
two items in this collection.
|
viewVendorTabs.Tabs[0]
|
CaptionAttributes.Caption
|
Find
|
viewVendorTabs.Tabs[0]
|
Views
|
Create
two items in this collection.
|
viewVendorTabs.Tabs[0].Views[0]
|
View
|
viewVendorSC
|
viewVendorTabs.Tabs[0].Views[1]
|
View
|
viewFindVendors
|
viewVendorTabs.Tabs[1]
|
CaptionAttributes.Caption
|
Edit
|
Add new interface method IPresentationServices.DisplayVendors:
Deploy a new ASP script that invokes IPresentationServices.DisplayVendors
and try to switch between Find and Edit tabs, add vendors
to shopping cart, etc. The page displayed below was build with Advanced
template and includes demo menu.
Application Presentation
Services: Editing Data
We have provided an extra Edit tab that can be used to link some
other views to application presentation. Lets put TXMLData and two TASPXEditView
components on the data module. Change their properties according to the
table:
Component
|
Property
|
Value
|
XMLData1
|
Name
|
dataParts
|
dataParts
|
Master
|
dataVendors
|
dataParts
|
MasterField
|
Parts
|
ASPXEditView1
|
Name
|
viewEditVendors
|
viewEditVendors
|
Data
|
dataVendors
|
viewEditVendors
|
Session
|
UserSession
|
viewEditVendors
|
NavigationFields
|
VendorName
|
viewEditVendors
|
ReconcileView
|
viewReconcile
|
viewEditVendors
|
Header
|
<div
style="viewHeader">Vendors</div>
|
ASPXEditView2
|
Name
|
viewEditParts
|
viewEditParts
|
Data
|
dataParts
|
viewEditParts
|
Session
|
UserSession
|
viewEditParts
|
NavigationFields
|
Description
|
viewEditParts
|
Header
|
<div
style="viewHeader">Parts</div>
|
viewVendorTabs.Tabs[1]
|
Views
|
Add
two items to this collection
|
viewVendorTabs.Tabs[1].Views[0]
|
View
|
viewEditVendors
|
viewVendorTabs.Tabs[1].Views[1]
|
View
|
viewEditParts
|
Setup viewEditVendors.Columns:
Setup viewEditVendors.Form as shown on the picture. Transform PreferredText1
into PreferredSelect1 and add two items to PreferredSelect1.Values:
Yes and No. Then set VendorNoText1.ReadOnly to True.
Setup viewEditVendors.ToolBar.Buttons:
Setup viewEditParts.Columns:
Setup viewEditParts.Form. Set PartNoText1.ReadOnly
and VendorNoText2.ReadOnly property values to True.
Setup viewEditParts.ToolBar.Buttons:
Create viewEditVendors.OnApplyUpdates event handler to send Delta
of changes to BusinessServices component for data resolving. This
event handler will also perform error reconciliation:
Run application in a web browser and try to explore its reach features.
Switch to Edit tab...
... click on Techniques link...
.. then click Underwater Diver Vehicle link...
In this advanced example you've learned how to build web-enabled data
entry screens that are accessible in modern forth generation browsers.
Powerful data management of ASP Express enables transactional data
updates with optimistic locking in multi-user environment. Built-in master-detail
support makes a snap complex User Interface design.
While developing this example we have implemented several methods of IPresentationServices
interface that expose different pieces of presentation logic incorporated
in our component. We have been running this methods from different ASP
scripts.
|