INPUT ARRAY temporary rows

Temporary rows can be created at the end of an editable record list.

In record list controlled by an INPUT ARRAY, the user can create a new temporary row at the end of the list: The new row is called "temporary" because it will be automatically removed if the user leaves the row without entering data. If data is entered by the user or by program (setting the touched flag), the temporary row becomes permanent.

A temporary row is promoted to a permanent row under certain conditions described in this topic. We distinguish also explicit temporary row creation from automatic temporary row creation.

Temporary row creation is different from adding new rows with the DIALOG.appendRow() method; When appending a row by program, the row is considered permanent and remains in the list even if the user did not enter data in fields.

Conditions to make a temporary row permanent

The temporary row is made permanent, when moving down to the next new temporary row, or if the modification flag of one of the fields is set. The modification flag of a field is typically set when the user enters data in the form field and tabs to another field (or validates the dialog), but this modification flag can also be set by program, with a DISPLAY TO / BY NAME instruction or with the DIALOG.setFieldTouched() method. When the modification is set by program, NOENTRY fields are ignored, however, fields dynamically disabled by DIALOG.setFieldActive() are taken into account.

Explicit temporary row creation

Explicit temporary row creation takes place when the user decided to append a new row explicitly with the append action. If the list is empty, an insert action will have the same effect as an append action (i.e. a temporary row will be created at position 1).

Automatic temporary row creation

By default, automatic temporary row creation takes place when:

Avoiding temporary row creation

Temporary row creation is useful because, in most cases, INPUT ARRAY is used to edit existing rows and append new rows at the end of the list. However, you might want to deny row addition or at least avoid the automatic temporary row creation when the last row is deleted or when an empty list gets the focus.

To avoid explicit temporary row creation, prevent INPUT ARRAY to defined the implicit append action by setting the APPEND ROW attribute to FALSE in the ATTRIBUTE clause:
...
   INPUT ARRAY p_items FROM sa.* ATTRIBUTES(APPEND ROW=FALSE)
   ...
   END INPUT
...
Even if APPEND ROW /INSERT ROW attributes are set to FALSE, automatic temporary row can still occur when the user deletes the last row of the list or if the list is empty when the INPUT ARRAY is entered. Without automatic temporary row creation, an INPUT ARRAY instruction would have no rows to edit if the array is empty. To avoid automatic temporary row creation is such cases, set the AUTO APPEND attribute to FALSE:
...
   INPUT ARRAY p_items FROM sa.* ATTRIBUTES(AUTO APPEND=FALSE)
   ...
   END INPUT
...

To fully deny row addition, set both APPEND ROW and AUTO APPEND to FALSE.

If both APPEND ROW and INSERT ROW attributes are set to FALSE, the dialog will deny explicit temporary row creation but also automatic temporary row creation, as if AUTO APPEND = FALSE would be used.

Row creation control blocks for temporary rows

In order to control row creation, use the BEFORE INSERT and AFTER INSERT control blocks. The BEFORE INSERT trigger is invoked after a new row was inserted or appended, just before the user gets control to enter data in fields. Regarding temporary rows, the AFTER INSERT block is invoked if data has been entered and you leave the new row (for example, when the focus moves to another row or leaves the current list), or if the dialog is validated, for example with ACCEPT DIALOG in case of DIALOG (or ACCEPT INPUT in case of singular INPUT ARRAY). No AFTER INSERT block is invoked if the user did not enter data: The temporary row is automatically deleted.

In the BEFORE INSERT control block, you can tell if a row is a temporary appended one by comparing the current row (DIALOG.getCurrentRow() or ARR_CURR()) with the total number of rows (DIALOG.getArrayLength() or ARR_COUNT()). If the current row index equals the row count, you are in a temporary row.

AFTER ROW and temporary rows

When a temporary row as automatically removed, the AFTER ROW block will be executed for the temporary row, but ui.Dialog.getCurrentRow() / ARR_CURR() will be one row greater than DIALOG.getArrayLength() / ARR_COUNT(). In this case, ignore the AFTER ROW event.