Date post: | 12-Nov-2014 |
Category: |
Documents |
Upload: | manipfizer |
View: | 170 times |
Download: | 15 times |
Welcome to the Oracle Forms Developer 9i tutorial. The objective of this tutorial is to let
you to familiarize yourselves with the forms development process. We will be creating a
form with the same functionality as the sample form you have seen in class. Please read
Chapter 1 from your lab manual before you start this tutorial. Open the SQL window and
log into your account. Type in the following command: select * from tab; Note: 'tab' is a
table that stores names of all tables in your account.
We will use the following tables in the tutorials.
S_ORD
S_CUSTOMER
S_ITEM
S_EMP
S_PRODUCT
Start the OC4J instance before you proceed. Remember to SAVE your work at regular
intervals.
FORMS I
Create & Customize a data Block: You will start with creating a Data Block
using Data Block Wizard.
create & Customize A Canvas/Layout: You will at fist learn to create a layout for a
Data Block using Layout Wizard. Then you
will get to know some layout customization
: Initial Values, Radio Buttons, Check Box.
FORMS II
CONNECTING two DATA BLOCKS: Then you will learn how to create a Master-Detail relationship between two Data Blocks.
Triggers: You will know to use a WHEN-BUTTON-
PRESSED Trigger to save information. Also,
you will know to customize a Data Block using a Control Block
List of Values (LOVs): You will learn how to use List of Values
(LOVs) to display dynamic information.
Auto Generated Primary Keys: You will learn to generate Primary Keys by
creating and calling Sequences.
FORMS III
Program Units and Calculated Values: You will know to use a Program Unit to
generate Calculated Values .
Alerts: You will know about Alerts and how to use
them in forms.
More Triggers: You will learn more about triggers .
Advanced Topics: You will get to know some advanced topics:
switching between canvas/blocks,
close a window, adding a graphic,
clearing a form, saving a form,
delete a record, and displaying an error.
Welcome
Start Oracle 9i Forms Builder.
** Note that "MODULE1" may have a different number like "MODULE2", this does not
affect the assignment. **
Change the name of your form by clicking two times on the "MODULE1" until it is
highlighted then type "SAMPLE"
Data Block Wizard
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.
Make sure that the Check boxes for "Current User" and "Tables" are checked. If you
are creating a data block based on a View then the "Views" check box has to be checked.
This will show you the list of all the tables in your account. We will first create a data
block based on the S_ORD Table. Select that table from the list and click "OK"
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.
Layout Wizard: Create a Layout for the Master Block.
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.
What are these layout styles? How do I decide which one to use ?
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.
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"
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.
Customizing a Canvas / Layout
(a) Set Initial Values
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$$
Close the property palette.
What does $$date$$ do?
Answer: $$date$$ sets the initial value of the Order Date field to the Current System
Date.
Create a Radio Button
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
PROPERT
Y
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:
Create a Check Box
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:
The completed form TUT1 is available here
Start with TUT1.fmb
Master-Details Relationships
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 * from user_constraints where constraint_name = 'S_ITEM_ORD_ID_FK';
We will now create a data block for the "Detail" table : S_ITEM
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.
Important: Understanding the foreign keys. Click here for a quick presentation to
understand the role of foreign keys in a relational database.
Note: In some cases a detail block may have more than one Master Blocks. In such a
scenario press the "Create Relationship" button again and select the other foreign key
constraint. The "Master Data Blocks" field in the above dialogue box will then have two
blocks listed.
What happens if I create S_ITEM (detail) block first and then the S_ORD (master)
block? In other words is the sequence in which data blocks are created important?
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"
Note: After you create the detail block associated with the S_ITEM table use the Wizard to display multiple
rows of S_ITEM on the canvas. Use a tabular display to display multiple rows.
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:
The S_ORD gets a relations item called "S_ORD_S_ITEM" which documents the
foreign key relation between the two blocks. Double Click on the icon next the the
relation and open the Property Palette to verify the Join Condition.
"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