Handling the current row

Query and control the current row in a read-only or editable list of records.

Get the current row

To query the current row of a list, use either the ui.Dialog.getCurrentRow() method or the ARR_CURR() built-in function, according to the context.

The getCurrentRow() method can be used inside or outside the context of the DISPLAY ARRAY or INPUT ARRAY dialog. The method takes the name of the screen array as the argument to identify the list. For example, when implementing a DIALOG block with two DISPLAY ARRAY subdialogs, you can query the current row of a list in the code block of the other list controller:
DIALOG ...
   DISPLAY ARRAY arr1 TO sa1.*
      ON ACTION check
         IF arr2[DIALOG.getCurrentRow("sa2")].value > 0 THEN
            ...
         END IF
   END DISPLAY
   DISPLAY ARRAY arr2 TO sa2.*
   END DISPLAY
END DIALOG
The ARR_CURR() function must be used in the context of the current DISPLAY ARRAY or INPUT ARRAY dialog, or just after executing such a dialog. For example, when implementing modification triggers in a DISPLAY ARRAY dialog, the current row and the current screen line can be queried respectively with the ARR_CURR() and SCR_LINE() functions:
DISPLAY ARRAY arr TO sa.*
    ON UPDATE
       INPUT arr[arr_curr()].* WITHOUT DEFAULTS FROM sa[scr_line()].* ;
END DISPLAY
The ARR_CURR() function returns the current row index for the last executed dialog, until a new list dialog is started.

Set the current row

To set the current row in a list controlled by a DISPLAY ARRAY or INPUT ARRAY, use the ui.Dialog.setCurrentRow() method. This method takes the name of the screen array and the new row index as parameters:
DISPLAY ARRAY p_items TO sa.*
   ...
   ON ACTION next_empty 
      LET row = findEmptyRow(p_items)
      CALL DIALOG.setCurrentRow("sa", row)
   ...
END DISPLAY
Calling the DIALOG.setCurrentRow() method will not execute control blocks such as BEFORE ROW and AFTER ROW, and will not set the focus. If you want to set the focus to the list, you must use the NEXT FIELD instruction. This works with DISPLAY ARRAY as well as with INPUT ARRAY.
Tip: Use this method with care. Let the dialog handle normal navigation automatically, and jump to a specific row only in the context of an ON ACTION block.
The FGL_SET_ARR_CURR() function can also be used. This function must be called in the context of the current list having the focus.
Note: FGL_SET_ARR_CURR() triggers control blocks such as BEFORE ROW, while DIALOG.setCurrentRow() does not trigger any control blocks.

Converting visual index to/from program array index

When the end user sorts rows in a table, the program array index (arr_curr()) may differ from the visual row index (the row position as seen by the user).

The ui.Dialog class provides methods to convert between these contexts:

The ui.Dialog.arrayToVisualIndex method converts a program array index to a visual index. It can be used, for example, to display a typical list position message (Row: current-row / total-rows). The current row (arr_curr()/getCurrentRow()) is a program array index that must be converted to a visual index. Note that you need to display such messages in the BEFORE ROW trigger and ON SORT trigger:
FUNCTION disp_row(d,n)
   DEFINE d ui.DIALOG, n STRING
   MESSAGE SFMT("Row: %1/%2",
                d.arrayToVisualIndex(n,d.getCurrentRow(n)),
                d.getArrayLength(n))
END FUNCTION
...
   DISPLAY ARRAY arr TO sr.*
       ...
       BEFORE ROW
           CALL disp_row(DIALOG,"sr")
       ON SORT
           CALL disp_row(DIALOG,"sr")
       ...
   END DISPLAY
The ui.Dialog.visualToArrayIndex method converts a visual index to a program array index. It can be used for example to ask the user for a row position (visual index), and make that row current by using DIALOG.setCurrentRow() after converting to the program array index:
DEFINE i INTEGER
...
DISPLAY ARRAY arr TO sr.*
   ...
   ON ACTION move_to
      PROMPT "Enter row index:" FOR i
      CALL DIALOG.setCurrentRow( "sr", DIALOG.visualToArrayIndex("sr", i))
   ...
END DISPLAY