The browse and its query must remain in sync. At times, you might have to do some behind-the-scenes manipulation of the result set to keep them in sync. Generally speaking, whenever the user repositions the browse by selecting a new row, its query repositions automatically to that same row. Likewise, if the query is programmatically repositioned to a different row, the browse automatically coordinates with it and the new current row within the query becomes the currently selected row in the browse. However, if you simply FIND a row using the query’s buffer, this does not reposition either the query or its browse. This is why you might need to resync the query in your code in order to properly refresh the browse. To do this, you can use the REPOSITION statement. The REPOSITION statement moves the database cursor to the specified position and adjusts the browse viewport to display the new row.

To avoid display flashing when doing programmatic repositions, you can set the REFRESHABLE browse attribute to FALSE, do the REPOSITION, and then set REFRESHABLE to TRUE. This suspends any redisplay of the browse until after the operation is complete.

In addition, the SET-REPOSITIONED-ROW() method gives you control over the position in the viewport where the browse displays the repositioned row. The method takes two arguments:

  1. Its first integer argument tells the AVM which row (that is within the browse viewport) to position to. For example, if your browse displays seven rows at a time, you could use the SET-REPOSITIONED-ROW method to show a newly positioned row in the middle of the viewport by using an argument value of 4.
  2. The second character argument to the method can be ALWAYS or CONDITIONAL. If you specify ALWAYS, the browse is always adjusted to show the repositioned row in the specified position. If you specify CONDITIONAL, then the browse adjusts only if the repositioned row is not already in the viewport.

Note that normally you set SET-REPOSITIONED-ROW() once for the session for a browse to establish its behavior wherever it is used. You can also use the GET-REPOSITIONED-ROW() method to return as an Integer the current target viewport row for repositions.

To reposition the query and the browse along with it:

  1. Define a new fill-in called iOrder of INTEGER data type labelled Order.
  2. Define this LEAVE trigger for the fill-in field:
    DO:
      BROWSE OrderBrowse:SET-REPOSITIONED-ROW(3, "CONDITIONAL").
      ASSIGN iOrder.
      FIND Order WHERE order.orderNum = iOrder NO-ERROR.
      IF AVAILABLE (Order) THEN
        REPOSITION OrderBrowse TO ROWID ROWID(Order) NO-ERROR.
    END.

When you enter a value into the field and press TAB, the query and the browse are both repositioned to that row. If you enter a row that the AVM cannot find or that is not an Order for the current Customer, the AVM suppresses these errors and nothing changes in the browse. The SET-REPOSITIONED-ROW method makes the new row the third row in the viewport unless it is already displayed.

For a multiple-select browse, the concepts of focus and selection separate. Selection indicates that the user has selected a record. The user can select many records. The last selected record is the one in the record buffer. Focus indicates that the record has input focus. There can be only one focused row, and it might or might not be a selected row. In a single-select browse, selection and focus are one and the same.