Release 10.1A: OpenEdge Development:
Progress 4GL Handbook

> ## Using the SELF handle to identify an object in a trigger

> 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’re defining the same trigger code for all the fields.

> Progress 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:

> 1. 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’s important to make this check because the `LEAVE` trigger 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.

> 2. 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 `cFillIns` variable in the Definitions section specifically because you do 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 a `g` for 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.

> 3. Get the handle to the query, along with the current `PREPARE-STRING`:

>     ASSIGN hQuery = QUERY CustQuery:HANDLE
>            cPrepare = hQuery:PREPARE-STRING.

> You’re saving off the current `PREPARE-STRING` before 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’s a special case you have to deal with here. If the query has not yet been re-prepared dynamically, then the `PREPARE-STRING` attribute is unable to return the `FOR EACH` statement used in the original static `OPEN QUERY` statement. In this case, you just have to set the variable to the default query string:

>     /* If the query hasn't been prepared dynamically just restore
>        the original query definition. */
>     IF cPrepare = ?  THEN
>        cPrepare = "FOR EACH Customer".

> 4. 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-CLOSE` step is actually optional. The `QUERY-PREPARE` method closes the query automatically.

> Using the `DATA-TYPE` attribute of the `SELF` handle, 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 value `BEGINS` with what the user typed in, which is the `SELF:SCREEN-VALUE` attribute. 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, the `FOR EACH` statement sorts the record by the filter field, using the `SELF:NAME` attribute.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095