Field-level focus in DISPLAY ARRAY

The DISPLAY ARRAY dialog supports cell-level focus with the FOCUSONFIELD.

Enabling focusable cells in DISPLAY ARRAY

When using a DISPLAY ARRAY dialog to control a list view, you can enable cell-level focus handling with the FOCUSONFIELD attribute.

With a graphical front-end, this feature allows cell mouse clicks or tabbing between cells, instead of having the whole current row highlighted.

This feature can also be used in text mode (FGLGUI=0), to move in DISPLAY ARRAY fields with the keyboard using arrow keys or tab.

To enable field-level focus handling in a DISPLAY ARRAY, add the FOCUSONFIELD attribute in the dialog definition:

DISPLAY ARRAY arr TO sr.* ATTRIBUTES(FOCUSONFIELD)

Detecting cell focus changes

When the FOCUSONFIELD attribute is defined, BEFORE FIELD and AFTER FIELD blocks can be used, to detect field focus changes:
DISPLAY ARRAY arr TO sr.* ATTRIBUTES(FOCUSONFIELD)
   ...
   BEFORE FIELD cust_id
      MESSAGE "focus in cust_id, row = ", arr_curr()
   AFTER FIELD cust_id
      MESSAGE "focus left cust_id, row = ", arr_curr()
   BEFORE FIELD cust_name
      MESSAGE "focus in cust_name, row = ", arr_curr()
   ...
END DISPLAY
Note that if defined, the AFTER ROW control block will execute after the AFTER FIELD block and the BEFORE ROW control block will execute before the BEFORE FIELD block. The code blocks execute in the following order:
  1. AFTER FIELD (for the field that loses the focus)
  2. AFTER ROW (for the previous current row)
  3. BEFORE ROW (for the new current row)
  4. BEFORE FIELD (for the field that gets the focus in the new row)

What is the current cell?

The current cell of DISPLAY ARRAY with FOCUSONFIELD attribute can be found by using the ui.Dialog.getCurrentItem() method:
DISPLAY ARRAY arr TO sr.* ATTRIBUTES(FOCUSONFIELD)
   ...
    ON ACTION show_current_cell
        MESSAGE "Current cell = ", DIALOG.getCurrentItem()

Setting the current cell

To set the focus to a specific cell with program code, use the NEXT FIELD instruction, or the ui.Dialog.nextField() method, in conjunction with the ui.Dialog.setCurrentRow() method:
DISPLAY ARRAY arr TO sr.* ATTRIBUTES(FOCUSONFIELD)
   ...
    ON ACTION top_left ATTRIBUTES(TEXT = "TOP LEFT")
        CALL DIALOG.setCurrentRow("sr", 1)
        NEXT FIELD first_field
    ON ACTION bottom_right ATTRIBUTES(TEXT = "BOTTOM RIGHT")
        CALL DIALOG.setCurrentRow("sr", sr.getLength())
        NEXT FIELD last_field
   ...
END DISPLAY