# CHAPTER 8: Multi-Fields Record Display

Empress 4GL has the capability to handle more than one record at a time in an application. One screen can work with several records, simplifying the coding of the application. This is accomplished with multi-record displays, also known as multis.

## 8.1 Multi-Fields

The heart of an Empress 4GL multi is the multi-field. When you create a form, you can also create two different types of fields. The normal fields hold a single value, while multi-fields are arrays that hold several values. A multi-field also has an index which is called the field number.

### 8.1.1 On the Form

In order to make a multi-field, the Form Editor must be in `multi` mode. When it is, every field that you create with more than one line will be a multi-field, with each line of the field being one. This allows multi-fields to be created as columns of elements.

Since a multi-field may need to be other than a column of single line field elements, you can build multi-fields by joining fields together when in multi mode. This is a more powerful tool since multi-fields do not need to appear one after the other. You can create multi-fields with elements that are multiple line normal fields, all on the same line, or using the join, even several columns of elements.

Normally, a multi-field will have the same characteristics for each element. It is possible to alter the characteristics for individual elements by placing the Form Editor into `normal` mode and changing the characteristics of an individual element. In this way, some elements of the multi can be normal video fields, some reverse, some filled, some not, and so on.

Note that changing the name of one element of the multi-field will remove that element from the multi and make it a normal field by itself, even though it may still be in the middle of the multi. To correct this, you must put Editor in `multi` mode and join the fields together again.

### 8.1.2 In the Window

When an application uses a multi-field, you must define the multi-field within the application as you would for any normal field. However, there are differences that are important when dealing with multi-fields.

One major difference that needs to be considered is the field number. For normal fields the field number "1" is always used. With multi-fields the field number can range from "0" to the maximum number of elements.

The field number "0" is a special case. Any definition which uses field number "0" means that the definition applies to all elements of the multi-field unless they are specifically overridden by another definition. Definitions that have specific field numbers will apply only to that element of the multi.

For example, you create a multi-field with seven elements. Each element of the multi is the same except for the enter script of the last element. A definition with field number "0" will be created which defines all the characteristics of the field including an enter and exit script. Then an entry for field number "7" will be created but the only characteristic that will be different will be the enter script.

Note that all of the characteristics will have to be defined in both definitions. The definition for field number "7" will not assume the values from that for field number "0".

When the application runs, each of the elements will behave identically except for the last one, which has a different enter script.

## 8.2 Definition of Multi-Fields

It is possible to build an application which uses multi-fields and explicitly controls details such as what line is being worked with, when to scroll, and how to update the fields. However, Empress 4GL has several functions which make working with multis much easier.

The `define_multi` function is the starting point. This function has the following syntax:

        CALL define_multi (context, window, next_line,

                prev_line, display_script, lock_script,

                fill_script [, field {, field}])

This function sets up what is known as a multi. As you can see, the function has several items defined in it.

### 8.2.1 Context

The first parameter for the `define_multi` function is the context of records. This must be defined either by executing a `SELECT` or `DEFINE SELECT` statement. The actual context can be re-selected as many times as necessary without having to re-define the multi, but the `define_multi` function needs to know about the context in some way first.

If the same selection criteria are to be used every time the selection is performed, the best solution is the `DEFINE SELECT` statement, since it does not actually have to select any records from the tables. However, if the selection criteria are going to change then you need to perform an initial selection.

If the second option is used, care must be taken with the initial select. If the records are not going to be used (i.e., the select is only so the context will be defined) then it is best to arrange the criteria such that no records are selected. The context will still be defined, but no records will have to be locked.

### 8.2.2 Window and Fields

The second parameter of the `define_multi` is the window name. This is the window that the records will be displayed in. There can be only one window per multi that you define.

This window must display a form that has multi-fields. Not all fields have to be multis, but there must be at least one.

As well, all multi-fields involved in the multi must have the same number of elements. Otherwise, there will not be enough room for the last few records. For example, if there are five elements in the name field and four in the address, the fifth record that the application attempts to display will fail as there is no space for the address.

When you define the fields in the application, you should define the next and previous fields to keep the cursor on the same line when the `next_field` or `previous_field` functions are executed. Otherwise, the cursor is free to move through the fields from line to line when the current record is not being kept in synchrony. Functions which move the cursor to the next line while keeping the current record within the context in synchrony, will be described in Chapter 8.3.

### 8.2.3 Next and Previous Line

The next two parameters define the scrolling for the multi. The next line is the field number that a new record should be put into if the user requests the next record when the cursor is on the last line of the multi.

For example, if there are five lines on the multi and the cursor is on the fifth line, you will need to scroll to get the next record. A new set of records must be displayed. If you set the "next line" parameter to "1", the next record will be placed in line 1 of the multi with four records following it. If you set the parameter to "5", the next record would be on the fifth line with the currently displayed records scrolling accordingly.

The "previous line" parameter controls the action when someone requests a previous record when the cursor is on the top line of the multi.

If you use a value of "0" for the parameter, it indicates the largest possible line number. For the example above, "0" would translate to "5". You can also use the `largest_field_number` function to achieve the same results.

Typically the values for these two parameters are "1, 0". These values let you scroll page by page. If you use "0, 1", you would be able to scroll line by line. These values are often used as well.

### 8.2.4 Scripts

The next three parameters are the names of subscripts that the multi uses at various points. They are the display script, locked script, and fill script.

The display script is used when the multi needs to put values from the context into the fields. This script should have all the commands to create one line of the display from the current records of the context. If the fields have been appropriately named, you can use the `set_field_values` function or any commands which assign the values to the fields.

The display script, locked script, or fill script must be set up to deal with fields which have the same field number as the current field. There should never be any mention made of an explicit field number. If the display script contains a command such as `call set_field_values,` all the records would be written into the fields on line "1" of the multi. The field number should be left alone (or set to "0" where a field number is required) indicating the field number is that of the current field.

The only exception to this is when dealing with fields that are not part of the multi. You should not deal with fields in the display script. If you do, you must refer to the fields by their field numbers, because the default is to use the field number of the current field.

The locked script is used when a record that should be displayed is unavailable because it is locked. When this occurs, Empress 4GL has to inform the user that a record should be entered into this location, but the application cannot access it. Usually a locked script will clear the fields on the line and enter a value into one of the fields to indicate that the record is locked. You can do this by using:

        CALL set_field_values ("win", "con", 0, NULL)

The fill script is used when there are not enough records to fill up all the lines in the multi. This script clears the fields or indicates there are no more records to display. It is important because if the user scrolls past a page, the last few lines may be left untouched. If there is no fill script, these will contain the values of the previous records which could mislead the user.

### 8.2.5 Field List

The last parameters of the `define_multi` function are the list of fields. This is optional. If you do not use this parameter, Empress 4GL will assume all of the fields in the window are to be used in the multi. Problems will eventually arise if there are any normal fields or even multi-fields with the wrong number of elements. In this case it is important that you specify the list of multi-fields involved.

## 8.3 Using a Multi-Field

Once you define a multi, the application can use it. First, select the appropriate records. This will display the initial set of records. If the window does not appear, you must execute a `show_window` function. At this point, you have the option to make the window current.

The user can control what happens in the window once this is completed. Among other things, the user can:

- move from one record in the multi to the next
- scroll by pages or by a certain number of records
- request a new set of records to be selected and displayed

### 8.3.1 Loading the Multi

After selecting the context that the multi will use, the `display_page` function loads the initial records into the window. The optional parameter is the context name. This parameter is only necessary if the window for the multi is not the current window. If the context is not specified, Empress 4GL will determine which context to use based on the current window name. If you define the context name, Empress 4GL determines which window is appropriate.

This function will load the first `n` records into the fields where "`n`" is the maximum field number in the multi. It will make each line current in turn and use the display script that you indicated in the definition to display the current record. If it encounters a locked record the locked script will be used or that line. If there are no `n` records in the context, the last lines will be set with the fill script.

Once the records have been loaded, the current record will be set back to the first record and the appropriate field of the first line will be made current.

### 8.3.2 Moving the Cursor

When you use a multi, the cursor should always remain on the line that is displaying the current record. Otherwise, the user will work on the wrong record. For this reason, you should set the field definitions so that the next and previous fields for every field are on the same line. If the field number is left null for the next and previous fields, Empress 4GL will assume they are the same as the current field number. You must specify the field names though, or the default order will be used.

Five functions let the user move the cursor around in the records.

The first two are the `next_line` and `prev_line` functions. They are only available if the multi is using a current window. These functions take no parameters and they work with the current window. With these functions, you can:

- move the cursor to the next or previous line in the display if there is a record there
- move the current record in the context by one record in the direction you choose so the highlighted record in the window will correspond to the current record in the context

If the cursor is at last line of the multi when the `next_line` function is called, Empress 4GL will scroll the appropriate number of records into the window. This is determined by the next line parameter of the `define_multi`. Similarly, the `prev_line` will scroll if the cursor is at the top of the multi.

You must remember that any values changed on the screen will not be kept. If you re-display the record at a later time, the values will be those that are actually in the record. For this reason, any update operations you perform should be on a record-by-record basis and should always deal with the current record and current line on the multi. Make sure the users are aware of this and are trained to update on a line-by-line basis. If you do not want users to perform update operations, you should make the fields read only or skip to ensure they cannot be changed.

As well as line-by-line movement functions, Empress provides three functions to move by larger groups. The `next_page`, `prev_page`, and `scroll_page` functions perform these operations.

The `next_page` function brings in the next `n` records of the context and displays them in the window. If the context name is omitted then it will assume the context that is related to the current window, this is similar to the `display_page` function.

The `prev_page` function operates in the same way, except it moves backwards. The only difference is that if there are not enough records before the first one on the current screen, the appropriate number of records from the current screen will move to the bottom so that the first record of the context will be at the top of the multi.

When you use the `scroll_page` function, the appropriate number of records are moved off of the screen. The rest of the records are shifted up (or down) and the appropriate number of records from the context are brought in.

For each of these three functions, the cursor will always remain on the same line and the record represented will be made current.