Immediate detection of user changes

This section describes the purpose of the predefined dialogtouched action.

The dialogtouched special predefined action can be used to detect user changes immediately and execute code in the program.

Singular interactive instruction are typically ended with an accept or cancel action. For example, a singular INPUT statement allows the end user to enter a database record, and validate or cancel the input for that record. The INPUT statement is then re-executed to input another record. Unlike singular dialogs, the DIALOG instruction can be used continuously for several data operations, such as navigation, creation, or modification. Typically, default is the navigation mode, and as soon as the user starts to modify a field, it switches to edit mode, to modify a record, or create a new record. In such case, the dialog must be notified when the user starts to modify the current record, for example to enable a save action. This is achieved with the dialogtouched predefined action.

The dialogtouched action works for any field controlled by the current interactive instruction, and with any type of form field: Every time the user modifies the value of a field (without leaving the field), the ON ACTION dialogtouched block will be executed; This can be triggered by typing characters in a text editor field, clicking a checkbox / radiogroup, or modifying a slider. When a ON ACTION dialogtouched action handler is defined, the front-end knows that it must send this action when the end-user modifies the current field (without leaving that field), just by a simple keystroke.

Important: The dialogtouched action must be enabled/disabled in accordance with the status of the dialog: If this action is enabled, the ON ACTION dialogtouched block will be invoked each time the user types characters (or modifies the value with copy/paste) in the current field; This can generate a lot of network traffic and is not the goal of this action: The dialogtouched action must be disabled as soon as it is detected, and the DIALOG can then enter in modification/edit mode. When user input is validated and saved in the database, the dialogtouched action can be enabled again.

Use ON ACTION dialogtouched to detect the beginning of a record modification in a DIALOG block, to enable a "save" action for example. To prevent further dialogtouched action events, disable the action with a DIALOG.setActionActive() method. When the dialogtouched action is enabled, the ON ACTION block will be invoked each time the user types characters in an editable field. This programming pattern is illustrated by the next code example:

DIALOG
   ...
   ON ACTION dialogtouched 
      CALL setup_dialog(DIALOG,TRUE)
   ...
   ON ACTION save 
      CALL save_record()
      CALL setup_dialog(DIALOG,FALSE)
   ...
END DIALOG
 
FUNCTION setup_dialog(d,editing)
   DEFINE d ui.Dialog, editing BOOLEAN
    CALL DIALOG.setActionActive("dialogtouched", NOT editing)
    CALL DIALOG.setActionActive("save", editing)
    CALL DIALOG.setActionActive("query", NOT editing)
END FUNCTION

When a dialogtouched action occurs, the current field may contain some text that does not represent a valid value of the underlying field data type. For example, a form field bound to a DATE variable may contain only a part of a valid date string, such as [12/24/ ]. For this reason, the target variable cannot hold the current text displayed on the screen when the ON ACTION dialogtouched code is executed, even when using the UNBUFFERED mode.

To avoid data validation on action code execution, the dialogtouched action is defined with validate="no" attribute in the FGLDIR/lib/default.4ad action defaults file. This is mandatory when using the UNBUFFERED mode; otherwise the runtime would try to copy the input buffer into the program variable when a dialogtouched action is invoked. Since the text of the current field will in most cases contain only a part of a valid data value, using validate="yes" would always result in a conversion error.

In order to detect field input changes, you can use the ON CHANGE trigger, when the form item type allows to detect value changes immediately, for example in COMBOBOX, CHECKBOX or DATEEDIT fields.