Back to Contents


Array Display

Summary:

See also: Arrays, Records, Result Sets, Programs, Windows, Forms, Input Array


Basics

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.

The full list mode

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. 

The paged mode

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.


DISPLAY ARRAY

Purpose:

The DISPLAY ARRAY instruction controls the display of a program array on the screen.

Syntax:

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
}

Notes:

  1. record-array is a static or dynamic array containing the records you want to display.
  2. screen-array is the name of the screen array used to display data.
  3. help-number is an integer that allows you to associate a help message number with the instruction.
  4. key-name is an hot-key identifier (such as F11 or Control-z).
  5. action-name identifies an action that can be executed by the user.
  6. field-name identifies a field used in the dialog instruction.
  7. idle-seconds is an integer expression that defines a number of seconds.
  8. statement is any instruction supported by the language.

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.

Usage:

When the runtime system encounters an DISPLAY ARRAY statement, it does the following::

  1. Displays the program array values in the screen array fields.
  2. Selects the first screen record in the list.
  3. Waits for the user to initiate an action on the list (scrolling, validation, or cancellation).

The DISPLAY ARRAY statement does not terminate until the user validates or cancels the dialog.

Warnings:

  1. The INVISIBLE attribute is ignored.
  2. The ON KEY blocks are supported for backward compatibility, use ON ACTION instead.

Tips:

  1. If you want to display data to a reduced set of columns, you must define a second screen array in the form file, containing the limited list of form fields. Then you can use the second screen array in a DISPLAY ARRAY a TO sa.* instruction.

Programming Steps

The following steps describe how to use the DISPLAY ARRAY statement:

  1. Create a form specification file containing a screen array. The screen array identifies the presentation elements to be used by the runtime system to display the rows.
  2. Make sure that the program controls interruption handling with DEFER INTERRUPT, to manage the validation/cancellation of the interactive dialog.
  3. Define an array of records with the DEFINE instruction. The members of the program array must correspond to the elements of the screen array, by number and data types. You can use a static or a dynamic array for a full list mode, but you must use a dynamic array for a paged mode.
  4. Open and display the form, using an OPEN WINDOW with the WITH FORM clause.
  5. If you want to use the full list mode, fill the program array with data, for example with a result set cursor, counting the number of program records being filled with retrieved data.
  6. Use the DISPLAY ARRAY statement to display the values. When using a static array, specifying the number of rows with the COUNT attribute in the ATTRIBUTE clause.
  7. If you want to use the paged mode, add the ON FILL BUFFER clause inside the instruction, and write the code to fill the dynamic array with the expected rows from fgl_dialog_getBufferStart() to fgl_dialog_getBufferLength().
  8. Inside the DISPLAY ARRAY statement, control the behavior of the selection list with BEFORE DISPLAY, BEFORE ROW, AFTER ROW, AFTER DISPLAY and ON KEY blocks.
  9. After the DISPLAY ARRAY statement, test the INT_FLAG predefined variable to check if the interactive dialog was canceled ( INT_FLAG = TRUE ) or validated ( INT_FLAG = FALSE ).
  10. If needed, get the selected row with the ARR_CURR() built-in function.

Variable Binding

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 change
03       LET arr[arr_curr()].field1 = newValue()
04 ...

Instruction Configuration

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.

Default Actions

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       ...

Control Blocks

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.

Interaction Blocks

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 10
03       IF ask_question("Do you want to leave the dialog?") THEN
04          EXIT DISPLAY
05       END IF
06 ...

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 zoom
03       CALL zoom_customers() RETURNING st, cust_id, cust_name
04       ...

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.

Control Block Execution Order

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
  1. BEFORE DISPLAY
  2. BEFORE ROW
Moving to a different row
  1. AFTER ROW (the current row)
  2. BEFORE ROW (the new row)
Validating the dialog
  1. AFTER ROW
  2. AFTER DISPLAY
Canceling the dialog
  1. AFTER ROW
  2. AFTER INPUT

Control Instructions

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.

Control Class

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 DISPLAY
03       CALL DIALOG.setActionActive("refresh",FALSE)

Control Functions

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().


SCROLL

Purpose:

The SCROLL instruction specifies vertical movements of displayed values in all or some of the fields of a screen array within the current form.

Syntax:

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
} [,...]

Notes:

  1. field-name is the identifier of a field of the current form.
  2. table-name is the identifier of a database table of the current form.
  3. screen-record is the identifier of a screen record of the current form.
  4. screen-array is the name of the screen array used of the current form.
  5. lines is an integer literal or variables that specifies how far (in lines) to scroll the display.

Warnings:

  1. This instruction in only supported for backward compatibility, it is not recommended to use it for graphical applications.

Examples

Example 1: Full list mode

Form definition file "custlist.per":

01 DATABASE stores
02
03 LAYOUT
04 TABLE
05 {
06  Id       Name         LastName
07 [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 END
15 END
16 
17 TABLES
18 customer
19 END
20
21 ATTRIBUTES
22 f001 = customer.customer_num;
23 f002 = customer.fname;
24 f003 = customer.lname;
25 END
26
27 INSTRUCTIONS
28 DELIMITERS "||";
29 SCREEN RECORD srec[6] (
30        customer.customer_num,
31        customer.fname,
32        customer.lname);
33 END

Application:

01 MAIN
02   DEFINE cnt INTEGER
03   DEFINE arr ARRAY[500] OF RECORD
04             id INTEGER,
05             fname CHAR(30),
06             lname CHAR(30)
07         END RECORD 
08   DATABASE stores7
09   OPEN FORM f1 FROM "custlist"
10   DISPLAY FORM f1
11   DECLARE c1 CURSOR FOR
12          SELECT customer_num, fname, lname FROM customer
13   LET cnt = 1
14   FOREACH c1 INTO arr[cnt].*
15     LET cnt = cnt + 1
16   END FOREACH
17   LET cnt = cnt - 1
18   DISPLAY ARRAY arr TO srec.* ATTRIBUTES(COUNT=cnt)
19     ON ACTION print
20        DISPLAY "Print a report"
21   END DISPLAY
22 END MAIN

Example 2: Paged mode

Form definition file "custlist.per" (same as example 1)

Application:

01 MAIN
02   DEFINE arr DYNAMIC ARRAY OF RECORD
03             id INTEGER,
04             fname CHAR(30),
05             lname CHAR(30)
06         END RECORD 
07   DEFINE cnt, ofs, len, i INTEGER
08   DATABASE stores7
09   OPEN FORM f1 FROM "custlist"
10   DISPLAY FORM f1
11   SELECT COUNT(*) INTO cnt FROM customer
12   DECLARE c1 SCROLL CURSOR FOR
13          SELECT customer_num, fname, lname FROM customer
14   OPEN c1
15   DISPLAY ARRAY arr TO srec.* ATTRIBUTES(COUNT=cnt)
16     ON FILL BUFFER
17        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 len
21           FETCH ABSOLUTE ofs+i-1 c1  INTO arr[i].*
22        END FOR
23     AFTER DISPLAY
24        IF NOT int_flag THEN
25           DISPLAY "Selected customer is #"
26                   || arr[arr_curr()-ofs+1].id
27        END IF
28   END DISPLAY
29   CLOSE c1
30 END MAIN