Validation, Navigation, and Simulating Navigation
A Change event in Forms triggers a Validate event. In this situation, the WHEN-VALIDATE-ITEM and WHEN-VALIDATE-RECORD triggers come into the picture.
Note
A Change in Oracle forms is some change in an item value, either interactively through user input or programmatically. Overwriting the item with its original value is also a Change event.
A WHEN-VALIDATE-ITEM trigger fires when the item value has been changed and navigation is initiated out of the item either explicitly or programmatically. If no navigation needs to be initiated out of the item, there is a way to imitate navigation using the ENTER built-in.
COMMIT also imitates navigation and initiates validation.
Suppose there is a WHEN-VALIDATE-ITEM trigger for the last item of a record. The user enters a value into this item and does not press Enter. Instead, he clicks the Save button. As I just mentioned, COMMIT fires the WHEN-VALIDATE-ITEM trigger. But COMMIT is a form level event and in addition to this WHEN-VALIDATE-ITEM trigger, validation occurs throughout the form and multiple failures might cause multiple error messages to be displayed, which is confusing to the user as it messes up the process. Multiple failures might be because of failure of form object properties in addition to failure of the WHEN-VALIDATE-ITEM or cascading effects of these. Also there might be code that needs to be written before the call to the built-in COMMIT_FORM in the WHEN-BUTTON-PRESSED trigger of the Save button, such as assigning variables or simulating an UPDATE when the user enters non-base table items so that a PRE-UPDATE trigger fires and so on.
As an illustration, suppose that in our preceding example, there was code to assign a base table item to itself ”to simulate an UPDATE operation ”before the call to the COMMIT_FORM. The WHEN-VALIDATE-ITEM trigger fires after the assignment even if a RAISE FORM_TRIGGER_ FAILURE is done in WHEN-VALIDATE-ITEM. So the record would be marked as an update before checking for the success or failure of the WHEN-VALIDATE-ITEM. To prevent this, in the WHEN-BUTTON-PRESSED trigger of the Save button, add the following code in the beginning:
WHEN-BUTTON-PRESSED ENTER; IF FORM_SUCCESS THEN COMMIT_FORM; IF FORM_SUCCESS THEN END IF; END IF;
Note how ENTER simulates navigation and thus initiates validation. In this case, the WHEN- VALIDATE-ITEM fires. On its failure, the assignment is not done because FORM_SUCCESS evaluates to FALSE.
VALIDATION, VALIDATION_UNIT, and VALIDATE
The Validation and Validation Unit properties control the occurrence and scope of validation in a form.
The Validation property decides whether forms should initiate or not when the Validate event occurs. This property is ON by default and can be turned on and off programmatically by using SET_FORM_PROPERTY. The property is specified by the constant VALIDATION. For example
SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATION, PROPERTY_FALSE);
The Validation Unit property decides at what point validation should be initiated. In other words, until what point in time should Forms defer validating changes in the form? This property is valid only if the Validation property is set to YES. The valid values for this are DEFAULT_SCOPE, ITEM_SCOPE, RECORD_SCOPE, or FORM_SCOPE. For example
SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATION_UNIT, ITEM_SCOPE);
When set to ITEM_SCOPE, validation is initiated on navigation at the item level ”that is, when control moves out of an item. The validation unit specifies at what level (item, record, or form) validation is initiated. This requires that the corresponding event initiating this validation should be an item-, record-, or form-level event, and this is what becomes the default scope of validation in the form from that point on. If the event initiating validation is an item-level event, the default scope is ITEM_SCOPE. Similarly, if the event initiating validation is a record-level event or form-level event, the default scope is RECORD_SCOPE or FORM SCOPE respectively.
The constant DEFAULT_SCOPE is environment specific and is ITEM_SCOPE on the GUI Windows platform. This should not be confused with the default scope previously discussed.
Tip
Turning off the Validation property automatically turns off Validation Unit property.
VALIDATE
Validation might be turned off for some particular reason; for example, during form startup. It can be later turned on ”for example, just before committing. When turned on, the VALIDATE built-in has to be invoked to actually perform (execute) the validation.
Setting the Validation property to YES only indicates that validation should occur. Setting the Validation Unit property to the appropriate scope only indicates that validation should occur at the particular scope. Specifying a call to the VALIDATE built-in actually initiates the validation so that any WHEN-VALIDATE-ITEM, WHEN-VALIDATE-RECORD, and form object properties triggered by validation are fired .
The following example code illustrates this point:
WHEN-NEW-FORM-INSTANCE SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATIION, PROPERTY_FALSE); PRE-INSERT, PRE-UPDATE or PRE-DELETE SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATION, PROPERTY_TRUE); SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATION_UNIT, FORM_SCOPE); VALIDATE(FORM_SCOPE);
In this code, setting the validation unit is not necessary because VALIDATE(FORM_SCOPE) automatically sets the VALIDATION_UNIT and then validates at form scope.
Note that after you set the Validation Unit constant for the whole form, even if you set it dynamically, it cannot be reset to hold for specific item(s), record(s), or block(s).
Initially, when a form is run, the validation is ON and the DEFAULT_SCOPE is the same as ITEM_SCOPE. If the validation is turned off and then turned on, even though the DEFAULT_SCOPE is ITEM_SCOPE, validation might not occur at the item level. As specified earlier, it depends on the event initiating the validation.
Tip
DEFAULT_SCOPE is not the same as ITEM_SCOPE when it comes to initiating the validation process.
Turning off Validation using
SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATION, PROPERTY_FALSE)
also turns off the validation occurring because of the Required property when set to TRUE/YES.
Turning off validation doesn't completely nullify the validation occurring in a form. Validation is nullified only for Validation initiating form object properties and validation triggers in forms.
An example of the former is the Required property. Other validations do occur. To exemplify this point, when the Enforce Primary Key property is set to YES and validation is turned off in the WHEN-NEW-FORM-INSTANCE trigger, the primary key enforcement is still checked in case of a duplicate record and Forms displays the following message on its failure:
FRM-40600: Record has already been inserted.
Oracle errors on the database side are also propagated to Forms.
When validation is turned off and then turned on at a later point of time, immediately call the VALIDATE built-in with the appropriate scope specified as its parameter. This is required to initiate the validation so that validation actually occurs.
When you turn off validation, if you are turning it on in a COMMIT event-initiated trigger, set it to Form scope. This is because COMMIT is a form-level event by default.
For example, if the Validation has been turned off in the WHEN-NEW-FORM-INSTANCE trigger, and you are turning it on in, say, a PRE-INSERT trigger, specify the following:
SET_FORM_PROPERTY(:SYSTEM.CURRENT_FORM, VALIDATION, PROPERTY_TRUE); VALIDATE(FORM_SCOPE);
Using DEFAULT_SCOPE will not work to validate form-level initiated events, such as pressing the Commit key.