Summary:
See also: Arrays, Records, Result Sets, Programs, Windows, Forms, Input Array
With DISPLAY ARRAY, you can let the user browse in a list of records, using a static or dynamic array as the data buffer. The DISPLAY ARRAY instruction can work in full list mode or in paged mode. In the full list mode, you must copy into the array all the data you want to display, while the paged mode allows you to provide data rows dynamically during the dialog, using a dynamic array to hold one page of data. The full list mode should be used for a short and static list of rows, while the paged mode can be used for an infinite number of rows. Additionally, the paged mode allows you to fetch fresh data from the database.
In full list mode, the DISPLAY ARRAY instruction uses a static or dynamic program array defined with a record structure corresponding to (or to a part of ) a screen-array of a form. The program array is filled with data rows before DISPLAY ARRAY is executed. In this case, the list is static and cannot be updated until the instruction is exited.
In paged mode, the DISPLAY ARRAY instruction uses a dynamic program array defined with a record structure corresponding to (or to a part of ) a screen-array of a form. The program array is filled dynamically with data rows during the DISPLAY ARRAY execution, as needed. The ON FILL BUFFER clause is required, to feed the DISPLAY ARRAY instruction with pages of data. The statements in the ON FILL BUFFER clause are executed automatically by the runtime system each time a new page of data is needed.
The DISPLAY ARRAY instruction controls the display of a program array on the screen.
DISPLAY ARRAY record-array TO screen-array.*
[ HELP help-number ]
[ ATTRIBUTE ( { display-attribute |
control-attribute } [,...] ) ]
[ dialog-control-block
[...]
END DISPLAY ]
where dialog-control-block is one of :
{ BEFORE DISPLAY
dialog-statement
[...]
| AFTER DISPLAY
dialog-statement
[...]
| BEFORE ROW
dialog-statement
[...]
| AFTER ROW
dialog-statement
[...]
| ON IDLE idle-seconds
dialog-statement
[...]
| ON ACTION action-name
dialog-statement
[...]
| ON FILL BUFFER
dialog-statement
[...]
| ON KEY ( key-name [,...] )
dialog-statement
[...]
}
where dialog-statement is one of :
{ statement
| EXIT DISPLAY
| CONTINUE DISPLAY
| ACCEPT DISPLAY
}
The following table shows the display-attributes supported by the DISPLAY ARRAY statement:
Attribute | Description |
BLACK, BLUE, CYAN, GREEN, MAGENTA, RED, WHITE, YELLOW Console Only! |
The color of the displayed data. |
BOLD, DIM, NORMAL Console Only! |
The font attribute of the displayed data. |
REVERSE, BLINK, UNDERLINE Console Only! |
The video attribute of the displayed data. |
The following table shows the control-attributes supported by the DISPLAY ARRAY statement:
Attribute | Description |
COUNT = row-count | Defines the number of data rows in the static array. Here row-count can be an integer literal or a program variable. This is the equivalent of the SET_COUNT() built-in function. |
HELP = int-expr | Defines the help number when help is invoked by the user. |
KEEP CURRENT ROW [=bool] | Keeps current row highlighted after execution of the instruction. |
UNBUFFERED [ =bool] | Indicates that the dialog must be sensitive to program variable changes. The bool parameter can be an integer literal or a program variable. |
CANCEL = bool | Indicates if the default action 'cancel' should be added to the dialog. If not specified, the action is registered. |
ACCEPT = bool | Indicates if the default action 'accept' should be added to the dialog. If not specified, the action is registered. |
When the runtime system encounters an DISPLAY ARRAY statement, it does the following::
The DISPLAY ARRAY statement does not terminate until the user validates or cancels the dialog.
The following steps describe how to use the DISPLAY ARRAY statement:
fgl_dialog_getBufferStart()
to
fgl_dialog_getBufferLength()
.The DISPLAY ARRAY statement binds the screen array fields to the member records of the program array. The number of variables in each record of the program array must be the same as the number of fields in each screen record (that is, in a single row of the screen array). Each mapped variable must have the same data type or a compatible data type as the corresponding field.
When using the UNBUFFERED attribute, the instruction is sensitive to program variable changes. This means that you do not have to DISPLAY the values; setting the program variable used by the dialog automatically displays the data into the corresponding form field.
01
...02
ON ACTION change03
LET arr[arr_curr()].field1 = newValue()04
...
The ATTRIBUTE clause specifications override all default attributes and temporarily override any display attributes that the OPTIONS or the OPEN WINDOW statement specified for these fields. While the DISPLAY ARRAY statement is executing, the runtime system ignores the INVISIBLE attribute.
The HELP clause specifies the number of a help message to display if the user invokes the help while executing the instruction. The predefined 'help' action is automatically created by the runtime system. You can bind action views to the 'help' action.
When using a static array, the number of rows to be displayed is defined by the COUNT attribute. You can also use the SET_COUNT() built-in function, but it is supported for backward compatibility only. When using a dynamic array, the number of rows to be displayed is defined by the number of elements in the dynamic array (the COUNT attribute is ignored).
Depending on the list container used in the form, the current row may be highlighted during the execution of the dialog, and cleared when the instruction ends. You can change this default behavior by using the KEEP CURRENT ROW attribute, to force the runtime system to keep the current row highlighted.
When an DISPLAY ARRAY instruction executes, the runtime system creates a set of default actions. See the control block execution order to understand what control blocks are executed when a specific action is fired.
The following table lists the default actions created for this dialog:
Default action | Control Block execution order |
accept | Validates the DISPLAY ARRAY dialog (validates current row
selection) Creation can be avoided with ACCEPT attribute. |
cancel | Cancels the DISPLAY ARRAY dialog (no validation, int_flag is set) Creation can be avoided with CANCEL attribute. |
close | By default, cancels the DISPLAY ARRAY dialog (no validation, int_flag is set) Default action view is hidden. See Windows closed by the user. |
help | Shows the help topic defined by the HELP clause. Only created when a HELP clause is defined. |
nextrow | Moves to the next row in a list displayed in one row of fields. Only created if DISPLAY ARRAY used with a screen record having only one row. |
prevrow | Moves to the previous row in a list displayed in one row of fields. Only created if DISPLAY ARRAY used with a screen record having only one row. |
The accept and cancel default actions can be avoided with the ACCEPT and CANCEL dialog control attributes:
01
DISPLAY ARRAY arr TO sr.* ATTRIBUTES( CANCEL=FALSE, ... )02
...
The BEFORE DISPLAY block is executed one time, before the runtime system gives control to the user. You can implement some initialization in this block.
The AFTER DISPLAY block is executed one time, after the user has validated or canceled the dialog and before the runtime system executes the instruction that appears just after the DISPLAY ARRAY block. You typically implement dialog finalization in this block.
The BEFORE ROW block is executed each time the user moves to another row, after the destination row is made the current one. When called in this block, the ARR_CURR() function returns the index of the current row.
The AFTER ROW block is executed each time the user moves to another row, before the current row is left. When called in this block, the ARR_CURR() function returns the index of the current row.
The ON FILL BUFFER clause is provided to fill a page of rows into the dynamic array, according to an offset and a number of rows. The offset can be retrieved with the FGL_DIALOG_GETBUFFERSTART() built-in function and the number of rows to provide is defined by the FGL_DIALOG_GETBUFFERLENGTH() built-in function. A typical paged display array consists of a scroll cursor providing the list of records to be displayed (see Example 2 for a simple usage example). Scroll cursors use a static result set. If you want to display fresh data, you can write advanced paged display array instructions by using a scroll cursor providing the primary keys of the reference result set, plus a prepared cursor used to fetch rows on demand in the ON FILL BUFFER clause. In this case you may need to check if a row still exists when fetching a record with the second cursor.
The ON IDLE idle-seconds clause defines a set of instructions that must be executed after idle-seconds of inactivity. This can be used, for example, to quit the dialog after the user has not interacted with the program for a specified period of time. The parameter idle-seconds must be an integer expression. If it evaluates to zero, the timeout is disabled.
01
...02
ON IDLE 1003
IF ask_question("Do you want to leave the dialog?") THEN04
EXIT DISPLAY05
END IF06
...
You can use ON ACTION blocks to execute a sequence of instructions when the user raises a specific action. This is the preferred solution compared to ON KEY blocks, because ON ACTION blocks use abstract names to control user interaction.
01
...02
ON ACTION zoom03
CALL zoom_customers() RETURNING st, cust_id, cust_name04
...
For backward compatibility, you can use ON KEY blocks to execute a sequence of instructions when the user presses a specific key. The following key names are accepted by the compiler:
Key Name | Description |
ACCEPT | The validation key. |
INTERRUPT | The interruption key. |
ESC or ESCAPE | The ESC key (not recommended, use ACCEPT instead). |
TAB | The TAB key (not recommended). |
Control-char | A control key where char can be any character except A, D, H, I, J, K, L, M, R, or X. |
F1 through F255 | A function key. |
DELETE | The key used to delete a new row in an array. |
INSERT | The key used to insert a new row in an array. |
HELP | The help key. |
LEFT | The left arrow key. |
RIGHT | The right arrow key. |
DOWN | The down arrow key. |
UP | The up arrow key. |
PREVIOUS or PREVPAGE | The previous page key. |
NEXT or NEXTPAGE | The next page key. |
The following table shows the order in which the runtime system executes the control blocks in the DISPLAY ARRAY instruction, according to the user action:
User action | Control Block execution order |
Entering the dialog |
|
Moving to a different row |
|
Validating the dialog |
|
Canceling the dialog |
|
The CONTINUE DISPLAY instruction continues the execution of the DISPLAY ARRAY block, skipping all statements appearing after this instruction. Use this instruction to give control back to the interactive dialog, for example after testing for a special situation where the user must continue to scroll in the list of records.
You can use the EXIT DISPLAY to terminate the DISPLAY ARRAY instruction and resume the program execution at the instruction following the DISPLAY ARRAY block.
The ACCEPT DISPLAY instruction validates the DISPLAY ARRAY instruction and exits the DISPLAY ARRAY instruction. The AFTER DISPLAY control block will be executed. Statements after ACCEPT DISPLAY will not be executed: the statement acts like a CONTINUE DISPLAY.
Inside the dialog instruction, the predefined keyword DIALOG represents the current dialog object. It can be used to execute methods provided in the dialog built-in class.
For example, you can enable or disable an action with the setActionAction() dialog method, or you can also hide and show the default action view with setActionHidden():
01
...02
BEFORE DISPLAY03
CALL DIALOG.setActionActive("refresh",FALSE)
The language provides several built-in functions and operators to use in a DISPLAY ARRAY statement. You can use the following built-in functions to keep track of the relative states of the current row, the program array, and the screen array or to access the field buffers and keystroke buffers. These functions and operators are listed here: ARR_CURR(), FGL_SET_ARR_CURR(), ARR_COUNT(), SCR_LINE(), SET_COUNT().
The SCROLL instruction specifies vertical movements of displayed values in all or some of the fields of a screen array within the current form.
SCROLL field-list { UP | DOWN } [ BY lines
]
where field-list is :
{ field-name
| table-name.*
| table-name.field-name
| screen-array[line].*
| screen-array[line].field-name
|
screen-record.*
|
screen-record.field-name
}
[,...]
Form definition file "custlist.per":
01
DATABASE stores02
03
LAYOUT04
TABLE05
{06
Id Name LastName07
[f001 |f002 |f003 ]08
[f001 |f002 |f003 ]09
[f001 |f002 |f003 ]10
[f001 |f002 |f003 ]11
[f001 |f002 |f003 ]12
[f001 |f002 |f003 ]13
}14
END15
END16
17
TABLES18
customer19
END20
21
ATTRIBUTES22
f001 = customer.customer_num;23
f002 = customer.fname;24
f003 = customer.lname;25
END26
27
INSTRUCTIONS28
DELIMITERS "||";29
SCREEN RECORD srec[6] (30
customer.customer_num,31
customer.fname,32
customer.lname);33
END
Application:
01
MAIN02
DEFINE cnt INTEGER03
DEFINE arr ARRAY[500] OF RECORD04
id INTEGER,05
fname CHAR(30),06
lname CHAR(30)07
END RECORD08
DATABASE stores709
OPEN FORM f1 FROM "custlist"10
DISPLAY FORM f111
DECLARE c1 CURSOR FOR12
SELECT customer_num, fname, lname FROM customer13
LET cnt = 114
FOREACH c1 INTO arr[cnt].*15
LET cnt = cnt + 116
END FOREACH17
LET cnt = cnt - 118
DISPLAY ARRAY arr TO srec.* ATTRIBUTES(COUNT=cnt)19
ON ACTION print20
DISPLAY "Print a report"21
END DISPLAY22
END MAIN
Form definition file "custlist.per" (same as example 1)
Application:
01
MAIN02
DEFINE arr DYNAMIC ARRAY OF RECORD03
id INTEGER,04
fname CHAR(30),05
lname CHAR(30)06
END RECORD07
DEFINE cnt, ofs, len, i INTEGER08
DATABASE stores709
OPEN FORM f1 FROM "custlist"10
DISPLAY FORM f111
SELECT COUNT(*) INTO cnt FROM customer12
DECLARE c1 SCROLL CURSOR FOR13
SELECT customer_num, fname, lname FROM customer14
OPEN c115
DISPLAY ARRAY arr TO srec.* ATTRIBUTES(COUNT=cnt)16
ON FILL BUFFER17
LET ofs = fgl_dialog_getBufferStart()18
LET len = fgl_dialog_getBufferLength()19
-- Warning: Fill the array from index 1 to len!20
FOR i=1 TO len21
FETCH ABSOLUTE ofs+i-1 c1 INTO arr[i].*22
END FOR23
AFTER DISPLAY24
IF NOT int_flag THEN25
DISPLAY "Selected customer is #"26
|| arr[arr_curr()-ofs+1].id27
END IF28
END DISPLAY29
CLOSE c130
END MAIN