Filling a COMBOBOX item list

The item list of COMBOBOX fields can be initialized at runtime.

Introduction to COMBOBOX fields

COMBOBOX fields are typically used when a field can hold a short predefined list of values. COMBOBOX fields are usually rendered with a drop-down list, from where the end user can choose a value.

Note: All items of a COMBOBOX list will be transmitted to the front-end. Therefore, the number of items that can be selected in a COMBOBOX fields should be limited to 20 to 50 items. If the selection list holds more items, consider using a BUTTONEDIT field, which opens a new window with a TABLE container.
COMBOBOX item lists can be defined in three different ways:
  1. In the form definition file, as a static list of items with single values.
  2. In the form definition file, as a static list of items with value/label pairs.
  3. At runtime when the form is loaded, as single values or value/label pairs.

In this topic we will learn how to implement a COMBOBOX field that is filled dynamically.

For static item list definitions, see COMBOBOX item type.

Defining the COMBOBOX initialization function

In order to fill a COMBOBOX field when the form file is loaded, use the INITIALIZER attribute to define the name of the function that will be called to fill the item list:

COMBOBOX f1 = FORMONLY.city, INITIALIZER=fill_city;

The initialization function name is case-insensitive.

Important: When the form is displayed, make sure that the initialization function is available (i.e. the .42m module where the function is defined is loaded).

Implementing the item list initialization function

The function defined with the INITIALIZER attribute takes a ui.ComboBox object as parameter.

To add items to the selection list of the COMBOBOX field, use the addItem() method of ui.ComboBox:

FUNCTION fill_city(cmb)
    DEFINE cmb ui.ComboBox
    CALL cmb.addItem(101,"Berlin")
    CALL cmb.addItem(102,"Madrid")
    CALL cmb.addItem(103,"London")
    CALL cmb.addItem(104,"Paris")
    CALL cmb.addItem(105,"Rome")
END FUNCTION
Note: If you want to define a list of items with single values, specify only the first parameter of addItem().

Detecting COMBOBOX value change

In order to detect a value change in a COMBOBOX, define the ON CHANGE dialog control block. The ON CHANGE block will be immediately executed when the user selects a new item in the list. One can typically clear other fields related to the COMBOBOX field:

   ON CHANGE city
      LET rec.address = NULL

NULL values in COMBOBOX fields

Pay attention to NULL value handling with COMBOBOX fields:
  • By default, if the field allows nulls, the item list automatically gets a NULL item.
  • Prefer to deny nulls with the NOT NULL attribute, and add a special item such as (0,"<Undefined>") to identify a non-specified-value.

Example

The next example shows how to implement the function to fill the item list of a COMBOBOX field with a list of cities. When the COMBOBOX field is changed, the ON CHANGE block is fired and the address field is cleared:

Form file (combobox.per):
LAYOUT
GRID
{
City   : [f1                      ]
Address: [f2                                              ]
}
END
END
ATTRIBUTES
COMBOBOX f1 = FORMONLY.city, INITIALIZER=fill_city;
EDIT f2 = FORMONLY.address;
END
Program file (combobox.4gl):
MAIN
    DEFINE rec RECORD
               city INTEGER,
               address VARCHAR(100)
           END RECORD

    OPEN FORM f1 FROM "combobox"
    DISPLAY FORM f1

    INPUT BY NAME rec.* ATTRIBUTES(UNBUFFERED)
        ON CHANGE city
           LET rec.address = NULL
    END INPUT

END MAIN

FUNCTION fill_city(cmb)
    DEFINE cmb ui.ComboBox
    CALL cmb.addItem(101,"Berlin")
    CALL cmb.addItem(102,"Madrid")
    CALL cmb.addItem(103,"London")
    CALL cmb.addItem(104,"Paris")
    CALL cmb.addItem(105,"Rome")
END FUNCTION