Adding Flexfields to Your Forms

There are four basic parts to calling a flexfield from an Oracle Forms window. These steps assume that your flexfield is already registered and defined in Oracle Application Object Library and that the flexfield table and columns already exist. These steps apply to both key and descriptive flexfields.

To code a flexfield into your form:

Create Your Hidden Fields

In general, you create your hidden flexfield fields as part of creating your default form block from the database table (or view). Set the canvas property of the flexfield fields to null (so they do not appear on a canvas).

Your hidden ID (for key flexfields only), structure field, and segment or attribute fields must be text items on the null canvas. Note that these must be text items rather than display items, and that they should use the TEXT_ITEM property class. Set the field query lengths to 255 for most fields, with a query length of 2000 for hidden ID fields.

Attention: You should never create logic that writes values to the hidden fields directly. Since the flexfield keeps track of whether a record is being inserted, updated, etc., putting values in these fields by any method other than the flexfield itself (or a query from the database) may cause errors and data corruption.

In some foreign key forms for key flexfields, you may need to create extra non-database fields that represent the segment columns (SEGMENT1 through SEGMENTn) in your combinations table. Put your SEGMENT1 through SEGMENTn fields on the null canvas (field length the same as your SEGMENTn columns). These fields help Oracle Application Object Library to create new code combinations from your form with a foreign key reference (using dynamic insertion).

Normally, Oracle Application Object Library can create new code combinations (dynamic insertion) from your form with a foreign key reference using only the concatenated segment values field. However, if you expect the concatenated length of your flexfield to be defined to be larger than 2000 (the sum of the defined segments' value set maximum sizes plus segment separators), then you should create these non-database fields to support the dynamic creation of new combinations from your form.

If you do not have these fields and your users define a long flexfield (> 2000 characters), your users can experience truncation of key flexfield data when trying to create new combinations.

If your key flexfield is registered with Dynamic Inserts Feasible set to No, you do not need to add these fields, though they are recommended. If you do not create these fields, and your users define a long flexfield, your users may see empty flexfield segments upon entering the flexfield pop-up window after a query. These blank segments do not adversely affect the underlying data, nor do they adversely affect flexfield changes if your user updates those segments after querying.

If you use these fields and you have more than one key flexfield in the same row (in a block) of your form, you should also create one extra set of non-database segment fields per flexfield. So, if you have three foreign-key-reference flexfields in your block, you should have four sets of segment fields (for example, SEGMENT1 to SEGMENTn as the main set; and SEGMENT1_A to SEGMENTn_A, SEGMENT1_B to SEGMENTn_B, and SEGMENT1_C to SEGMENTn_C as the extra sets). In addition, you should use the USEDBFLDS="Y" argument for your flexfield definition routine calls. When you do so, you must write trigger logic to explicitly copy the appropriate values into or out of these fields before your flexfield routine calls. You must copy your values into the main set from the appropriate extra set before the WHEN-NEW-ITEM-INSTANCE and the PRE-INSERT and PRE-UPDATE flexfield event calls. You must copy your values out of the main set into the appropriate extra set after the POST-QUERY, WHEN-NEW-ITEM-INSTANCE, WHEN-VALIDATE-ITEM, PRE-INSERT, or PRE-UPDATE calls.

For a descriptive flexfield, it is possible (though not recommended) to create your form such that the table containing the descriptive flexfield columns is not the base table (or included in the base view) of the form. To do this, you create all the hidden fields (the ATTRIBUTEn fields and the structure defining field) as non-database fields on the null canvas. Then, code trigger and table handler logic that keeps the data in the two tables synchronized. For example, when your form updates your base table, your ON_UPDATE table handler should update the ATTRIBUTEn and structure defining columns in the descriptive flexfield table. Likewise, when your form inserts new records, you should have logic in your ON_INSERT table handler that inserts into the descriptive flexfield table. Descriptive flexfields never write directly to a table (base table or otherwise); they always write to the hidden segment fields.

Create Your Displayed Fields

Create your concatenated segments field as a 2000 character displayed, non-database text item for either key or descriptive flexfields. For a range flexfield, you create two non-database fields with the same name but with the suffixes _LOW and _HIGH.

Use the TEXT_ITEM property class for your key and range flexfields. For a descriptive flexfield, use the property class TEXT_ITEM_DESC_FLEX and name the field DESC_FLEX.

You must attach the dummy LOV from the TEMPLATE form, ENABLE_LIST_LAMP, to the displayed key or descriptive flexfield field. Make sure that "Validate from List" property (formerly "Use LOV for Validation") is set to No. This ensures that the List lamp works properly for your flexfield.

If you experience strange LOV behavior (where the LOV provides "null" as the only valid choice) or messages that the flexfield cannot be updated and/or has invalid values, check that "Validate from List" is set to No.

Create Your Flexfield Definition

Call a flexfield definition procedure from your WHEN-NEW-FORM-INSTANCE trigger to set up your flexfield. Using this procedure, you specify the block and fields for your flexfield and its related fields, the flexfield you want, and other arguments. See: Flexfield Definition Procedures.

You may need to enable, disable, or modify your flexfield definition depending on conditions in the form. For example, you may want to have a flexfield be updatable under some conditions but not under other conditions. In this case you should also call an UPDATE_DEFINITION procedure after calling the appropriate DEFINE procedure. See: Updating Flexfield Definitions.

Invoke Your Flexfield Definition from Several Event Triggers

Code handlers for special procedures into several form level triggers. These procedures fire your flexfield at certain events such as WHEN- NEW-ITEM-INSTANCE, WHEN-VALIDATE-ITEM, and PRE-INSERT.

You call your flexfields from form level triggers using the FND_FLEX.EVENT(EVENT) procedure. You can also call your flexfields using this procedure from within your own procedures. This procedure takes the event name as its argument. Call FND_FLEX.EVENT and pass the trigger name from the triggers listed in the following table:

Trigger Procedure
PRE-QUERY FND_FLEX.EVENT('PRE-QUERY');
POST-QUERY FND_FLEX.EVENT('POST-QUERY');
PRE-INSERT FND_FLEX.EVENT('PRE-INSERT');
PRE-UPDATE FND_FLEX.EVENT('PRE-UPDATE');
WHEN-VALIDATE- RECORD FND_FLEX.EVENT('WHEN-VALIDATE- RECORD');
WHEN-NEW-ITEM- INSTANCE FND_FLEX.EVENT('WHEN-NEW-ITEM-INSTANCE');
WHEN-VALIDATE- ITEM FND_FLEX.EVENT('WHEN-VALIDATE-ITEM');

These calls should usually be coded into your form as form-level triggers. If you define any of these triggers at the block or field level, you need to make sure the block or field level triggers have execution style set to "Before" so the form-level flexfield calls still execute, or you should include these procedure calls in those triggers as well.

While we recommend you code all the flexfields triggers at the form level for convenience and consistency, having the triggers at form level may cause performance problems for very large or complicated forms. In that case, you may code the PRE-QUERY, POST-QUERY, PRE-INSERT, PRE-UPDATE, and WHEN-VALIDATE-RECORD triggers at the block level on all blocks that have flexfields (key or descriptive). You would then code the WHEN-NEW-ITEM- INSTANCE and WHEN-VALIDATE-ITEM at the item level for items on which the flexfields are defined.

You only need to code one set of these triggers regardless of how many flexfields you have in your form (assuming these triggers are at the form level).

Three form-level triggers in the TEMPLATE form, KEY-EDIT, KEY-LISTVAL, and POST-FORM, already have the appropriate FND_FLEX.EVENT calls performed through the APP_STANDARD.EVENT('trigger_name') routines as part of the APPCORE library. You must ensure that these APP_STANDARD.EVENT calls are not overridden by triggers at the block or item levels.

Attention: If you have a block or item level POST-QUERY trigger that resets the query status of a record, you must set the Execution Style of that block or item level POST-QUERY trigger to After. Because the flexfield POST-QUERY logic updates field values for your flexfield, the record must be reset to query status after that logic has fired.

Opening a Flexfield Window Automatically

By default, descriptive flexfields open automatically without any special code so long as the profile option Flexfields:Open Descr Window is not set to No.

Normally, key flexfields do not open automatically. However, users can set the profile option, Flexfields:Open Key Window, to Yes to automatically open all key flexfields. You must not code any code in your form to open the window automatically, because the window would then be forced to open a second time.

You should remove any existing code that opens a key flexfield automatically. Such code would probably be in your WHEN-NEW-ITEM-INSTANCE trigger at the field level, instead of the form level, on the field that contains the flexfield. You should remove any "FND_FLEX.EVENT('KEY-EDIT');" call that opens the flexfield automatically.