Form Management in an OPEN_FORM Configuration

Form management in an OPEN_FORM configuration requires special attention, especially when there is a chain of OPEN forms and each of these, in turn , has detail forms OPEN. For example, consider the multi-form situation described in the introduction to this chapter. It can be implemented by using OPEN_FORM to invoke multiple instances of ORDER form, with each instance displaying order information about each customer. The ORDER form might then invoke an ORDER DETAILS form that is particular to the current ORDER. Four critical issues must be taken care of:

  • Proper navigation between the various forms
  • Proper commit in the various forms
  • Proper exiting sequence of the various forms
  • Simulating a CLOSE ALL FORMS

Ensuring these will guarantee that the data, as well as the functionality, are in sync. I will discuss each of these in the following sections.

Proper Navigation Between Forms

You can navigate properly between forms by tracking the form_id. Consider the application cited earlier. Three forms are involved: CUSTOMER_SELECTION, CUSTOMER_ORDERS, and CUSTOMER_ORDER_DETS. The CUSTOMER_SELECTION form calls the CUSTOMER_ORDERS form using OPEN_FORM. It uses OPEN_FORM to enable multiple instances of the CUSTOMER_ORDERS form to be opened in order to compare the order information of two or more customers. The CUSTOMER_ORDERS form, in turn, uses OPEN_FORM to call the CUSTOMER_ORDER_DETS form, because the main CUSTOMER_SELECTION form is being called from a menu using CALL_FORM. No subsequent calls to CALL_FORM are allowed in the form chain, after using OPEN_FORM initially.

Tip

When opening multiple instances of the same form in OPEN_FORM configuration, especially in an OPEN_FORM chain, ensure correct navigation from the subform to its parent form. This can be done using GO_FORM(form_id) in the WHEN-WINDOW-ACTIVATED trigger of the calling form.

 

The desired functionality can be achieved in three steps:

  1. In the CUSTOMER_ORDERS form, write a WHEN-BUTTON-PRESSED trigger that keeps track of the form ID of the current particular instance of the form and then invokes the CUSTOMER_ORDER_DETS form using OPEN_FORM. The global variable CUSTOMER_ORDER_ DETS_PRESSED is initialized in the WHEN-NEW-FORM-INSTANCE trigger as follows :

    DEFAULT_VALUE('','global.customer_order_dets_pressed');
    
    WHEN-BUTTON-PRESSED trigger of CUSTOMER_ORDERS form.
    
    
    
    BEGIN
    
     :global.customer_order_dets_pressed := 'Y';
    
     SET_ITEM_PROPERTY('BUTTON_PALETTE.PB_CUST_ORD_DETS',
    
     ENABLED, PROPERTY_FALSE);
    
     form_id := FIND_FORM('CUSTOMER_ORDERS');
    
     :global.form_id := TO_CHAR(form_id.id);
    
    END;
    

    The global variable is necessary to prevent pressing of the button to invoke CUSTOMER_ORDER_DETS a second time while it is already open. An alternative way is to follow the same tracking by form_id for this form, also, and control it. This is not necessary if a need exists to compare the order details of two orders, such as the order information of two customers.

  2. In the CUSTOMER_ORDERS form, write a WHEN-WINDOW_ACTIVATED trigger that forces navigation to this form after the CUSTOMER_ORDER_DETS is exited:

    DECLARE
    
     form_id FORMMODULE;
    
    BEGIN
    
     IF :SYSTEM.EVENT_WINDOW = 'WINDOW0'THEN
    
     IF :global.customer_order_dets_pressed = 'N'THEN
    
     IF :global.form_id IS NOT NULL THEN
    
     form_id.id := TO_NUMBER(:global.form_id);
    
     GO_FORM(form_id);
    
     :global.form_id := NULL;
    
     END IF;
    
     END IF;
    
     END IF;
    
    END;
    
    SET_ITEM_PROPERTY('BUTTON_PALETTE.PB_CUST_ORD_DETS',
    
     ENABLED, PROPERTY_TRUE);
    

    The last line re-enables the button after correct navigation has taken place.

  3. Reset the value of the global variable to 'N' while exiting the CUSTOMER_ORDER_DETS form:

    POST-FORM trigger of CUSTOMER_ORDER_DETS form
    
    :global.customer_order_dets_pressed := 'N';
    

Proper COMMIT

Proper COMMIT in the various forms is automatically ensured by forms, depending on whether the child forms are invoked in the same session or a different session. In such a case of multiple open forms,

  • Call all forms in the same session.
  • As a general rule of thumb, invoke the child forms after saving pending database changes in the calling forms. An alert similar to 'Do you want to save the changes you have made?' with three choices ” Yes, No, and Cancel ”can be displayed whenever the form status is changed. A Yes saves the pending changes and invokes the child forms, a No undoes the pending changes and invokes the child form, and a Cancel does a NULL operation.

Tip

Pending changes in the calling form invoke the called form in POST ONLY mode, which enables the form to only POST and NOT COMMIT, pending changes in the called form.

 

Proper Exiting Sequence

A proper exiting sequence makes sure that all child forms are exited before exiting the parent forms. (Do not exit parent forms before exiting child forms, unless otherwise specifically required.) This is done by writing a KEY-EXIT trigger for the CUSTOMER_ORDERS and CUSTOMER_SELECTION forms. If the CUSTOMER_ORDER_DETS form calls child forms, you must exit those forms properly, also. The following shows code for a KEY-EXIT for the CUSTOMER_ORDERS form. A similar KEY-EXIT can be written for the CUSTOMER_SELECTION form by replacing the module name .

KEY-EXIT for the CUSTOMER_ORDERS form



DECLARE

 form_id FORMMODULE;

 v_msg VARCHAR2(1000);

BEGIN

 form_id := FIND_FORM('CUSTOMER_ORDER_DETS');

 IF NOT ID_NULL(form_id) THEN

 v_msg := 'There are instance(s) of the Customer Order Details Open.';

 v_msg := v_msg'Please close them first!';

 MESSAGE(v_msg);RAISE FORM_TRIGGER_FAILURE;

 END IF;

 IF FORM_SUCCESS THEN

 EXIT_FORM;

 END IF:

END;

If the form is being exited by means of an Exit button or using the x box of the main window, use DO_KEY('EXIT_FORM') in the WHEN-BUTTON-PRESSED trigger of the Exit button or WHEN-WINDOW-CLOSED of the main window, respectively, to invoke the preceding code without repeating it.

Simulating a CLOSE ALL FORMS

When multiple forms are open in a single run-form session, exiting the application requires each open form to be exited individually. However, providing a single function to close all open forms in one shot gives greater flexibility to the end user . It calls for some amount of coding on the part of the developer. You can implement a trick of the trade to simulate a CLOSE ALL FORMS using the WHEN-WINDOW-ACTIVATED trigger. This section presents this technique, which is both elegant and efficient.

Tip

Set a global variable like global.close_all to 'Y'. Use CLOSE_FORM to close the currently activated form.

 

A WHEN-WINDOW-ACTIVATED trigger can be written for each and every form invoked, either by using CALL_FORM or by independently using OPEN_FORM , and its code is based on the following algorithm. Declare a global variable to initiate CLOSE ALL FORMS . Set its value to 'Y'. If the value of this global variable is 'Y', close the currently active form.

The algorithm is given below:

if  = 'Y'then

 if  then

 close form;

 end if;

 end if;

The WHEN-WINDOW-ACTIVATED trigger calls a procedure p_close_all_forms whose logic is based on the above algorithm. The code for this procedure follows this trigger code:

WHEN-WINDOW-ACTIVATED

p_close_all_forms;

The code for the procedure p_close_all_forms is as follows:

PROCEDURE p_close_all_forms IS

 form_id FORMMODULE;

BEGIN

 IF NAME_IN('global.close_all') = 'Y'THEN

 form_id := FIND_FORM(NAME_IN('SYSTEM.CURRENT_FORM');

 IF NOT ID_NULL(form_id) THEN

 CLOSE_FORM(form_id);

 END IF;

 END IF;

END;

The global global.close_all can be set in an iconic button on a toolbar, in a trigger for a hot key, or in a menu option common to all forms. The disadvantage of this method is that any nonactive forms are still left open until the user clicks on a particular form. To enhance the functionality to accommodate this feature, use :SYSTEM.MOUSE_FORM and the WHEN-MOUSE-ENTER trigger at the form level of each independent form. Then the user can just move the mouse around, and the CLOSE ALL FORMS magic follows. The corresponding procedure is named xclose_all_forms .

WHEN-MOUSE-ENTER

xclose_all_forms;

The code for the procedure is as follows:

PROCEDURE xclose_all_forms IS

 form_id FORMMODULE;

BEGIN

 IF NAME_IN('global.close_all') = 'Y'THEN

 form_id := FIND_FORM(NAME_IN('SYSTEM.MOUSE_FORM');

 IF NOT ID_NULL(form_id) THEN

 CLOSE_FORM(form_id);

 END IF;

 END IF;

END;

This method is more user friendly than the first because it saves the many extra clicks required in the former.

Tip

CLOSE_FORM is equivalent to EXIT_FORM(ASK_COMMIT). If other parameters such as NO_COMMIT, DO_COMMIT or NO_VALIDATE are required, use EXIT_FORM instead.


GUI Development

Advanced GUI Development: Developing Beyond GUI

Multi-form Applications

Advanced Forms Programming

Error-Message Handling

Object-oriented Methods in Forms

Intelligence in Forms

Additional Interesting Techniques

Working with Trees

Oracle 8 and 8i Features in Forms Developer



Oracle Developer Forms Techniques
Oracle Developer Forms Techniques
ISBN: 0672318466
EAN: 2147483647
Year: 2005
Pages: 115

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net