Use the SELF handle to identify an object in a trigger
- Last Updated: May 6, 2024
- 3 minute read
- OpenEdge
- Version 12.8
- Documentation
Now you need to check the SCREEN-VALUE of the field to see whether the user
typed anything into it. The reason for this check is that the LEAVE
trigger could fire under other circumstances, such as if the user clicked on a button
while the cursor was positioned in the field. This action would fire the
LEAVE event, but you want to disregard such events unless the user
actually entered a value in the field.
But which field? You are defining the same trigger code for all the fields.
ABL defines another built-in handle that gives you what you need: the
SELF handle. Within a trigger block, this handle resolves to the
object the trigger has fired for.
To identify a field in a trigger:
- Check to see whether the user entered a value using this statement and start a block
that is executed only if the user did:
IF SELF:SCREEN-VALUE NE "" THEN DO:It is important to make this check because the
LEAVEtrigger fires in many different ways, including clicking on a button while the cursor is in the field. You need to check that the user really entered a value to filter on. - Inside this block, use the list of fill-in field handles to disable them again, now
that the user has had a chance to enter a value into one of them:
DO iField = 1 TO NUM-ENTRIES(cFillIns): ASSIGN hField = WIDGET-HANDLE(ENTRY(iField, cFillins)) hField:SENSITIVE = NO. END.Remember that you defined the
cFillInsvariable in the Definitions section specifically because you want its value to be scoped to the whole procedure, so that its value persists between trigger or procedure calls. To remind yourself, and other readers of your code, that a variable like this is scoped to the entire procedure, you can use a naming convention such as putting agfor global on the front of the variable name. Even though such a variable is not actually global to the session, it is global to this procedure, so its scope is worth noting in some way. - Get the handle to the query, along with the current
PREPARE-STRING:ASSIGN hQuery = QUERY CustQuery:HANDLE cPrepare = hQuery:PREPARE-STRING.You are saving off the current
PREPARE-STRINGbefore closing and re-preparing the query so that you can restore it later in the block in case the user chooses not to continue with the filtering. There is a special case you have to deal with here. If the query has not yet been re-prepared dynamically, then thePREPARE-STRINGattribute is unable to return theFOR EACHstatement used in the original staticOPEN QUERYstatement. In this case, you just have to set the variable to the default query string:/* If the query has not been prepared dynamically just restore the original query definition. */ IF cPrepare = ? THEN cPrepare = "FOR EACH Customer". - Close the query and re-prepare it using its handle and the value the user entered
into whichever one of the fill-in fields:
hQuery:QUERY-CLOSE(). hQuery:QUERY-PREPARE("FOR EACH Customer WHERE " + SELF:NAME + (IF SELF:DATA-TYPE = "CHARACTER" THEN " BEGINS " ELSE " = ") + QUOTER(SELF:SCREEN-VALUE) + " BY " + SELF:NAME).The
QUERY-CLOSEstep is actually optional. TheQUERY-PREPAREmethod closes the query automatically.Using the
DATA-TYPEattribute of theSELFhandle, the code identifies the data type of the field the user is filtering on. If the field is CHARACTER, the code builds a query retrieving all Customers where the field valueBEGINSwith what the user typed in, which is theSELF:SCREEN-VALUEattribute. Otherwise, it retrieves records where the field value is equal to the filter value. You could, of course, set up such a query to filter records in any way that you want. Finally, theFOR EACHstatement sorts the record by the filter field, using theSELF:NAMEattribute.