We will use the following tables in
the tutorials.
Start Oracle 9i Forms Builder.
** Note that "MODULE1" may have a different number like "MODULE2", this does not
affect the assignment. **
Right Click "SAMPLE" under Forms.
Select the Data Block Wizard
Select "Table or View" and Click
"Next"
Note:
"Table or View" lets you create data
blocks based on a table or a view
created on the Oracle Database Server.
You will now see the following
dialogue box. Click on "Browse". A small
"Connect" box appears. Enter your Login
information and click "Connect".
Once you connect to the Oracle
Database Server you will see the
following screen.
You will now see all the columns of
the S_ORD table under "Available
Columns". Click the ">>" sign to select
all of them to "Database Items". Click
"Next" to proceed.
We will retain the table name "S_ORD"
as the name for the new data block.
Click "Next"
We will create a Layout later. Select
"Just create a data block" and click
Finish.
A new data block called "S_ORD" has
been created. Go to the object navigator
(F3) to check this. Before we proceed
lets save the file. Click Twice (not a
double click!) on "MODULE 1" and change
the name of the form to "SAMPLE". Save
the form (CTRL +S). The figure below
shows how the data block in the Object
Navigator window.
Note:
Forms are saved as *.fmb files on
the local machines. You may want to save
them on a floppy as well.
Right-Click the icon for S_ORD data
block in the OBJECT NAVIGATOR. Select
"Layout Wizard". This will bring up the
Welcome screen. Click "Next"
In the next dialogue box select "(New
Canvas)". The drop down menu for TYPE
shows various canvas layout styles. At
this moment we shall use the simplest of
them all : Content.
Answer: Form layout style is well-suited
for a single-record block, while tabular
layout style, which is a matrix display,
is better-suited for a data block that
displays multiple records. In our case
one canvas can be used to place one
order hence the order data block : S_ORD
will have a form layout. On the other
hand a single order can have more than
one items on it. Thus the same canvas
will have multiple records for item data
block and hence we will use tabular
layout for S_ITEM data block.
The next dialogue box asks you to choose
the items from the block that will
actually be visible on the canvas.
Select all of them by pressing the ">>"
button. Click "Next" to proceed.
Type in : "ORDER DETAILS" in the
frame title field. Click "Next". Click
"Finish" on the next page. The layout
wizard will now create a default layout
for you. Also in the OBJECT NAVIGATOR
under CANVASES you will find a new
canvas object with a default name. Click
Twice (not a double click) on it and
rename it to "ORDER_CANVAS". The Layout
will look as shown below:

Note:
Object names cannot contain
spaces. ORDER CANVAS is not a valid
name.
Open the PROPERTY PALETTE for the the
Order Date Field. This can be done by a
double-click on the Order Date Text Item
OR by a right click on the Order Date
Text Item and selecting "Property
Palette" from the menu.

The Property Palette allows you to
change all aspects of an particular
item. Take some time to go through the
entire property palette for the Order
Date Item before you proceed.
Note: The Blue column on the left of the
Property Palette contains the names of
all the property field. The values for
the fields are entered to the right.
Find the property field called "INITIAL VALUE" and enter the following :
$$date$$
Answer: $$date$$ sets the initial value
of the Order Date field to the Current
System Date.
Go to the Object Navigator and expand
the S_ORD block to see the items
contained within the block. Double -
Click on the "PAYMENT_TYPE" icon to
bring up its PROPERTY PALETTE. 
Click on the drop down menu for the ITEM
TYPE field and select Radio Group as the
ITEM TYPE.
Type CASH as the field value for INITIAL VALUE and close the PROPERTY
PALETTE.

Note: Setting "CASH" as the initial
value for the radio button makes CASH the default option.
In the Property Palette expand the "PAYMENT_TYPE" item. Click on the "Radio
Button" field and press the Green "+" in the Object navigator toolbar TWICE
(since we have CASH and CREDIT as our options). You will see two radio
buttons created in the Object Navigator with default names like
"RADIO_BUTTON11" and "RADIO_BUTTON12". Rename them as "CASH" and "CREDIT".
Open the PROPERTY PALETTE for the "CASH" radio button by a double click on
its icon. Change values of the "Label" and "Radio Button Value" as shown in
the picture below
Note: Radio button value is the actual
data that gets saved to the database.
Repeat to create the Credit Radio Button. Set Radio Button Value to
CREDIT.
Open ORDER_CANVAS and drag the two radio buttons to a visible place. You
will find both the buttons in the top left corner of the canvas.
While creating the database tables for this project the following constraint
was added : CONSTRAINT s_ord_payment_type_ck CHECK (payment_type in ('CASH',
'CREDIT')),
(above is not an complete statement!)
This means that the values returned by the radio buttons can be "CASH"
or "CREDIT". This is a hard coded constraint. If instead of "CASH" you input
"Cash" as the radio button value, you will get the following error:

In the OBJECT NAVIGATOR double click on the icon for "ORDER_FILLED" to open
its PROPERTY PALETTE.
Select "CHECK BOX" as the value for "Item Type". This changes the
ORDER_FILLED field from a TEXT ITEM to a CHECK BOX.
Under the Functional properties of the ORDER_FILLED field there field called
"Value when checked" and "Value when unchecked". Insert the following values
:
for "Value when checked" : Y
for "Value when unchecked": N
While creating the database tables for this project the following constraint
was added: CONSTRAINT s_ord_order_filled_ck CHECK (order_filled in ('Y',
'N'))
(above is not an complete statement!)
This means that the values returned by the check box can be "Y" or "N".
This is a hard coded constraint.
Under the "Check Box Mapping of Other values" select "UNCHECKED" from the
drop down list
Set INITIAL VALUE of the Order Filled button as "N".
Note:
The Property Palette looks something like this:

When two tables are linked together by a
foreign key constraint one of them is a
"Master" and the other one is the
"Detail" table. To understand this
concept consider the two tables we are
currently working with: S_ORD (Orders
Table) and S_ITEM (Items Table).
The foreign key ORD_ID field in S_ITEM
references the ID field in S_ORD. Thus
S_ORD is the Master table and the S_ITEM
is the detail table. These two tables
are linked together by a foreign key
constraint named "S_ITEM_ORD_ID_FK".
To view the details of this constraint
type in the following command in the SQL
window.
Select
"Data blocks" by clicking it once in the
object navigator. Then click the ' + '
Sign in the Object Navigator tool box on
the left
"New Data Block" dialogue box
appears. Make sure "Use data block
wizard is selected" and press "OK" This
will start the Data block wizard again.
Click "Next" to leave the Welcome
Screen.
Select "Table or View" and Click
"Next"
Click on "Browse". Select "S_ITEM".
You will now see all the columns of
the S_ITEM table under "Available
Columns". Click the ">>" sign to select
all of them to "Database Items". Click
"Next" to proceed.
You will now see a New Dialogue box
that has two buttons on it : "Create
Relationship" and "Delete Relationship".
Press "Create Relationship" and the
following box appears :

The data block wizard realizes that the
data block being created is based on a
detail table. It gets this information
from the foreign key constraint "S_ITEM_ORD_FK"
and asks you to confirm the same. Click
"OK". The dialogue box shows the foreign
key relationship as the join condition.
Answer: No, the sequence in which you
create data block is not important. In
case you create S_ITEM block first and
then create the S_ORD block make sure
that you select the S_ITEM data block in
the OBJECT NAVIGATOR and right click to
select "Data Block Wizard". This is
called "Starting the Wizard in
Re-Entrant Mode". Select the "Master -
Detail" Tab and Press the "Create
Relationship" button.
We will retain the table name "S_ITEM"
as the name for the new data block.
Click "Next"
We will create a Layout later. Select
"Just create a data block" and click
Finish.
A new data block called "S_ITEM" has
been created. Go to the object navigator
(F3) to check this. The OBJECT NAVIGATOR
will look like this
Note:
"ON-POPULATE-DETAILS" and "ON-CHECK-DELETE-MASTER" are two triggers that forms
developer automatically creates to facilitate co-ordination between related data
block. To learn more about these trigger Press Help (CTRL+H).
Create a block
corresponding to the S_CUSTOMER table.
It will be a master block and the detail
block will be associated with the
S_ORDER table since the S_ORDER table
has a foreign key that references
S_CUSTOMER.
Before we proceed:
You should now have three data
blocks and two relations items in your
forms file. Please save the file and
proceed. The Object Navigator looks
something like this at this stage.
Saving data in a
table
Next, we will create a button
which will allow us to save the data
entered in the form in the respective
table (S_ORD). The resulting form will
have minimal functionality. We can
further enhance the form by customizing
it.
Placing a button on the canvas. Click
the "Push Button" icon on the canvas
toolbar (shown below) and then click
once on the canvas.
A new push button with default
properties will be created. Forms
builder will give it a default name like
"PUSH_BUTTON14". You can drag and place
the button any where on the canvas.
Note:
The Push Button is automatically
placed in the same data block (S_ORD) as
the data block on the current canvas.
On the canvas double click on the Push
button to open its PROPERTY PALETTE. In
the value for the "LABEL" field enter
"SUBMIT" or "SAVE" to indicate the
function of the button.
6(a).3
Try running the form. Click
here for instructions for running a
form. Try clicking on the Push Button -
nothing happens. This is because we
still have not told Forms builder what
to do once the button is clicked. This
is done entering PL/SQL code in a
trigger. Please refer to the lab manual
for more information on triggers. At
this moment it is enough for you to know
that triggers are blocks of code that
are executed when a particular event
occurs. In this case we need certain
code to be executed when the "Submit"
button is pressed. So we use what is
called a WHEN-BUTTON-PRESSED trigger !
Here is how the form would look:
Note:
The green back ground is the default
color for the form. This can be easily
changed using the canvas toolbar, though
at the moment we will not bother
ourselves with such cosmetic details.
Create a
WHEN-PRESSED-BUTTON Trigger
On the ORDER_CANVAS right click on the
"Submit" Button. Select "PL/ SQL Editor"
from the menu. This will bring up a list
of triggers that can be associated with
the push button. Select
"When-Button-Pressed" from this list.
Once you select the trigger forms
builder will open a PL/SQL Editor
window. This is where you input PL/SQL
code that has to be executed when the
"Submit" button is pressed. For saving
information through a form we use the
following line of code:
commit_form;
Compile the PL/SQL code by clicking on
the first button on the toolbar for the
PL/SQL Editor.

Note:
You should get a "Not Modified -
Successfully Compiled" message as shown
in the picture above. Any errors
generated during the compilation process
will be shown in the bottom part of the
editor window.
Close the PL/SQL Editor window and run
the form.
Since CUSTOMER_ID and SALE_REP_ID must
refer to actual customers and sales
representatives, we will enter these
values after looking up values in the
databases from S_CUSTOMER and S_EMP
tables.
Enter data as shown in the picture below
and click on the "Submit" button.
Note:
You will get the following
message at the bottom of the applet
window:
Create a Control Block and a Non Base Table Item
So far we selected a database table to
create a data block by selecting a
particular table in the database schema
and then selected the columns from that
table to be ITEMS in the data block.
Later using the LAYOUT WIZARD we placed
these items on the ORDER_CANVAS. These
items are called "Database Table Items".
We might need to have other items on the
canvas to make the form more user
friendly. Suppose we wanted to display
customers and sale representatives
information in an order form and these
items are not included in S_ORD. They
are called "NON Database Table Items".
Forms developer considers all new items
to be "Database Table Items" (default).
This can be changed by opening the
PROPERTY PALETTE of a item and changing
the "Database Item" field to "NO".
Instead
of changing the property of every item
added to the form you can simply create
a "dummy data block" or CONTROL BLOCK
and add these items like text boxes,
buttons etc. to this data block.
Select "Data Block" in the OBJECT
NAVIGATOR and press the "+" button to
add a new data block.
Select "Build Data Block Manually" in
the next dialogue box and click "OK".
You can now see a new data block with no
items. Rename the Data block to "CTRL_S_ORD"
- indicating that it is a control block
for the S_ORD data block.
To add a new item to the CTRL_S_ORD
block select ITEMS node and press the
"+" sign. This will create a new text
item with a default name. Rename the
item as "CUST_NAME" - we will use this
text item in the next stage of the
tutorial (Dynamic Lists : LOV's).
Repeat to create two more text items :
CUST_PHONE and SR_NAME (Sales Rep Name).
Repeat to create two more text items :
SR_BUTTON and CUST_BUTTON. Open the
PROPERTY PALETTE for these two items and
change the value of the "Item Type"
field to "Push Button". Also change the
labels of these items to "Select Sales
Rep" and "Select Customer".
The OBJECT NAVIGATOR looks like this:

For the next part of the tutorial we
need to place these items on the
ORDER_CANVAS. This can be done by simply
opening the PROPERTY PALETTE for each of
these items and setting the value of the
"CANVAS" field to "ORDER_CANVAS".
Rearrange the items on the canvas as
shown :
|
The completed form TUT2 is
available
here |
Create Dynamic
Lists: List of Values (LOVs)
There are two types of lists we can use
: Static Lists and Dynamic lists. Static
Lists are lists of item that do not
change frequently - these are
implemented using simple drop down boxes
(ask your GA to show you how to create a
Static List). Typically a static list
would be a list of all States in the US,
or list of semesters for the next couple
of years etc. Dynamic lists on the other
hand are based on data in the database
tables. The data is frequently changing
and the most up-to-date data has to be
presented to the user every time he /
she asks to see the dynamic list. For
e.g. a list of items in an warehouse
that has gone below its re-order level.
These dynamic lists are based on SQL
queries and show the results of the
query every time the user calls the
dynamic list. We shall start with
creating a dynamic list (called LOV /
List of Values) for all the customers in
the database - this data is frequently
changing as new customers are added and
old customers are deleted.
Stage 1 Create LOV Using SELECT
Statement
Select "LOVs" in the OBJECT NAVIGATOR
and click on the "+". Choose to build a
LOV using the LOV wizard.
Select "New Record Group based on a
query" and click "NEXT". The next screen
will prompt you to enter the query on
which this LOV is based.
Enter the query shown in the picture
below and press "Check Syntax" to ensure
that the query is correct. Click "OK"
and then "Next".
select id, name, phone from s_customer
order by name

Note:
Though all SQL statements end with a
semi-colon (;) the SQL statements
entered in the LOV wizard should NOT be
terminated with a semi-colon (;).
In the next step Click on the ">>" to
select all items as LOV items. Click
"Next" and you will see the following
screen.

Click on the "Return Value" column for
the ID field and press the "Look up
return item" button you will see the
following dialogue box.

Select S_ORD.CUSTOMER_ID as the return
item. Repeat step 6(d).5 to specify
return items for NAME and PHONE as
CTRL_BLK.CUST_NAME and
CTRL_BLK.CUST_PHONE respectively.
Click "NEXT" when done.
Note:
Specifying Return Values for LOV items
is a very important step. Ask your GA to
explain what a return value does. Try
the exercise below to find what Return
Values do.
After we are done with this part of the
tutorial (creating dynamic lists) open
the LOV wizard in re-entrant mode by
right clicking the LOV and selecting "LOV
Wizard". Delete the return item
specified for CTRL_BLK.CUST_PHONE.
Click finish and run the form - observe
what happens to the customer phone
field.
Answer: Repeat the entire procedure to
create a LOV to select Sales
Representative Name and display his /
her ID and name on the form. Hint : Use
the following SQL code to create the LOV:
select id, last_name from s_emp order by
last_name
Specify a appropriate title for the LOV:
"Select Customer name". This appears on
top of the LOV. Retain other default
values - these can be changed later.
Click "Next" till you reach the end of
the wizard. We will retain all default
values. Click "Finish" on the last
screen - a new LOV with a default name
will be created in the OBJECT NAVIGATOR.
Rename the LOV as "CUST_LIST".
Note:
Creating a LOV is the first stage of creating a dynamic lists.
Next we have to insert code to call the
LOV.
Stage 2 Call LOV Using
WHEN-BUTTON-PRESSED Trigger
Open ORDER_CANVAS and right click on the
"Select Customer" button. Choose "PL/SQL
Editor" from the resulting menu.
Choose WHEN-BUTTON-PRESSED trigger from
the list and insert the following code
in the PL/SQL editor:
declare
lov_return boolean;
begin
lov_return := show_lov('cust_list');
end;
NOTE:
cust_list is the name of the LOV.
Compile the code and close the PL/SQL
editor window. Run the form to see the
LOV at work.
Note:
You may need to open the LOV wizard
again to modify the visual attributes of
the LOV.
Before we proceed:
We frequently need to refer to data in a
particular text item. The syntax for
referring to a particular item is as
follows:
:block_name.item_name
Thus the item "TOTAL" under the S_ORD
block is shall be referred to as:
:s_ord.total
Auto Generate Primary Key
Stage 1 Create a Sequence
Open the SQL*Plus window and enter the login and account information.
Once you have logged in enter the following command:
create sequence ord_pk start with 1 increment by 1;
Stage 2 Call a Sequence
Note: We need to use a few lines of
code in order to call the sequence and tell it to insert the new sequence
value. Before we do that we have to decide when this code should be
executed? We want to make sure that a new primary key is generated only
when the customer has submitted the final order. This can be done either by
incorporating the code into the WHEN-BUTTON-PRESSED trigger of the "Submit"
button or by using a BLOCK-LEVEL-TRIGGER called PRE-INSERT trigger. This
trigger is fired just before forms developer saves data to the table. Since
we have used the WHEN-BUTTON-PRESSED trigger before lets experiment with
the PRE-INSERT trigger.
In the OBJECT NAVIGATOR expand the S_ORD data block. You will find the
"Triggers" node right under the data block name. Select the node and click
"+" to add a trigger.
Select PRE-INSERT from the pop-up list and click OK. The PL/SQL editor for
the trigger will open up. Use the following code :
select ord_pk.nextval into :s_ord.id from dual;
The OBJECT NAVIGATOR for the S_ORD block looks something like this:

Note: Dual is a dummy table
used to complete the "From" part of a SQL statement. The required property
for the id text field must be changed to "No." If this field is not changed
the form will force the user to enter a value for the id field and the
field will not populate.
Compile the code and close the editor window. Run the form to see how
auto-generated primary key works.
Note: In order for the id field to
populate correctly an existing customer id and sales rep id must be entered
in their respective fields.
|
The completed form TUT3 is
available
here |
The value in Shipping cost will be added to the total cost of the order and the
sum will be displayed in the GrandTotal Field. Create the Shipping and
GrandTotal text fields as we have done before, place it on ORDER_CANVAS and
proceed to Step 1.
Calculated Values
We use program units when we want to execute pieces of PL/SQL code.
S_ORD has an field TOTAL. We refer its as :
:S_ORD.TOTAL
We will need to add two text items called: SHIPPING and GRANDTOTAL to
the control block CTRL_BLK. The value of SHIPPING will be entered by a
user and GRANDTOTAL will be calculated.
Stage 1 Create a Program Unit
Open the OBJECT NAVIGATOR and select the PROGRAM UNIT node and click "+"
to add a program unit. You will see the following dialogue box. Enter
the name shown in the picture and click OK:

A PL/SQL Window will automatically open up with the following code in it
:
PROCEDURE calc_order_details IS
BEGIN
END;
Enter the code given below.
PROCEDURE calc_order_details IS
BEGIN
:ctrl_s_ord.grandtotal := :ctrl_s_ord.shipping + :s_ord.total;
END;
Compile the code and close the PL/SQL Editor Window.
Stage 2 Call the Program Unit
Right click on the SHIPPING text item from the ctrl_s_ord block
(referred to as :ctrl_s_ord.total) and click on the PL/SQL editor to
bring up the list of possible triggers.
Select a WHEN-VALIDATE-ITEM trigger and enter the following code :
calc_order_details;
This calls the program unit and executes the PL/SQL code in it.
What
is validation ? When is the
WHEN-VALIDATE-ITEM trigger fired?
Answer: Validation is a process through
which forms builder checks the whether
the data being entered in a text box
matches with the data type defined for
that item. Every time the validation
process takes place the
WHEN-VALIDATE-ITEM trigger is fired.
You may want to disable the total cost
(:s_ord.total), and Grand Total (:s_ord.grandtotal)
so that the user cannot modify the
values in these fields. This can be done
by opening the PROPERTY PALETTE of the
items and turning the value of the
ENABLED field to NO.
Create Alert
Alerts are simple mechanisms to require
user confirm the requested action.
Alerts are used to avoid mistakes made
by the user. For e.g. when you ask for a
document to be deleted, the windows
operating system asks if you are sure -
this is a alert that requires the user
to confirm his action. We shall see how
alerts can be incorporated into forms.
Let us add a alert to the form that asks
the user to confirm his request to
submit an order. (A alert has to show up
after the user has pressed the "Submit"
button.)
Stage 1 Create an Alert
Select "Alerts" in the OBJECT NAVIGATOR
and click on the "+". A new alert with a
default name will be created. Change the
default name to "SAVE_ALERT".
Double click on the icon to open the
PROPERTY PALETTE for the alert. Change
the field values as shown in the picture
below.
Note:
Your alert is now ready to be used. The
next stage is to call the alert using a
PL/SQL code.
Stage 2 Call an Alert
Since we want the alert to be called
when the user presses the "Submit"
button we have to include code for the
Alert in the WHEN-BUTTON-PRESSED
trigger.
Open the PL/SQL editor for the
WHEN-BUTTON-PRESSED trigger associated
with the Submit button. This can be done
by opening ORDER_CANVAS and right
clicking on the Submit button. Select
"PL/SQL Editor" from the menu.
We already have the following code in
this trigger:
commit_form;
We will modify the code in this trigger
as shown below:
declare
alert_id alert;
choice number;
BEGIN
alert_id := Find_Alert ('SAVE_ALERT');
choice := Show_ALert(alert_id);
IF choice = ALERT_BUTTON1 THEN
commit_form;
ELSE null;
END IF;
END;
Note:
Please note the the commit_form; code
has now been placed INSIDE the
If-THEN-ELSE LOOP.
Compile the code and close the PL/SQL
editor window. Your Alert has now ready
to be used. Run the form and see how the
alert works. Click here for instructions
for running a form. This is how a alert
looks after the Submit button has been
pressed.

Before we proceed:
We
currently have just one Data Block (S_ORD)
on the ORDER_CANVAS. The form as a whole
is not yet complete , we will add S_ITEM
to the same canvas.
|
The completed form TUT4 is
available
here
|
Create Multiple
Data Blocks on the Same Canvas
In the OBJECT NAVIGATOR right click on
the S_ITEM data block and click on
LAYOUT WIZARD. This will bring up the
Welcome Screen. Click NEXT to proceed
Since we want the data block on the same
canvas (ORDER_CANVAS) select that canvas
from the Drop down list and click NEXT.
You will see all the items in the data
block S_ITEM under the "Available Items"
column. Select all items EXCEPT
QUANTITY_SHIPPED to the "Displayed
Items" column. Click NEXT once the
dialogue box looks like this :

Note:
We are not including QUANTITY_SHIPPED as it is currently out of the scope
of the tutorial. It involves working with the S_INVENTORY table which we
will not be using for the purpose of this tutorial.
Change the names of the label under "Prompt". The default name given to the
item is always the column name in the base table which may not always be useful
to the end user. Leave the width and heights unchanged. These can be changed by
simply stretching the items on the canvas. Click "Next"
Select "TABULAR" as the layout style and Click NEXT
Note:
It would be interesting to note
that the tabular layout allows a better organization of multiple items. This is
in line with the ER-Diagram where we have a One-Many relationship between S_ORD
and S_ITEM tables.
Input "Items for the order" in the FRAME
TITLE field. Also choose to display 7
items with a distance of 3 between each
record. Click NEXT when the dialogue box
looks like this :

On the next screen click "FINISH' to
close the layout wizard. ORDER_CANVAS will be opened with the newly added data
block S_ITEM on it. Here is how it looks :

Note:
All items in the above canvas belong to the same order. Thus to satisfy the
foreign key constraints :s_item.ORD_ID has to be same as :s_ord.ID. We will have
to add a line of PL/SQL code to do that. We have to transfer the automatically
generated primary key for S_ORD to :S_ITEM.ORD_ID
before forms builder inserts the
records in the database tables.
Expand the S_ORD data block in the
object navigator. Expand the TRIGGERS
node under the S_ORD data block and
double click on the icon for the
PRE-INSERT Trigger. This opens the
PL/SQL editor with a line of code we
have enter previously:
select ord_pk.nextval into :s_ord.id
from dual
Add the following line AFTER the above
line : :s_item.ord_id := :s_ord.id;
Note:
The second line of code (STEP 1.9) will
copy the auto generated key in :s_ord.id
to :s_item.ord.id.
On the ORDER_CANVAS double click on the
ORD_ID column to open the PROPERTY PALETTE. Change the value of the "Enabled"
field to NO.
Run the form to see the results of your
work. Click
here for instructions for running a
form. Enter the data shown in the
picture below and submit the order:

Start with TUT4.fmb
- Disable user data entry into specific
fields, e.g., GRANDTOTAL in CTRL_BLK and ID in the S_ORD block.
- Customize the Sales Rep LOV. Create an
item COMMISION_PCT in CTRL_BLK and add it to the canvas. The user will enter
a value here. Modify the LOV query that selects values from the S_EMP table
to only select sales representatives whose commission is below the user
specified input. You will also need to add this item COMMISSION_PCT (from
the S_EMP table) to LOV Columns so that it is displayed when you run the LOV.
- Create a new canvas “Customer
Maintenance” to display and modify Customer information. Create a new canvas
and use the layout wizard to attach the S_CUSTOMER block to the new canvas.
Use the GO_BLOCK command to switch from one canvas to the other. The canvas
will not be populated unless you use the EXECUTE_QUERY macro. You will need
to create a PRE_QUERY trigger in the S_CUSTOMER block that copies the
customer id from the S_ORD block (:S_ORD.CUSTOMER_ID) to the ID field in
S_CUSTOMER block (:S_CUSTOMER.ID). You may need to delete the Master Detail
relationship between the S_ORD and S_CUSTOMER blocks to get this to work
correctly.
- Display items belonging to an order.
Recall that there is a master detail relationship between the S_ORD and
S_ITEM block. Display the S_ITEM block on the same canvas as the S_ORD
block. As you scroll through each order, the items in the order will be
displayed.
- Create a new item for a new order.
To make sure that the order id from S_ORD is entered into the ORD_ID field
in the S_ITEM block you can use the property palette “Copy Value from Item”
function or you can use a PRE_INSERT or PRE_QUERY trigger. The user has to
manually enter a new item 1, 2, 3, etc. or you can use a program unit to
calculate this value. Please note that the TOTAL is not calculated
automatically!
|
The completed form TUT5 is
available
here
|
Triggers
Triggers are PL/SQL program units that
are executed when a certain event
occurs. Oracle recognizes the occurrence
of an event, typically INSERT, DELETE,
BUTTON PRESSED, CURSOR IN AN TEXT ITEM
etc., and executes the program unit.
Triggers
are typically classified depending on the level of operation, timing of
operation etc. Based on the level of operation triggers are classified as:
1.
Form Level Triggers
2.
Block Level Triggers
3. Item
Level triggers
This
classification becomes more evident in the object navigator window (given below
is the object navigator for sample.fmb)

Oracle
classifies
triggers
in
the
following
categories
(HELP
gives
a
lot
of
details!
):
):
-
Block-processing triggers
Triggers that fire in response to record management events at block level.
-
Interface event triggers
Triggers that fire in response to events that occur in the form interface
-
Master-detail triggers
Triggers that enforce co-ordination between detail block and master block
-
Message-handling triggers
Triggers that fire in response to error / informational messages generated
by Form builder.
-
Navigational triggers
Triggers that fire when the user moves between forms / items on a canvas.
-
Query-time triggers
Triggers that fire when a query is executed in a block
-
Transactional triggers
Triggers that fire when the form interacts with the database.
-
Validation triggers
Validation is a process where Oracle ensures that the data / record being
inputted is in conformance with the details in DDL statements. (Such as
validating whether an input for a text item is an INTEGER) Validation
Triggers are triggers that are fired during the validation process for item
or record.
Someome< of the triggers used in sample.fmb (and ones that are used
frequently) are discussed below. Typically these are the triggers where you
will provide the PL/SQL code:
1. ON-CLEAR-DETAILS: S:
Definition Level form, block
Type: Master – Detail Trigger
Action: Used for coordination between Master / Block when form builder tries to
delete a record from a block which is a DETAIL block in a master-detail
relationship.
Action in Sample.fmb: Fires stored procedure (procedure provided by Oracle)
called CLEAR_ALL_MASTER_DETAILS.
2. WHEN-NEW-FORM-INSTANCE: CE:
Definition Level form
Type: Navigational trigger
Action: Executes code at form start-up
Action in sample.fmb: Sets the window size.
Note: Other similar triggers are WHEN-NEW-BLOCK/RECORD/ITEM-INSTANCEANCE
3. ON-CHECK-DELETE-MASTER:
Definition Level form or block
Type: Master – Detail Trigger
Action: Fires when there is an attempt to delete a record in a master block.
Checks if details items are associated with the master record. Does not
allow deletion of master if details are found.
Action in sample.fmb (trigger in ORD_BLK): Checks if there are records in
ITEM_BLK are linked to items in ORD_BLK.
4. PRE-INSERT:
Definition Level form or block
Type: Transactional Trigger
Action: Executes code before a record in inserted in to the database.
Action in sample.fmb (ord_blk): Generate new order number (PK) using
sequences.
Action in sample.fmb (item_blk): generates new item_id by incrementing max (item_id)
in the current order. (Please refer to the actual trigger for a more
detailed description).
5. PRE-QUERY:
Definition Level form or block
Type: Query Time Trigger
Action: Executes code before the SELECT statement (Query) is sent to the
database to search for matching records. Typically maybe used to alter the
SELECT statement (Query). E.g. A query is supposed to return records, which
can be sorted according criteria A, B, C (mutually exclusive options
implemented using Radio buttons). When the user selects one of the criteria
the order by clause of the SELECT statement (Query) has to be altered
accordingly. This can be done during the PRE-QUERY trigger execution.
Action in sample.fmb: Checks if customer name is entered. If customer name
is present it fills the customer_id field with appropriate number and
allowing query based on customer name.
6. POST-QUERY:
Type: Query Time Trigger
Definition Level form or block
Action: To execute more SQL code that might have to use the results returned
by the QUERY.
Action in sample.fmb: Executes program units: get_customer_name,
get_sales_rep_name;
7. WHEN-VALIDATE_ITEM:
Type: Validation Trigger
Definition Level form, block, or item
Action: Execute PL/SQL code to supplement the default validation process.
(Validation process is defined above)
Action sample.fmb (associated with Customer_id): Execute program unit
get_customer_name. After the input entered in the customer_id field has been
validated, the program unit will get the corresponding customer name.
8. WHEN-BUTTON-PRESSED:
Type: Interface Event Trigger
Definition Level form, block, or item
Action: Executes PL/SQL code when a button is pressed! ! ! ! duh!
Action in sample.fmb (Customers Button): Launch customer_lov.
9. PRE-TEXT-ITEM
Type: Navigational Trigger
Action: Executes PL/SQL code as soon as the cursor goes to the text item.
10. POST-TEXT-ITEM
Type: Navigational Trigger
Action: Executes PL/SQL code after the cursor moves away from text item.
Advanced Topics
Switch Between Canvases/Blocks
If you want to switch from one canvas to another, you can use the command
go_block. For example, when you run Sample.fmb, pressing the button labeled
'Customer Maintenance' will bring you to a different canvas for customer
maintenance.
Examine Sample.fmb in the Object Navigator, and you will find a button
named customers_maintenance in the Control block. Its WHEN-BUTTON-PRESSED
trigger has the following code:
& go_block('cust_blk');
The command go_block('name-of-block') takes you to a block, which is 'cust_blk'
in this case. Note that the button is associated with the ord_can canvas and
cust_blk is associated with the cust_can canvas. Therefore when the trigger
is fired, the application will switch from ord_can to cust_can.
However, if you only have the go_block command, it will bring you to the
new canvas and nothing else. In the Sample.fmb, we want to display the
customer information in the customer canvas. Therefore, we should add the
following code after the go_block command:
execute_query;
Also, add a pre-query trigger to the cust_blk like this:
:cust_blk.id := :ord_blk.customer_id;
This will make sure the customer id in the ord_blk is carried over to
cust_blk.
Close a Window
Sometimes you need to close a window. In the previous example, after you
click the 'Customer Maintenance' button, there are two windows open. We
prefer not having more than one window open at the same time. Because
multiple windows mean multiple data blocks, and multiple data blocks usually
cause trouble when you try to save the form. (We will explain it later.) Now
if you press the 'Close' button, you will close the customer window and
return to the ord_can canvas. Examine cust_blk in the Object Naviagtor, you
will find the WHEN-BUTTON-PRESSED trigger of the 'Close' button has the
following code:
Close_Win2; ;
Note that Win2 is associated with cust_can. This command will close Win2,
so that the canvas and data blocks in it will also be closed. Since the
other window is the only open window at this time, you will be automatically
brought to it.
The difference between go_block and close_win: It seems that both
commands can bring you to a different window. However, go_block simply
switches between windows. It doesn't close anything. In contrast, close_win
cannot navigate to a specific window. It will automatically bring you to the
next available window.
Add Graphics to a Form
You can add graphic images to your application. To do this, select a
canvas in the Object Navigator, and click on Edit \ Import \ Image. This
will import into the form a file that contains a graphic image. You can edit
its layout in the Layout Editor.
Clear the Values in a Form
There are two commands CLEAR_FORM and CLEAR_BLOCK. Basically, CLEAR_FORM
will clear the whole form, no matter which data block the button belongs to.
In contrast, CLEAR_BLOCK will only clear the data block which the button
belongs to. Please download ClearTest.fmb
here and examine the two buttons CLR_FM
and CLR_BLK in block S_ITEM.
Save Information within a Form
When we want to create a SAVE
button to save information, we use the following code in the WHEN-BUTTON-PRESSED
trigger:
COMMIT_FORM;
If your form is simple and has only one data block
associated with one table, this usually works correctly. However, if your form
has two or more data blocks or if you have multi-record data blocks
corresponding to multiple rows of a table, then the COMMIT_FORM command will try
to insert one or more tuples into multiple tables simultaneously. Depending on
the "logic" of your application, the form may give errors.
How to Debug
If you are having problems with inserting records into a table using
COMMIT_FORM,
(1) Simplify your application by reducing it to
one data block and verify that it works.s.
(2) Add more data blocks to the form.
(3) Start with inserting new data to the FIRST data
block (the one on the top of the data block list in the Object Navigator)
(4) Avoid multiple SAVE buttons and COMMIT_FORM
commands in one form.
(5) Examine
SaveTest.fmb to see how the two save buttons work.
Unable to insert tuples into a table?
If some attributes in a table have NOT NULL constraints, inserting a
record that has NULL values for those attributes will give errors. The
solution is to either drop the NOT NULL constraints in the table definition
or make sure that you provide a value for those attributes. ;
Delete a Record Within a Form
Create a button labeled DELETE and add a WHEN_BUTTON_PRESSED trigger with
the following code:
delete_record;
commit;
This will delete the current record. However, if you have more than one
data block in the form, it is more complicated. Basically, DELETE_RECORD
will delete the current record in the data block which the button belongs
to. If you have a tabular form, it will delete the first record by default.
And if you want to delete another record, you can move your cursor to that
record and press the DELETE button. Most importantly, if you have a
master-detail relationship in your form, in order to delete a parent record
with child records, you have to change the property of the relationship.
Click herere
for an example of the delete record command
Note: To use this sample please login to the
database with the following account info:
s04sample1/abc123
Display Error Messages
If you get an error when you run a form, you can use the Help feature to
display the error by clicking on Help / Display Error on the menu bar. This may
help you debug your form especially when there are multiple data blocks in the
form. For example, the error may actually occur in another table - not the one
which you are trying to insert records into!
Run a Form
Step 1 Start the OC4J instance by selecting
Programs >> Oracle 9i Developer Suite >> Forms Developer >> Start OC4J instance.
Note: Wait till you get the "Containers for
J2EE initialized" message as shown below.

Step 2 Connect to your database account by clicking on File >> Connect (Short
cut : Ctrl + J)
You will be asked for your account information. Your database accounts have been
assigned to your teams.
Step 3 Run the form by clicking on Program >> Run Form (Short cut : Ctrl + R)
Note: The form will start running in the web
browser.
Step 4 To exit the form, click on the "EXIT" button on the toolbar. (Green door
with a blue arrow). You can close the browser window after that