Table views and columns

Views

A table view specifies the columns that a table should have.

Views are created using the View (library.table.ViewType) node type. Views are used in conjunction with one or a list of nodes to build tables, each node, termed a row node, contributing to one row.

The view allows a list of columns to be specified. Each column can be:

  • A member type.
  • A node containing a member type list. This has the same effect as adding each member type in the member type list to the column list.
  • A column script.

The name of the column will be taken from the member type, unless an alternative column name is given. A column name of ${hidden} is used to indicate a column that should not be shown.

Thew view contains a number of optional fields, which are used by various table-building processes.

  • Apply To (library.table.ApplyViewTo) lists tags which identify nodes that may use this view. This is used by flexi tables.
  • Table Options (library.table.TableOptions) provides an options block to be added to the generated tables. Use this to set standard options defined in Table structure and additional Table display options.
  • Recalculation Frequency specifies how often the table should be recalculated. It can be set to one of three values:
    • Only recalculate when data changes - calculate when the node is derived and store the results. This is the default.
    • Always recalculate - calculate the table every time it is accessed.
    • Recalculate on first access after data change - calculate when the node is first retrieved after recalculation, but then store the results so that it is not recalculated until after the next derivation.

Column scripts

As well as listing member types, views can include column scripts. A column script is a script that creates one or more columns on a table.

Column Scripts are created using the Column Script (library.table.ColumnScriptType) type. As well as entering the script and bindings, this automatically sets a column script tag and provides a Columns list for the column script to declare the data columns it requires. These columns are added to the column list of the view if they are not already present, but with the ${hidden} name.

When the column script is called, it must pass an object to the register() method of the object passed in attribute "caller". This object must have three methods: init(), getColumns() and getRow().

  • init() performs initialisations.
  • getColumns() should return one or more column objects in an array.
  • getRow(rowNumber) should return a row object that relates to the column or columns.

When these methods are called, 'this' is populated, and has the following members:

  • this.column – a reference to the script node itself
  • this.resultSet – a Script Result Set object containing all the data for the table
  • this.columnNumber – the position of this column within the result set
  • this.name – a name to use for the column
  • this.getNode() – a method that, when passed a node version identifier or node reference, will return the node. This caches the returned node to prevent a database lookup if the same node is retrieved by a different column script. 

The column script is invoked using application.call().

The init() method is always called once. The getRow() method is likely to be called many times, and all one-off processing should take place in the init() method.

Column scripts can access other data in the result set by column number. This can be found by calling the getColumnNumber() of the resultSet object within the init() call, as in the example below. To make sure these columns are returned in the result set, they should be listed in the Columns section of the column script.

The example below returns the name of the row in upper case.  For this to work, the name member type should be bound to the reference mtNodeName, and should also be listed in the column script's Columns member type.

/**
 * Return the name of the node in upper case
 */

var mtNodeName = application.getBinding('mtNodeName');
var cnNodeName; application.get('caller').register({ init: function() {
cnNodeName = this.resultSet.getColumnNumber(mtNodeName); }, getColumns: function() { return [ { name: this.name , reference: this.column.getNodeReference() } ]; }, getRow: function(rowNumber) { var nameMember = this.resultSet.getMember(rowNumber,cnNodeName); if ( nameMember != null && nameMember.getValue() != null ) { var row = {}; row[this.column.getNodeReference()] = nameMember.getValue().toUpperCase(); return row; } } });

The column script can not access global variables set in the caller or other column scripts.  However, it can set and use its own global variables, even though the methods are called from another script. (There is effectively a closure around the whole column script.)

Each of the three methods has a default:

  • The default init() does nothing.
  • The default getColumns() produces a single column using the object from the method getColumn(), which itself returns a text column using the name and reference of the column script.
  • The default getRow() builds a row containing a single text field using the column script's node reference and the value returned from getField(rowNumber), which itself defaults to returning undefined, which means not to produce a field.

This means that:

  • init() is optional.
  • If the column script only returns a single column, use getColumn() and getField().
  • If the column script only returns a single column of type text, you only need to use getField().

These defaults mean that column scripts can be very small.  For example, the following column script is equivalent to the one above (it uses getNodeName() instead of reading the system.NODE_NAME member).

application.get('caller').register({
  getField: function(rowNumber) {
    return this.resultSet.getRow(rowNumber).getNodeName().toUpperCase();
  }
});

Advanced

getColumns(), getColumn(), getRow() and getField() are all passed an additional parameter which represents the columns or row that has already been written.  This can be used access column definitions or fields that have already been produced. This creates a dependency between the columns, and should be used with caution.

Select column

An additional column can be added to a table for a select check box. This is done by setting the table option select to true before the table is built using the Table.build() or Table.buildAll() methods. If you do not use these methods, you must call table.addSelectColumn() after the table is built, passing it a function that indicates how to build the check box.

The following options can be set to control how the select is created:

selectPosition

Position for the select column. One of:

  • first - the first column.
  • last - the last column.
  • auto - automatically position, which is last for table format, first for list and none format. This is the default.
  • a number - 0-based index where column should be. Other columns are shifted to the right.
selectReference

Reference to use for the select column. Defaults to 'select'.

selectName

Name for the select column. Defaults to 'Select'.

selectCSSClass

Class for the select column and each field (i.e. the column cssClass and fieldCSSClass). Defaults to 'select'.

selectPrefix

Prefix to be used for generated field names. Defaults to 'Select'. Assuming default is used, checkbox names will be of format Select[n]/nodeVersionReference, where n is their row number. Where Table.build() or Table.buildAll() have been used, the value of the checkbox will be the node version reference.

selectSuffix

Suffix to be used for generated field names. Defaults to 'nodeVersionReference'.