Each item in a block can have its own Number of Items Displayed property, so you can have a single block in which some items are single-record (Detail) and some are multi-record (Summary). When you implement a combination block, most items appear twice, so coordination of the values in these items must be managed. The Synchronize with Item property does this automatically. You control which portion of the block is navigated to in different situations using a field called Switcher. The Switcher field is the first navigable item in the block. When the cursor enters the Switcher, it is immediately moved to the first item in either the Detail or Summary portion of the block.
Setting up the combination block
Create two windows and canvases to hold the different portions of your block. Use the non-mirror items in your block for the Summary portion. Duplicate the items to create the Detail portion. The Detail portion of your combination block should be sequenced first. Thus, when the user does not fill in a required item and tries to commit the block, Oracle Forms positions the cursor in that item in the Detail block.
Setting the item properties
For the mirror items, change the item names to reflect the real item that they are mirroring (for example, name the mirror item of "status" to "status_mir"). Set the Synchronize with Item property, and make sure the Database Item property is set to Yes (if the synchronized items are a base table item).
Set the block-level Number of Records Displayed property for your Summary portion. This will get picked up by the items so long as you do not explicitly set the Number of Items Displayed property. So that your Detail portion items do not get the same value, explicitly set their Number of Items Displayed property to 1.
To prevent the user from tabbing out of the Detail and into the Summary, set the Previous Navigation Item property for the first Detail item, and the Next Navigation Item property for the last Detail item.
To enforce the standard multi-record block navigation behavior of Change Record, call APP_COMBO.KEY_PREV_ITEM in the KEY-PREV-ITEM (Fire in ENTER-QUERY mode: No) trigger of the first navigable item of the Summary portion, and call next_record in the KEY-NEXT-ITEM trigger (Fire in ENTER-QUERY mode: No) of the last navigable item of the Summary portion.
If you are converting an existing block into a combination block, do not forget to change references in any existing triggers to recognize that there are now two instances of every field.
The Drilldown Record Indicator
Add a Drilldown Record Indicator that does an execute_trigger('SUMMARY_DETAIL').
The Record Count Parameter
Create a parameter to store the record count for the portion of the block you are currently in. Name the parameter <block>_RECORD_COUNT, where <block> is the name of the combination block. The APPCORE code depends on this naming standard. This information is used to determine which portion of the block to navigate to. The parameter should have a Data Type of NUMBER and a default value of 2, so that the cursor is initially in the Summary portion. (If you want the cursor to start in the Detail portion, set the default value to 1).
Create a block level WHEN-NEW-ITEM-INSTANCE trigger (Execution Hierarchy: Before) that contains the following code:
:PARAMETER.<block>_RECORD_COUNT :=
GET_ITEM_PROPERTY(:SYSTEM.CURSOR_ITEM,
RECORDS_DISPLAYED);
The Switcher
Create a text item and assign it the property class SWITCHER. It needs to be the lowest sequenced item in the block. Place it at (0,0) on the toolbar canvas (the switcher belongs on the toolbar canvas because whatever canvas it is on paints). Create an item-level WHEN-NEW-ITEM-INSTANCE trigger (Execution Hierarchy: Override) that contains the following code:
IF(:PARAMETER.<block>_RECORD_COUNT > 1) THEN
GO_ITEM('<first Summary field>');
ELSE
APP_WINDOW.SET_WINDOW_POSITION('<Detail window>',
'OVERLAP',
'<Summary window>');
GO_ITEM('<first Detail field>');
END IF;
The Summary/Detail Menu Item
Create a block-level SUMMARY_DETAIL trigger (Execution Hierarchy: Override) that contains the following code:
IF GET_ITEM_PROPERTY(:SYSTEM.CURSOR_ITEM,
RECORDS_DISPLAYED) > 1 THEN
:PARAMETER.<block>_RECORD_COUNT := 1;
ELSE
:PARAMETER.<block>_RECORD_COUNT := 2;
END IF;
GO_ITEM('<block>.Switcher');
This code changes the value in the RECORDS_DISPLAYED parameter so that the Switcher sends the cursor into the opposite portion of the block. It will fire whenever the user chooses "Go -> Summary/Detail."
Create a block-level PRE-BLOCK trigger (Execution Hierarchy: Override) that contains the following code:
APP_SPECIAL.ENABLE('SUMMARY_DETAIL', PROPERTY_ON);
Finally, create a form-level PRE-BLOCK trigger (Execution Hierarchy: Override) that contains the code:
APP_SPECIAL.ENABLE('SUMMARY_DETAIL', PROPERTY_OFF);
If all blocks are combination blocks, you can turn on SUMMARY_DETAIL at the form-level and ignore the PRE-BLOCK trigger. If most blocks are combination blocks, you can turn SUMMARY_DETAIL on at the form-level, and disable it at the block-level for those blocks that are not combination blocks.
Initial navigation and window operations
If your combination block is the first block in the form, position the two windows in the PRE-FORM trigger with the following calls:
APP_WINDOW.SET_WINDOW_POSITION('<Summary window>',
'FIRST_WINDOW');
APP_WINDOW.SET_WINDOW_POSITION('<Detail window>',
'OVERLAP',
'<Summary window>');
Usually, the Summary is entered first, but there are cases where it is dynamically determined that the Detail should be entered first. If you need to dynamically decide this, set the parameter <block>_RECORD_COUNT in the PRE-FORM trigger (1 to send it to the Detail, 2 to send it to the Summary).