Set up triggers to be executed
- Last Updated: January 16, 2024
- 5 minute read
- OpenEdge
- Version 12.8
- Documentation
A trigger is executed if the object it applies to is enabled (sensitive), and if the trigger is currently active and in scope.
The trigger is active if the statement that defines it has been executed. As discussed earlier in the book, the AVM processes statements in a procedure in the order it encounters them in. Thus, the definition of an object must come before the block of code that defines a trigger for the object. Otherwise, the AVM will not recognize the object reference. And the trigger definition must come before the user receives control and can perform the action that would fire the event and run the trigger.
The scope of a definitional trigger is the scope of the object it is defined for. The scope of a run-time trigger is the nearest containing procedure or trigger block where it is defined. So if a trigger definition is inside an internal procedure, then its scope is limited to that internal procedure. If it is outside of any internal procedure, its scope is the entire external procedure.
The AppBuilder places all trigger definitions toward the top of the procedure, following
the Definitions section of the procedure but before the main
block and all internal procedures. In this way the trigger blocks are scoped to the
entire procedure and they are made active before any user actions that invoke them can
occur.
- Define a button and give it an initial label, then define an INTEGER variable as
a counter:
DEFINE BUTTON bButton LABEL "Initial Label". DEFINE VARIABLE iCount AS INTEGER NO-UNDO. - Add a statement to enable the button in a frame. As you learned earlier, this
causes both the button and its frame to be instantiated and
realized:
ENABLE bButton WITH FRAME fFrame. - Define a run-time trigger for the button that changes its label so that you can
see that the trigger fired:
ON CHOOSE OF bButton IN FRAME fFrame DO: iCount = iCount + 1. bButton:LABEL IN FRAME fFrame = "External " + STRING(iCount). END. - Create a
WAIT-FORstatement that blocks the termination of the procedure and allows the user to click the button:WAIT-FOR CLOSE OF THIS-PROCEDURE. - Run the procedure. As you would expect, the button’s
label is changed when you click the button:
The
ON CHOOSEtrigger you defined is scoped to the entire procedure and executes each time the button is pressed.
To define another trigger for the button in an internal procedure, make these changes to the procedure:
|
Before the WAIT-FOR statement the code runs the internal procedure
ChooseProc. This procedure defines a different trigger for the same
button, which identifies the trigger with the label Internal. The
second trigger definition replaces the first one within the ChooseProc
procedure.
Note that the scope of the button is the entire external procedure because it is defined
at that level. The scope of the variable iCount is also the external
procedure for the same reason. But what is the scope of the second trigger definition
you just added?
It is scoped only to the internal procedure where it is defined. So what happens when you run this version of the procedure? Before you run it, walk through the code in your head to decide what happens.
The external procedure defines a trigger for the button. It then runs an internal procedure that defines a different trigger. That internal procedure then exits, without giving the user any chance to use the new trigger, and its trigger goes out of scope. So what happens when the user clicks the button? The AVM reverts to the original trigger.
This example shows you that the AVM effectively keeps a stack of trigger definitions. If a later definition goes out of scope, the AVM reverts to the trigger definition that is now back in scope (if there is one).
So how would you see the effect of the internal procedure trigger? You can place a
WAIT-FOR statement inside the internal procedure to force the AVM
to wait until the user clicks the button.
To try this, add this statement to the end of the ChooseProc procedure:
|
Note that you can wait for any event, not just the close of the procedure or its window.
This statement waits until the user clicks the button exactly once. Then the
WAIT-FOR is satisfied, the internal procedure exits, and the first
trigger takes over.
To see the result of each button press, run the procedure again. This figure shows the result of the first four button presses.



