Looping Data Arrays
It is a very common requirement to build table rows or subforms that repeat for each item in an array (a one-to-many relationship in your data collection). Examples are for instance a table with line items in an invoice or a price quotation, or a list of covers in an insurance policy.
Inserting a Loop
Inserting a loop is a three step process.
Select the Element to Repeat
First, select the element in the canvas that you wish to repeat. Typically, this is a table row or a subform.
In many cases the row to be repeated is the second row of a table, while the first row is used as a header row.
Bind The Element to a Field
Locate the Data Bind property in the Properties panel to the right of the editing canvas and click the three dots to bring up the field selection dialog. Select a repeating element in the data collection.
Mark as Repeating
Tick the box that says Repeat element for each entry. Most probably iText DITO will already tick this box for you.
Note that the resulting bind expression looks like this: items[*]. You can manually insert this expression in the Data Bind parameter as well.
Binding Data within a Loop
Once the loop is in place, you can start inserting fields in it. For line items in an invoice for instance, you could be required to bind an item description, a quantity, a unit price and a line item total for instance.
In the above scenario, insert rich text elements in the cells of the repeating row and start adding simple data bindings to those rich text elements. The same process applies if you insert other bound elements, like images for instance.
Instead of selecting fields via the wizard, you can also type the names of fields into the Data Bind property of the rich text element. Note that data binds which you insert inside a loop are relative to the root of the loop, not to the root of the data collection. You can use $ or $parent in the path if you have to bind a field relative to the root or to a parent item of the loop's root.
Loop Properties
Filtering
You can create tables with repeating rows for any subset of a data array. Imagine that you have a list of line items in an invoice data set, and in the envisioned PDF document you want to build different tables, for instance to distinguish between line items of different types.
Use the filter property on your loop to set the filter. To set the filter condition, you can use the same wizard as for conditional insertion of content.
Note that you can also set the filter through syntax. The syntax to define the filtered loop looks like this:
iteratingElement[[conditionExpression]]
in which iteratingElement is the root element of the array and conditionExpression defines the filter.
To set the filter, you can use the operators in the table below. String values can be contained within single or double quotes.
Operator Name | Type | Syntax | Expression Example |
---|---|---|---|
Is equal to | Text/Number | == | {{fieldname}}=="fieldvalue" |
Is not equal to | Text/Number | != | {{fieldname}}!="fieldvalue" |
Is empty (string length is zero) | Text | isEmpty() | isEmpty({{fieldname}}) |
Is blank (no characters or only blank characters) | Text | isBlank() | isBlank({{fieldname}}) |
Is not empty | Text | !isEmpty() | !isEmpty({{fieldname}}) |
Is not blank | Text | !isBlank() | !isBlank({{fieldname}}) |
Contains | Text | contains() | contains({{fieldname}}, "fieldvalue") |
Does not contain | Text | !contains() | !contains({{fieldname}}, "fieldvalue") |
Is greater than | Number | > | {{fieldname}}>fieldvalue |
Is greater than or equal to | Number | >= | {{fieldname}}>=fieldvalue |
Is less than | Number | < | {{fieldname}<fieldvalue |
Is less than or equal to | Number | <= | {{fieldname}<=fieldvalue |
And | Logical | && | contains({{fieldname}}, "fieldvalue1")&&!contains({{fieldname}},"fieldvalue2") |
Or | Logical | || | {{fieldname}}=="fieldvalue1"||{{fieldname}}=="fieldvalue2" |
The operators in the table can be combined with the calculation functions that iText DITO supports, such as sum(), product(), concat() and size(). In our example, the expression size({{items[[{{producttype}} == 'wind mill']]}}) would return the number of items in that subarray.
Limiting
You can also set a minimum or maximum number of repetitions for the loop.
Example
Imagine you have created a loop on table row, bound to an array with 6 iterations:
- if you set the minimum number of repetitions to 10, a table with 10 rows will be generated. The first 6 rows will be bound to data iterations. 4 empty rows will be added to the end.
- if you set the maximum number of repetitions to 5, a table with 5 rows will be generated. The first 5 iterations will be bound to the table, the sixth iteration will not be added to the table.