Widget properties and functions

In many cases, the Rich UI widgets are EGL handler parts, stereotype RUIWidget. Exceptions include Tooltip, DataGridTooltip, and TreeTooltip, all of which are stereotype RUIHandler, and the Dojo widgets, each of which is based on an external type.

You can learn the properties and functions that are available for a widget type in any of the following ways:

Always use dot syntax to access a given function or property; for example, myWidget.myFunction() or myWidget.myProperty.

Properties available for most widgets

Most EGL properties are available only to EGL system code and are not available at run time. However, widget properties are fields; they are available to your code at run time.

Style-related properties such as class and style are available for all IBM-supplied widgets. For details on styles, see “Widget styles.”

The following properties are useful for developing business applications:
  • children provides access to an array of subordinate widgets, if any; for details, see a later section.
  • class identifies a cascading style sheet (CSS) class used when displaying the widget.
  • disabled takes a Boolean that indicates whether the widget is disabled. A disabled widget cannot respond to events and, on most browsers, its text appears in grey.
  • id takes a string used to assign or retrieve an ID for a specific widget. You can use the ID in a cascading style sheet (CSS) to identify the style characteristics of that widget. Also, if you are integrating EGL with JavaScript libraries, this property lets you assign an ID for use by the JavaScript logic.

    If the widget (for example, a box) corresponds to a DOM subtree rather than to a specific DOM element, the ID is for the topmost DOM element in the subtree. For an introduction to the DOM, see “Understanding how browsers handle a Rich UI application.”

  • position specifies the meaning of the widget's x and y coordinates and takes one of the following values:
    static
    The widget's x and y coordinates are ignored, as is the default behavior. The displayed position changes if you first set the x and y values when the position value is static and then change the position value.
    absolute
    The widget's x and y coordinates that you assign and that you get are different.
    • The value you assign should be relative to the top left origin of the closest non-static parent. Those coordinates are not affected by the alignment value.
    • The widget's x and y coordinate value you get from a widget are still relative to the browser including the height of the scroll bar.
    relative
    The widget's x and y coordinates are relative to the top left of the parent. If the widget's parent is the document element, the coordinates are relative to the top left of the viewable area of the browser.
  • tabIndex takes an integer that identifies the widget's placement in a tab order. For example, a widget assigned a tabIndex value of 2 receives focus after the user tabs away from a widget that has a tabIndex value of 1. You can use numbers such as 10 and 20 (rather than 1 and 2) to allow for the later addition of other widgets.

    The default tab order is browser specific.

  • x and y values are integers that refer to the x-y coordinate of the widget. The meaning of that coordinate varies in accordance with the value of the position property. As suggested in the description of the position property, the graphical origin is either the top left of the browser window or the top left of a parent widget. The following rules apply:
    • The x value is positive to the right of the origin, negative to the left
    • The y value is positive below the origin, negative above

    You can place a widget outside of its parent and even outside of the viewable area.

  • zIndex takes an integer that identifies the widget's position—its nearness to the front—in relation to other widgets at the same x and y location. A widget with a relatively large zIndex value (for example, 4) is closer to the front than a widget with a relatively small zIndex value (for example, 2). The zIndex value has no effect when the value of position is static.
The following properties are especially useful for developing new Widget types that are based on stereotype RUIWidget:
  • innerHTML is a string used to assign or retrieve the HTML within a container such as a div, floatLeft, or floatRight widget.
  • innerText is a string used to assign or retrieve text within a container. You can use innerText to provide a text property that is specific to the type.
  • logicalParent is used for developing Widget types that are containers. When writing the code that adds children to the container, you set the logicalParent property so that it refers to the appropriate parent DOM element. For an introduction to the DOM, see “Understanding how browsers handle a Rich UI application.”

    For example, in relation to the child of a box, the parent property refers, not the box, but to a DOM TD element within a DOM Table element. However, the logicalParent property refers to the DOM Div element that represents the box and is the parent of the DOM Table element.

    parent is for Widget-type development and provides access to a parent DOM element. For an introduction to the DOM, see “Understanding how browsers handle a Rich UI application.”
The following properties are for interacting with users who read Arabic or Hebrew:
  • numericSwap takes a string ("Yes" or "No") that lets you use Hindi numerals in Arabic. To use Hindi numerals, set numericSwap and reverseTextDirection to "Yes".
  • reverseTextDirection takes a string ("Yes" or "No") that indicates whether to reverse the text direction in the widget.
  • symmetricSwap takes a string ("Yes" or "No") that indicates whether to replace pairs of special characters to preserve the logical meaning of the presented text. If the value is "Yes", the effect is to replace paired characters such as <, >, [, and { with >, <, ], and }.
  • textLayout takes one of two strings: either "Visual" or "Logical":
    • If the setting is "Visual" and the user types "A" and then "B" (and if "A" and "B" are characters in a bidirectional language), the displayed characters are "AB". The order of display is the order of input, left to right, which is also the order in which the data is stored in local memory.
    • If the setting is "Logical", the displayed characters are "BA".

    In most cases, the setting "Visual" is appropriate for Arabic or Hebrew content derived from a machine that runs z/OS® or IBM® i.

  • widgetOrientation is for Arabic and Hebrew text. This property takes one of two strings: either "LTR" (left-to-right) or "RTL" (right to left). When you specify "LTR", the widgets acts as a standard non-bidirectional widget. When you specify RTL, the widgets are mirrored; that is, scroll bars for dropdown lists appear on the left, the text-typing orientation for input fields is right-to-left, and the text is right-aligned.
The following properties add accessibility:
  • ariaLive indicates the level of support provided for assistive technology; that is, for screen readers that are able to notify users of updates to screen regions. The specification for such technology is here:

    http://www.w3.org/TR/wai-aria

    The ariaLive value is a quoted string ("off", "polite". "assertive", or "rude"), each of which is described in the specification's section on property: live.

  • ariaRole indicates the role specified for the widget, as used for assistive technology. For details, see the specification mentioned earlier.

    The ariaRole value is a quoted string such as "button" or "listbox", each of which is described in the specification's section on Roles.

Functions available for most widgets

The following functions are available for all IBM-supplied widgets of type RUIWidget:
  • The function fadeIn causes the widget to fade in (to be presented slowly), and the function fadeOut causes the widget to fade out (to be slowly made invisible):
    fadeIn (duration int in, callback EffectCallback)
    fadeOut (duration int in, callback EffectCallback)
    Each function takes two parameters:
    duration
    Number of milliseconds between the start and end of the process, whether the widget is fading in or fading out
    callback
    A reference to a function that is invoked as soon as the widget fades in or out. That function takes no parameters and has no return value. If you do not wish to specify a function, set this argument to null.
    Here is an example:
    myButton.fadeOut(1000, null);
  • The function focus causes the widget to receive focus:
    focus()

    For example, a button in focus is highlighted, and the user's pressing the ENTER key is equivalent to the user's clicking the button. Similarly, a text field in focus (if not read only) includes a cursor so that the user enters data by typing a printable character without first tabbing to the field.

    The user can press TAB repeatedly to cycle through the available fields. With each keypress, the focus moves either to the next application field or to a field on the browser; for example, to the web address field.

    Here is an example invocation of focus:
    myButton.focus();
  • The function morph lets you change the display of a widget over time. The function repeatedly calls one of your functions; in this way, your code specifies the behavior caused by the runtime invocation:
    morph (duration int in, callback EffectCallback, morphFunction MorphFunction )
    The function takes three parameters:
    duration
    Number of milliseconds between the start and end of the process.
    callback
    A reference to a function that is invoked as soon as the process is complete. That function takes no parameters and has no return value. If you do not wish to specify a function, set this second argument to null.
    customMorphFunction
    A reference to a custom morph function, which is a function invoked repeatedly during the duration mentioned earlier. . The custom morph function takes two parameters: the widget being changed and a float assigned by the EGL runtime. The float is a fraction between 0 and 1 and reflects the progress made toward the end of the duration. (At each invocation of the custom morph function, the value of that float is larger.) That fraction is based on a calculation of how many times the custom morph function is invoked, given the duration available and the amount of time required to run the custom logic. The custom morph function has no return value.
    Here is an example:
    myButton.morph(1000, null, myCustomMorphFunction);
  • The function resize lets you change the size of a widget over time:
    resize (width int in, height int in,
           duration int, callback EffectCallback)
    The function takes four parameters:
    width
    The desired final width, in pixels.
    height
    The desired final height, in pixels.
    duration
    Number of milliseconds between the start and end of the process.
    callback
    A reference to a function that is invoked as soon as the process is complete. That function takes no parameters and has no return value. If you do not wish to specify a function, set this argument to null.
    Here is an example:
    myButton.resize(100, 100, 1000, myFunction);

Children property and related functions

In “Rich UI widgets,” a subset of widgets are categorized as “container widgets.” Those widgets include the children property, which specifies an array of subordinate widgets. Every element in the array refers to a named widget or to an anonymous one, as described here:
  • A named widget is declared outside the children array, as is the case for every widget in the following code:
    myInTextField TextField{};
    myButton Button{ text = "Input to Output", onClick ::= click };
    myOutTextField TextField{};
    
    myBox Box{ columns = 3, 
                 children = [ myInTextField,  myButton, myOutTextField ]};

    If the array references a named widget multiple times, only the last reference is used, and the other references are ignored.

  • An anonymous declaration starts with the keyword new, cannot be referenced in any of your code, and lets you create a widget at the moment you are thinking about the widget's placement:
    myInTextField TextField{};
    myTextOutField TextField{};
    
    myBox box{columns=3, 
              children=[myInTextField,
                        new Button{ text = "Input to Output", onClick ::= click},
                        myOutTextField]};
In many cases, a parent widget is of type Box or Div, and the placement of the children widgets is affected by the parent type:
  • A Box widget includes the columns property, and the value of that property specifies the default placement of each widget listed in the children array. For example, if columns=1, the widgets listed in the array are displayed in a single vertical column. Similarly, if columns=2, every second widget is displayed in the second column, and the subsequent widget (for example, the third in the array) is displayed in the first column of a new row.

    In general, if the value of columns is n, the widget at position n+1 of the array is displayed in the first column of a new row. If you do not specify a columns value, the children of the Box widget extend to the right.

  • The children of a Div widget extend to the right, with a horizontal scroll bar (if necessary) to provide access to widgets that extend to the right of the viewable area.

Div widgets that are children of another widget are displayed vertically, one underneath the previous.

You can reassign the value of children in any function and in this way change the web page. (Similarly, you can reassign the value of initialUI in the on-construction function.) For example, the following syntax is valid, assuming you have declared the widgets specified:
   myBox.children = [myInTextField, myButton02, myOutTextField];
Although you can reassign a children (or initialUI) array, do not make changes by using dynamic array functions such appendElement or the operator ::=. Instead, use the widget-specific functions appendChild, appendChildren, removeChild, and removeChildren. Here is an example, assuming you have declared the widgets specified:
Function myFirstFunction(){} 
   myBox.appendChild(myOtherButton);
   myBox.appendChildren([myOtherTextField, myOtherButton02]);
   myBox.removeChild(myOtherButton);
   myBox.removeChildren();
end
Similarly, you can add or remove children from the top DOM element, as shown here:
document.body.appendChild(myOtherButton);
document.body.appendChildren([myOtherTextField, myOtherButton02]);
document.body.removeChild(myOtherButton);
document.body.removeChildren(); 

The functions appendChild and removeChild each accepts a single widget; appendChildren accepts an array of widgets; and removeChildren takes no arguments. In the case of appendChild or appendChildren, the widget declarations can be anonymous or named. In the case of removeChild, the widget declarations must be named.

Note: The application's use of the removeChild or removeChildren function has no effect on memory allocation. For details on this potentially important issue, see “Rich UI memory management.”

The effect of assigning a widget to a different parent

A specific widget can be the child of only one other widget (or of the document body, as shown in a later example). If a widget has a parent, you can cause the widget to be the child of a different parent. We refer to the reassignment as re-parenting the child widget.

Consider the following declaration of myTopBox, which is the parent of two other boxes:
   myTopBox Box{padding = 8, columns = 1, backgroundColor = "Aqua",
      children =[myBox02, myBox03 ]};
Assume that the preceding declaration is in a Rich UI handler that makes myBox03 the only element in the initialUI array:
handler MyTest type RUIhandler{initialUI =[myBox03]}

At run time, the assignment to initialUI is handled after the declaration of myTopBox. The effect is that myBox03 is re-parented to the document body, leaving myTopBox with only one child, myBox02.

Your code might add myTopBox to the web page in response to a runtime event such as a user's button click. You can see the effect by running the following code and clicking the button:
import com.ibm.egl.rui.widgets.Box;
import com.ibm.egl.rui.widgets.Button;
import com.ibm.egl.rui.widgets.TextField;
import egl.ui.rui.Event;

handler MyTest type RUIhandler{initialUI =[myBox03]}
 
   myTopBox Box{padding = 8, columns = 1, backgroundColor = "Aqua", 
      children =[myBox02, myBox03 ]};
 
   myBox02 Box{padding = 8, columns = 2, backgroundColor = "DarkGray", 
      children =[myHelloField ]};
 
   myBox03 Box{padding = 8, columns = 3, backgroundColor = "CadetBlue", 
      children =[myInTextField, myButton, myOutTextField] };
 
   myHelloField TextField{readOnly = true, text = "Hello"};
   myInTextField TextField{};
   myButton Button{text = "Input to Output", onClick ::= click};
   myOutTextField TextField{};
 
   function click(e EVENT in)
      document.body.appendChildren([myTopBox]);		
   end
end

The effect of removing all children from the document body

Consider the following statement:
   document.body.removeChildren();
The effect is twofold:
  • Removes all children widgets from the web page.
  • Removes access to the external style sheet, if any. (Style sheets are explained in “Widget styles.”
If you wish to remove children from the document body without removing access to the external style sheet, remove specific children, as in the following statement:
   document.body.removeChild(myBox);