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 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 full list mode, you must copy all the data you want to display into the array. In paged mode, you 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 total number of rows is defined by the COUNT attribute. The program array is filled dynamically with data rows as needed during the DISPLAY ARRAY execution. 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.

Warnings:

  1. With paged mode, the user cannot sort data by clicking on a column header.

DISPLAY ARRAY

Purpose:

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

Syntax:

DISPLAY ARRAY array TO screen-array.*
  [ HELP help-number ]
 
[ ATTRIBUTES ( { display-attribute | control-attribute } [,...] ) ]
[
 dialog-control-block
 
[...]
END DISPLAY ]

where dialog-control-block is one of :

{ BEFORE DISPLAY
| AFTER DISPLAY
| BEFORE ROW
| AFTER ROW
| ON IDLE idle-seconds
| ON ACTION action-name
| ON FILL BUFFER
| ON KEY ( key-name [,...] )
}
    dialog-statement
    [...]

where dialog-statement is one of :

{ statement
| EXIT DISPLAY
| CONTINUE DISPLAY
| ACCEPT DISPLAY
}

Notes:

  1. 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 associates 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. idle-seconds is an integer literal or variable that defines a number of seconds.
  7. statement is any instruction supported by the language.

The following table shows the display-attributes supported by the DISPLAY ARRAY statement. The display-attributes affect console-based applications only, they do not affect GUI-based applications.

Attribute Description
BLACK, BLUE, CYAN, GREEN, MAGENTA, RED, WHITE, YELLOW The color of the displayed data.
BOLD, DIM, NORMAL The font attribute of the displayed data.
REVERSE, BLINK, UNDERLINE 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 when using a static array or the paged mode. 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 cancel action should be added to the dialog. If not specified, the action is registered.
ACCEPT = bool Indicates if the default accept action should be added to the dialog. If not specified, the action is registered.

Usage:

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 or the OPEN FORM / DISPLAY FORM instructions.
  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 ATTRIBUTES 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.

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.

Warnings:

  1. The INVISIBLE attribute is ignored.
  2. While the ON KEY block is supported for backward compatibility, it is recommended that you use ON ACTION instead.

Variable Binding

The DISPLAY ARRAY statement binds the members of the array of record to the screen array fields specified with the TO keyword. 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).

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

HELP option

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.

Warnings:

  1. The HELP option overrides the HELP attribute!
COUNT option

When using a static array or the paged mode, 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.

KEEP CURRENT ROW option

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.

ACCEPT option

The ACCEPT attribute can be set to FALSE to avoid the automatic creation of the accept default action. Use this attribute when you want to write a specific validation procedure by using ACCEPT DISPLAY.

CANCEL option

The CANCEL attribute can be set to FALSE to avoid the automatic creation of the cancel default action. Use this attribute when you only need a validation action (accept), or when you want to write a specific cancellation procedure by using EXIT DISPLAY.

Note that if the CANCEL=FALSE option is set, no close action will be created, and you must write an ON ACTION close control block to create an explicit action.


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 Description
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.
firstrow Moves to the first row in the list.
lastrow Moves to the last row in the list.
nextrow Moves to the next row in the list.
prevrow Moves to the previous row in the list.

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

BEFORE DISPLAY block

The BEFORE DISPLAY block is executed one time, before the runtime system gives control to the user. You can implement dialog initialization tasks in this block.

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

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

AFTER ROW block

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.

ON FILL BUFFER block

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

 See Example 2 for a typical paged mode implementation.

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:

Context / 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

Interaction Blocks

ON IDLE block

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 literal or variable. 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 ...
ON ACTION block

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       ...
ON KEY block

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 Instructions

Continuing the dialog: CONTINUE DISPLAY

CONTINUE DISPLAY skips all subsequent statements in the current control block and gives the control back to the dialog. This instruction is useful when program control is nested within multiple conditional statements, and you want to return the control to the dialog. Note that if this instruction is called in a control block that is not AFTER DISPLAY, further control blocks might be executed according to the context. Actually, CONTINUE DISPLAY just instructs the dialog to continue as if the code in the control block was terminated (i.e. it's a kind of GOTO end_of_control_block). However, when executed in AFTER DISPLAY, the focus returns to the current row in the list, giving the user another chance to browse and select a row. In this case the BEFORE ROW of the current row will be fired.

Leaving the dialog: EXIT DISPLAY

You can use the EXIT DISPLAY to terminate the DISPLAY ARRAY instruction and resume the program execution at the instruction immediately following the DISPLAY ARRAY block.

Validating the dialog: ACCEPT DISPLAY

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.


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 ui.Dialog.setActionActive() dialog method, or you can hide and show a default action view with ui.Dialog.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:


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. It is recommended that you NOT use this instruction in GUI mode.

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
09   DATABASE stores7
10   
11   OPEN FORM f1 FROM "custlist"
12   DISPLAY FORM f1
13
14   DECLARE c1 CURSOR FOR
15     SELECT customer_num, fname, lname FROM customer
16   LET cnt = 1
17   FOREACH c1 INTO arr[cnt].*
18     LET cnt = cnt + 1
19   END FOREACH
20   LET cnt = cnt - 1
21   DISPLAY ARRAY arr TO srec.* ATTRIBUTES(COUNT=cnt)
22     ON ACTION print
23        DISPLAY "Print a report"
24   END DISPLAY
25 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
09   DATABASE stores7
10
11   OPEN FORM f1 FROM "custlist"
12   DISPLAY FORM f1
13
14   SELECT COUNT(*) INTO cnt FROM customer
15   DECLARE c1 SCROLL CURSOR FOR
16          SELECT customer_num, fname, lname FROM customer
17   DISPLAY ARRAY arr TO srec.* ATTRIBUTES(COUNT=cnt)
18     ON FILL BUFFER
19        OPEN c1
20        LET ofs = fgl_dialog_getBufferStart()
21        LET len = fgl_dialog_getBufferLength()
22        -- Warning: Fill the array from index 1 to len!
23        FOR i=1 TO len
24           FETCH ABSOLUTE ofs+i-1 c1 INTO arr[i].*
25        END FOR
26        CLOSE c1
27     AFTER DISPLAY
28        IF NOT int_flag THEN
29           DISPLAY "Selected customer is #"
30                   || arr[arr_curr()-ofs+1].id
31        END IF
32   END DISPLAY
33 END MAIN