Please note that the functions described in this section are currently under development and may change in detail in future releases.
Suppose that you have designed a form which contains a button that has some fairly complicated script code associated with its onClick event, for instance a button that starts up an eMail composer window, sets the To:, Cc: and Subject: fields, plus a skeleton for the body of the eMail. Now, you might want to trigger this action automatically whenever the user performs some action, for instance saves a record with some particular set of values.
There are two things you could do to handle this. Firstly, you could duplicate all the code in the onClick event into the place (such as the block's postSync event) from where the action should be automatically triggered. This would work, but has the disadvantage that you now have two copies of the code to maintain.
A second option might be to move the code into a script module, and change the onClick and postSync events to call that script module. This has the advantage that there is only one copy of the code. On the other hand, the form is no longer self-contained; should you copy the form to another database you must also copy the script module.
From Rekall 2.2.0, you have a third option, since Rekall provides a mechanism whereby an event function can be invoked directly from another script; it also provides for direct invocation of slots.
Directly Invoking an EventThe key to this is to be able to access the events within a python script. An example of this is shown below:
def eventFunc (ctrl) target = ctrl.getNamedCtrl('../target') target.__events__.onclick() |
In this example, the control located by ctrl.getNamedCtrl('../target') should be a button, since we are going to invoke the onClick event, but the general principal applies to any type of form object. The events in the target object are accessed by the code target.__events__; individual events are accessed by property name (hence, the onClick event is named as onclick).
When the onClick event is executed, the button will be the first argument to the event function in the normal way. Any other arguments passed will become the other arguments to the event function. You should bear in mind that this allows you to "fool" an event function. For instance, Rekall calls a block's onCurrent event with the current row number, but if you call this event directly you could pass it any row number you wanted!
For python aficionados, the __events__ member is a python class. For each event, Rekall generates a python instance object corresponding to the event, and thence a bound method call which invokes the event function. This bound method is inserted into the class dictionary under the event property name.
Slots as MethodsIt is possible to directly invoke a slot in the same way as directly invoking an event, with the member __events__ replaced by __slots__. The target object is passed as the first argument to the slot function in the normal way, and the arguments to the call (ctrl and 'direct' in the example below) are passed as the subsequent arguments. As for direct invocation of events, you should pass arguments that the slot function expects, less you again fool it!
def eventFunc (ctrl) target = ctrl.getNamedCtrl('../target') target.__slots__.myslot(ctrl, 'direct') |
This facility is made more useful by the ability to create unbound slots. An unbound slot is a slot that is not linked to any events, ie., it does not specify any objects and events from which it should be triggered. If you create a slot without any links, then Rekall will warn you and ask if you really want to go ahead; when creating an unbound slot, allow rekall; to save the slot.
An unbound slot is, in effect, a method, in the object oriented programming sense, which can be arbitrarily invoked. Note that because an unbound slot is only never invoked directly by Rekall, the second and subsequent arguments to the slot function are at your discretion, and there is no need to follow the caller/event/other arguments pattern used by bound slots.