openUI

The openUI statement allows the user to interact with a program whose interface is based on Console UI. The statement defines user and program events and specifies how to respond to each.

You can end an openUI statement by issuing an exit openUI statement.

Syntax

Syntax of openUI Statement
OpenAttributes
A set of property-and-value pairs, each separated from the next by a comma. Each of the properties affects the user interaction, and some overwrite a property of the variable in OpenableElements. For more information on these properties, see openUI properties.
OpenableElements
The ConsoleUI variables on which the openUI statement can act:
  • ConsoleForm
  • A consoleField or one of these:
    • A list of consoleFields, each separated from the next by a comma
    • A dictionary that is declared in a consoleForm and refers to a set of consoleFields in that consoleForm
    • An arrayDictionary that is declared in a consoleForm and refers to a set of consoleField arrays in that consoleForm.
  • Menu
  • Prompt
  • Window
BindClause
The list of primitive variables, records, or arrays that are bound to the ConsoleUI variables. Characteristics of the binding variables depend on the characteristics of the consoleUI variable on which the openUI statement acts:
  • For a consoleField, you can specify a primitive variable.
  • For an on-screen arrayDictionary, you can specify an array of records, one element per row in the arrayDictionary; and if each row in the arrayDictionary represents a single value, you can specify an array of primitive variables.
  • For a dictionary or a list of consoleFields, you can specify a list of primitive variables. Alternatively, you can specify an array of records, with each element containing a series of fields that are bound to the consoleFields. This alternative is equivalent to binding a dynamic array with an on-screen arrayDictionary that has only one row; you can append, insert, or delete a record to change the dynamic array, and in any case only one record is displayed at a time.
  • For a prompt, you can specify a primitive field that receives the user's response.

For details on binding, see the description of the OnEventBlock parameter, as well as the topic "Console UI parts and related variables."

OnEventBlock
An event block is a programming structure that includes 0 to many event handlers, each of which contains the response for a particular event. An event handler begins with an onEvent header:
  onEvent(eventKind: eventQualifiers)
eventKind
One of several events. Valid values are described in Event types.
eventQualifier
Data that further defines the event. Such data might be the ConsoleField entered or the keystroke pressed.

The EGL statements that respond to a given event are between the onEvent header and the next onEvent header (if any), as shown in a later example. However, you cannot include a reference variable in the onEvent block unless that variable was declared as a program global.

The user continually interacts with the program, and the program runs an event handler when the event occurs that is associated with that event handler. If the purpose of the openUI statement is to display a prompt, however, the user-program interaction is less like a loop:
  1. An event handler (potentially one of several) traps a user keystroke and responds
  2. The openUI statement ends

No event block is available for a window.

Event types

ConsoleUI supports the following events for all modes:
BEFORE_OPENUI
The EGL runtime begins to run the openUI statement. This event is available for all ConsoleUI variables other than those based on Window.
AFTER_OPENUI
The EGL runtime is about to stop running the openUI statement. This event is available for all ConsoleUI variables other than those based on Window.
ON_KEY:(ListOfStrings)
The user has pressed a specific key, as indicated by a string such as "ESC", "F2", or "CONTROL_W". You can identify multiple keys by separating one string from the next, as in this example:
  ON_KEY:("a", "ESC") 

This event is available in an ArrayDictionary, a ConsoleField, a Menu, or a Prompt.

BEFORE_FIELD:(ListOfStrings)
The user has moved the cursor into the specified ConsoleField, as indicated by a string that matches the value of the ConsoleField name field. You can identify multiple consoleFields in the same consoleForm by separating one string from the next, as in this example:
  BEFORE_FIELD:("field01", "field02") 
AFTER_FIELD:(ListOfStrings)
The user has moved the cursor out of the specified ConsoleField, as indicated by a string that matches the value of the ConsoleField name field. You can identify multiple consoleFields in the same consoleForm by separating one string from the next, as in this example:
  AFTER_FIELD:("field01", "field02") 
BEFORE_DELETE
In relation to an on-screen arrayDictionary, the user has pressed the key specified in consoleLib.key_deleteLine, but the EGL runtime has not yet deleted the row. The program can invoke consoleLib.cancelDelete to avoid deleting the row.
BEFORE_INSERT
In relation to an on-screen arrayDictionary, the user has pressed the key specified in consoleLib.key_insertLine, but the EGL runtime has not yet inserted a row. The program can invoke consoleLib.cancelInsert to avoid inserting the row.
BEFORE_ROW
In relation to an on-screen arrayDictionary, the user has moved the cursor into a row.
AFTER_DELETE
In relation to an on-screen arrayDictionary, the user has pressed the key specified in consoleLib.key_deleteLine, and the EGL runtime has deleted a row.
AFTER_INSERT
In relation to an on-screen arrayDictionary, the user has pressed the key specified in consoleLib.key_insertLine; the EGL runtime has inserted a row; and the cursor leaves the row that was inserted.

The user can edit the row before committing changes to a database, as typically happens in the AFTER_INSERT handler.

AFTER_ROW
The user has moved the cursor from a row in an on-screen arrayDictionary.
MENU_ACTION:(ListOfStrings)
The user has selected a menuItem, as indicated by a string that matches the value of the menuItem name field. You can identify multiple menuItems by separating one string from the next, as in this example:
  MENU_ACTION:("item01", "item02") 
ConsoleUI supports the following events for RCP mode only. For more information, see Console UI widgets:
PUSHED: buttonName
The user clicked buttonName.
SELECTION_CHANGED: comboBoxName | radioGroupName
The user clicked comboBoxName or a member of radioGroupName.
STATE_CHANGED: checkBoxName
The user clicked checkBoxName.

isConstruct

When the isConstruct property is set to YES, you bind the entire openUI statement to a variable rather than binding individual fields to variables. EGL uses the string to which you bind the statement to hold the contents of an SQL WHERE clause, as shown in this example:
  1. An openUI statement acts on a ConsoleForm of three ConsoleFields (employee, age, and city), and each field is associated with an SQL table column of the same name.

    You associate a consoleField with an SQL table column by setting the SQLColumnName consoleField property; and you must set the dataType consoleField property, as noted in dataType.

  2. The user performs the following actions:
    • Leaves the employee field blank
    • Types this in the age field:
        > 25
    • Types this in the city field:
        = 'Sarasota'
  3. When the user leaves the on-screen variable on which the openUI statement acts, the bound variable receives the following content:
      AGE > 28 AND CITY = 'Sarasota'

As shown, EGL places the operator AND between each clause that the user provides.

The next table shows valid user input and the resulting clause. The phrase "simple SQL types" refers to SQL types that are neither structured nor LOB-like types.

Symbol Definition Supported data types Example Resulting clause (for a character column named C) Resulting clause (for a numeric column named C)
= Equal to Simple SQL Types =x, ==x C = 'x' C = x
> Greater than Simple SQL Types >x C > 'x' C > x
< Less than Simple SQL Types <x C < 'x' C < x
>= Not less than Simple SQL Types >=x C >= 'x' C >= x
<= Not greater than Simple SQL Types <=x C <= 'x' C <= x
<> or != Not equal to Simple SQL Types <>x or !=x C != 'x' C != x
.. Range Simple SQL Types x.y or x..y C BETWEEN 'x' AND 'y' C BETWEEN x AND y
* Wildcard for String (as described in next table) CHAR *x or x* or *x* C MATCHES '*x' not applicable
? Single character wildcard (as described in next table) CHAR ?x, x?, ?x?, x?? C MATCHES '?x' not applicable
| Logical Or Simple SQL Types x|y C IN ('x', 'y') C IN (x, y)

The equal sign (=) can mean "has a null value," and the not-equal sign (!= or <>) can mean "does not have a null value."

A MATCHES clause results from the user's specifying one of the wildcard characters described in the next table.

Symbol Effect
* Matches zero or more characters.
? Matches any single character.
[ ] Matches any enclosed character.
- (hyphen) When used between characters inside brackets, a hyphen matches any character in the range between and including the two characters. For example, [a-z] matches any lowercase letter or special character in the lower case range.
^ When used in brackets, an initial caret matches any character not included within the brackets. For example, [^abc] matches any character except a, b, or c.
\ Is the default escape character; the next character is a literal. Allows any of the wildcard characters to be included in the string without having the wildcard effect.
Any other character outside of brackets Must match exactly.

Example

Consider the following example for guiding the interaction between the user and a console form:
		openUI {bindingByName=yes}
			 activeForm
			 bind firstName, lastName, ID
			 OnEvent(AFTER_FIELD:"ID")
				  if (employeeID == 700)
        firstName = "Angela";
        lastName = "Smith";
				  end
  end
That code performs the following actions:
  • Opens the active ConsoleForm (which is the consoleForm that was most recently displayed in the active window);
  • Binds a set of primitive variables to each of the ConsoleFields; and
  • Specifies that after the user types a value in the employeeID field and moves to the next, EGL places strings in two other variables.
Consider the following details about the example:
  • The cursor starts in the first of the listed consoleFields; but should start in the ID field so that the user's input in the other fields is not wiped out by the event handler.
  • The event handler updates the variables that are bound to the firstName and lastName consoleFields but does not cause those values to be displayed until the cursor enters those fields. You might want to display the values earlier.

Feedback