Using scripts in Dynamic Tables

If the contents or style of cells or rows in a Dynamic Table need to be personalized based on the value of a data field, you will need a script.

Do you want to style or change the output of an expression, based on the value of a data field? Then a custom Helper can come in handy. A Helper is a function that can be used in an expression. How to create a custom Helper is described in the topic: Creating custom Helpers. After creating a Helper you can type that Helper's name in any expression.

In all other cases you will need a Standard Script.

This topic gives some information that will help you to write a script for (an element in) a Dynamic Table.
It is assumed that you are familiar with the scripting basics; see Writing your own scripts.

Writing scripts for a Dynamic Table

If you're going to create your own scripts for Dynamic Tables, there are a few things you need to know.

Selectors

Scripts that target (an element in) a Dynamic Table can use the same types of selectors as other scripts. In the output, Dynamic Table rows are repeated including any classes that are set on the row and on its contents.

In addition, Dynamic Tables and their rows and cells have some special data- attributes that can be used as selector. See: A Dynamic Table's data- attributes.
Note however, that the data-repeat attribute cannot be used as a selector for Standard scripts, since it gets removed when the table is expanded, which happens before Standard scripts run.
The data-script attribute is used if you let the Designer create a script for you (see Quick-start a script with the Create script button).

How the scope of a script can simplify code

It is recommended to set the scope of a script that targets (an element in) dynamically added rows to Each matched element.

The selector of a script that targets (something in) a row that is linked to a detail table will probably match multiple elements.
By setting the scope of a script you can determine whether you want to run the script once, or once for each element that matches the selector. (See Setting the scope of a script.)

If a script runs once, accessing the detail data and dynamically added rows tends to be a bit complicated, especially when they are nested, since it involves looping over the results and record objects (see results and record).

If a script targets (something in) a row that is bound to a detail table, and runs once for each matched element, the current element is accessible via the this object (see this) and the current detail record is accessible via this.record.

The advantage of the latter approach is demonstrated in an example below.

Quick-start a script with the Create script button

This quick-start procedure only works for elements (a cell or span) that have a direct link with a data field.

To find out whether a cell or span has a direct link to a data field, select it (see Selecting an element) and:

  • Take a look on the Attributes pane. If under Other, the Field drop-down or Sum field point to a data field in the detail table, the element has a direct link to a data field.

  • Switch to the Source view. Elements with a direct link to a data field have a data-field or data-sum attribute.

By default, cells that are filled with a placeholder have a direct link with a data field. Cells that are filled with an expression don't. To create a direct link with a data field, select the cell and choose the data field from the Field drop-down on the Attributes pane.

The easiest way to add a script that targets a specific element (a cell or span) that has a direct link with a data field is this.

  1. In Design mode, select the element.

  2. Click the Create Script button next to the Field drop-down on the Attributes pane.

  3. Click Yes to confirm that the direct link with the data field will be broken.

As a result:

  • The element will now have a data-script attribute.

  • The data-field or data-format attribute is removed.

  • A new script will be created and opened in the Script Editor.

The selector of the new script is the data-script attribute with the name of the data field that the element was linked to as its value. For example: table [data-script='ID'].

The code of the script replaces the contents of the element with the current value of the data field:

Copy
var field = this.record.fields['ID'];
if (field) {
this.text(formatter.upperCase(field));
}

Under Options, the scope of the script is set to Each matched element (see Setting the scope of a script). This means that in the code, this refers to the element that matches the selector, and this.record refers to the current (nested) detail record (see this).

Tip: To get access to the row in which the cell is located, you can use this.parent().

Note: If you bind the element to a data field again by selecting it and then selecting a field from the Field drop-down on the Attributes pane, the data-script attribute will be removed.

Example: Styling a row based on a value in a detail table

Here are two scripts that have the same effect: if in a row, the value of the field Shipped is 1, it colors the text of that row green.

The first script targets a cell in a Dynamic Table row that has a [data-script='Shipped'] attribute. The script has its scope set to "Each matched element", so it can use this (see this) to access the selected cell and this.record to access the current detail record, without performing any loops.

Selector: table [data-script='Shipped'].
Scope: Each matched element

Copy
var field = this.record.fields['Shipped'];
if (field == 1)  
    this.parent().css('color', 'green');

The following script targets the table, and has its scope set to "Result set". This script loops over the detail table in the record, evaluating the field Shipped. If the value of that field is 1, it looks up the corresponding row in the results (the selected Dynamic Table).

Selector: #table_1 tbody
Scope: Result set

Copy
for(var i = 0; i < record.tables.detail.length; i++){
    if(record.tables.detail[i].fields['Shipped'] == 1)
    query("tr:nth-child(" + (i+1) + ")", results).css('color','green');
}