Rich UI Grid and GridTooltip

A Rich UI grid widget defines an array of values in a table format. For new development, use the Rich UI dataGrid widget; it is superior in performance and capabilities and is described in “Rich UI DataGrid and DataGridTooltip.”

The grid widget allows you to set the following details:
Rich UI provides a number of functions that you can reference in the behavior fields: For details, see the following files in the com.ibm.egl.rui project, EGLSource folder, com.ibm.egl.rui.widgets package:

Be aware of the issue described in “Rich UI memory management.”

Supported properties and functions

The following properties are supported in the Grid widget:
  • data, which is of type ANY and holds an array of records defined by the developer. The data in a given record field is presented in the grid only if the name of the field is matched by the name of a grid column, as specified in the columns property. In the grid declaration, list the data property after the other properties.
    Here is an example:
    stocks Stock[] = [
    		 new Stock{Symbol = "Company1", Quote = 100, NumShares = 40, SelectQuote = false}, 
    		 new Stock{Symbol = "Company2", Quote = 200, NumShares = 10, SelectQuote = false}, 
    	]; 
    
    Grid myGrid {..., data = stocks as any[]};
  • columns, which holds an array of records of the following type:
    Record GridColumn
       displayName String;
       name String;
       width int;
    end
    displayName
    The column title. If this field is not specified, the column title is the value of the name field.
    name
    The default column title, as well the name of the data record field that provides the value for the column.
    width
    Number of pixels in the column.
  • totalRows is a read-only property that contains the number of rows in the grid.
  • behaviors is an array of delegates of type CellBehavior. You specify an array of functions that are invoked every time the user clicks any row other than the header row. The functions are invoked in the order specified in the array.
  • headerBehaviors is an array of delegates of type CellBehavior. You specify an array of functions that are invoked every time the user clicks a header row. The functions are invoked in the order specified in the array.
The following rules are in effect:
  • Except in the case of the referenced widgets in children or initialUI properties, Rich UI requires that you declare a value before you reference it. If a grid property refers to an array that is outside the grid declaration (as in our previous example of the data property), the array must be specified before the grid declaration.
  • When declaring a grid, ensure that you list the behaviors, headerBehaviors, and column properties before the data property.
  • If, when writing statements in functions, you change the value of the behaviors or headerBehaviors property, invoke the grid-specific function layouts() to reset the widget.

In relation to Grid (but not GridTooltip), other supported properties and functions are described in “Widget properties and functions.”

Use of this widget requires some or all of the following statements:
import com.ibm.egl.rui.widgets.Grid;
import com.ibm.egl.rui.widgets.GridBehaviors;
import com.ibm.egl.rui.widgets.GridSelector;
import com.ibm.egl.rui.widgets.GridSorter;
import com.ibm.egl.rui.widgets.GridToolTip;

Grid Tooltips

If you wish to include a tooltip for a grid, you have two main alternatives:
  • If you wish the tooltip to be displayed whenever the cursor hovers over the grid and not to vary according to the cell, row, or column, assign the grid as a whole to a tooltip. For details, see Rich UI Tooltip. You might declare a tooltip as a global widget and enable it (making it active) in some function; for example, in the on-construction function or in a function identified in the behaviors or headerBehaviors property.
  • If you wish the tooltip to specify different tooltip information for a given cell, row, or column outside of the header, you can specify a grid tooltip, which is similar to a tooltip but always requires that you specify a grid-tooltip provider function. That function returns a box that provides the content to display to the user.

    You can specify only one grid tooltip per grid.

Here is the process for creating a grid tooltip:
  • Declare a grid-tooltip handler globally, as in the following example, which references a grid-tooltip provider (the function to invoke) and a delay (the number of milliseconds between the start of the hover and the invocation of the provider):
    gridTooltip GridTooltip { provider = tooltipText, tooltip.delay = 1000 };
    That declaration requires that you include the following import statement:
    import egl.rui.widgets.GridToolTip;
  • Reference a function in the grid-tooltip handler when you assign an array for the behaviors property. In this example, the function is gridToolTip.setToolTips.
  • Create a grid-tooltip provider function with the name specified in the GridToolTip provider property (in this example, the function is tooltipText). The grid-tooltip provider function has the parameter and return-value characteristics outlined in the following Delegate part:
    Delegate GridTooltipTextProvider(row any in, fieldName String in, td TD in) returns(Box) 
    end
    row
    The row provided to the function. You can use the input argument to access a specific value. For example, consider the case in which the data is as follows:
    stocks Stock[] = [
    		 new Stock{Symbol = "Company1", Quote = 100, NumShares = 40, SelectQuote = false}, 
    		 new Stock{Symbol = "Company2", Quote = 200, NumShares = 10, SelectQuote = false}
    	]; 
    Inside the provider function, you can determine which row is being hovered over by writing code such as this:
    if (row.Quote as int == 200)
       // place content in a tooltip and return the tooltip
    end
    fieldName
    Name of the column provided to the function.
    td
    An internal widget that represents the grid cell. That widget is based on the HTML TD (table data) tag.
  • You do not enable the grid tooltip; it is enabled as soon as you declare it.

Example

Here is an example that you can try in your workspace and that includes a tooltip for the header row and a grid tooltip elsewhere:

import com.ibm.egl.rui.widgets.Box;
import com.ibm.egl.rui.widgets.Grid;
import com.ibm.egl.rui.widgets.GridBehaviors;
import com.ibm.egl.rui.widgets.GridColumn;
import com.ibm.egl.rui.widgets.GridSelector;
import com.ibm.egl.rui.widgets.GridTooltip;
import com.ibm.egl.rui.widgets.TextArea;
import com.ibm.egl.rui.widgets.Tooltip;
import egl.ui.rui.Widget;


Record Filler
	 F1 String;
	 F2 String;
	 F3 String;
end

handler myGrid1 type RUIhandler {initialUI = [ myBox ]}
	
	 gridSelector GridSelector { color = "lightgreen" };		
	 filler Filler[] = [
	    new Filler{F1 = "R3, C1", F2 = "R3, C2", F3 = "R3C3"}, 
		  new Filler{F1 = "R4, C1", F2 = "R4, C2", F3 = "R4C3"} 
	 ];
	
	 myFirstGrid Grid{
      behaviors 		= [
 			   GridBehaviors.whiteCells,
 			   GridBehaviors.alternatingColor,
 			   GridBehaviors.tightCells,
 			   gridSelector.enableSelection,
			   gridTooltip.setTooltips
      ],
      headerBehaviors = [
         GridBehaviors.grayCells,
         headerTooltips
      ],
		  columns = [
			   new GridColumn{name = "F1", displayName = "Column 1 Header", width=120},
         new GridColumn{name = "F2", displayName = "Column 2 Header", width=120},
			   new GridColumn{name = "F3", width=50}
		  ],
		  data = [
			   new Dictionary { F1 = "Row 1, Column 1", F2 = "Row 1, Column 2", F3 ="me"},
			   new Dictionary { F1 = "Row 2, Column 1", F2 = "Row 2, Column 2", F3 = "you"},
			   filler[1], filler[2]
		  ]
		
   };
	
   myBox Box{ backgroundcolor = "peachpuff", padding=8, 
              children=[myFirstGrid], marginbottom=15};
	
   HtooltipText String = "This is a Header tooltip";	
	 headerTooltip Tooltip { text = HtooltipText, delay=1000 };
	
   function headerTooltips(grid Grid in, td Widget in, row any in, 
                           ignoreRowNumber int in, column GridColumn in) 
      headerTooltip.enable(td);
   end
	
   gridTooltip GridTooltip { provider = tooltipText, tooltip.delay = 1000 };
   tooltipArea TextArea { width=450, height=100, paddingLeft=7, marginLeft=7 };

   function tooltipText(row any in, fieldName String in, td Widget in) returns(Box)
	    tooltipArea.text = 
          "In function tooltipText (a tooltip provider):" + 
          " \n   fieldName is the column name ('"+fieldName+"')." +
          "\nYou can access cell content:" +
          "\n   td.innerText is '"+td.innerText+"'. \nThanks to EGL dynamic access" +
	        "\n   row[fieldName] is also '"+row[fieldName] + "'."; 
          return (tooltipBox);
   end
	
   tooltipBox Box {columns=1, width=475, children = [ tooltipArea ]};
end