The SUBDIALOG clause
Purpose of SUBDIALOG
The SUBDIALOG clause defines a declarative dialog to be attached to the
current procedural DIALOG
block.
By using form inclusion (with the FORM clause in LAYOUT
sections) and declarative dialogs + SUBDIALOG, you enforce code reusability in your
application sources.
Defining the declarative dialog
The declarative dialog is implemented outside the scope of the using DIALOG
block, at the same level as a function.
The declarative dialog can be defined in a different module, to be reused in other
DIALOG instructions. The sub-dialog module must be imported with the IMPORT FGL instruction.
Like other module elements such as functions and reports, the name specification is mandatory
when defining a declarative dialog. The name of the declarative dialog will be referenced in a
SUBDIALOG clause of a procedural dialog instruction.
PUBLIC TYPE t_comment RECORD
c_text VARCHAR(200),
c_checked BOOLEAN
END RECORD
DIALOG comment_input(rc t_comment INOUT)
...
END DIALOGIMPORT FGL comment
...
FUNCTION mydialog()
DEFINE r_comment comment.t_comment
DIALOG ...
...
SUBDIALOG comment.comment_input(r_comment)
...
END DIALOG
END FUNCTIONSee also Identifying sub-dialogs in DIALOG.
Sub-dialogs in form definitions
Implementing a sub-dialog as a declarative dialog in a separate module is typically used in
conjunction with the FORM clause, in the
LAYOUT section of form specification files:
LAYOUT
...
FORM "comment"
...
END
Semantics with SUBDIALOG
In terms of semantics, behavior and control block execution, a declarative dialog attached to a
procedural dialog with SUBDIALOG, behaves like a sub-dialog that is defined inside
the procedural DIALOG block.
For example, BEFORE INPUT
inside an INPUT block of a declarative dialog will be executed when the focus goes
to one of the fields of that sub-dialog.
Scope of dialog instructions
Other sub-dialogs can reference the attached declarative dialog in the current scope.
NEXT
FIELD instruction referencing a field in another
sub-dialog:DIALOG ... -- Parent dialog block
...
NEXT FIELD the_comment -- Field of the declarative dialog.
...
END DIALOGScope of DIALOG keyword
DIALOG keyword inside a declarative dialog block to use
ui.Dialog class methods, it references the current procedural dialog
object:DIALOG comment_input()
...
CALL DIALOG.setFieldActive("the_comment",TRUE)
...
END DIALOGWriting generic code
To be reused by different procedural DIALOG instructions, the code of
sub-dialog modules must be generic. However, if the sub-dialog code needs to interact with
the parent DIALOG, it must be possible to call a function from the parent
DIALOG.
You achieve this by using function references. Parent modules can then configure the sub-dialog module at runtime, with callback functions:
- Create a user-defined
TYPEwith theFUNCTIONtype matching the callback function of the using module:PUBLIC TYPE t_event_callback FUNCTION (event SMALLINT) - Define a private module variable, with the declared function type. If you want to keep it
private to the module, define a setter function to assign the variable with the callback function
reference:
PRIVATE DEFINE _event_callback t_event_callback - Define public constants to identify the type of event to be signaled to the parent
dialog:
PUBLIC CONSTANT c_comment_changed = 101 PUBLIC CONSTANT c_comment_checked = 102 - Implement the function to notify the parent
dialog:
PRIVATE FUNCTION _signal_parent(ne SMALLINT) RETURNS () IF _event_callback IS NOT NULL THEN CALL _event_callback(ne) END IF END FUNCTION - Define the sub-dialog with the callback function reference
parameter:
DIALOG comment_input( cr t_comment INOUT, can_clear STRING, event_callback t_event_callback ) - In the sub0dialog block triggers, call the function to signal events to the parent
dialog:
ON CHANGE is_checked CALL _signal_parent(c_comment_checked) - In the parent dialog block, define the callback function to be bound to the
sub-dialog:
FUNCTION event_callback(event SMALLINT) CASE event WHEN comment.c_comment_checked LET msg = "Comment checked..." ... END CASE END FUNCTION - Provide the reference to the callback function as parameter of the sub-dialog, in the
SUBDIALOGinstruction of the parentDIALOG:SUBDIALOG comment_input(cust_comment, TRUE, (FUNCTION event_callback))
There is no need to implement a lot of complex callback functions: The main purpose is to
indicate to the parent DIALOG, that something happened in the sub-dialog. The
parent DIALOG can then query the sub-dialog module for more information, as long as
the sub-dialog module provides functions to query its status.
For a complete example, see Example 3: DIALOG with SUBDIALOG.