Use math functions in your custom print template to calculate totals, combine number field values, count rows, and apply formatting logic directly in the printed output.
|
Before you start
|
Basic math operators
You can perform calculations directly between two number field values using standard operators. Place the expression inside curly braces where you want the result to appear in your template.
| Operator | Syntax | Description |
|---|---|---|
| Add | {$id1 + $id2} | Sum of two number fields |
| Subtract | {$id1 - $id2} | Difference between two number fields |
| Multiply | {$id1 * $id2} | Product of two number fields |
| Divide | {$id1 / $id2} | First field divided by second |
| Round | {$id1|round:2} | Round to N decimal places |
| Ceil | {$id1|ceil} | Round up to nearest whole number |
| Floor | {$id1|floor} | Round down to nearest whole number |
| Abs | {$id1|abs} | Absolute value (remove negative sign) |
| Min | {$id1|min:$id2} | Return the smaller of two values |
| Max | {$id1|max:$id2} | Return the larger of two values |
| Sqrt | {$id1|sqrt} | Square root |
| Pow | {$id1|pow:2} | Raise to a power (e.g. squared) |
| Pi | {$smarty.const.M_PI} | Mathematical constant pi (3.14159...) |
|
Worked examples
|
How it works
Declare a variable before the table and set it to 0. Inside the tablerow loop, add each row's value to the variable. After the table, output the variable to display the total.
|
Step 1: Initialise the variable before your table {$value = 0}
$id4 = the group question, $_row.data.id3 = Number Value #3 inside the group {tablerow from=$id4 item=_row} {$_row.data.id1} | {$_row.data.id2} | {$value = $value + $_row.data.id3}{$_row.data.id3} {/tablerow}
Step 3: After the table, output the running total Total of all Number Value #3: {$value} |
|
How the code spans table cells in Word
|
Here is how each example looks as a Word table. The code is split across cells matching your column layout:
Running total template
{$value = 0} (place this above the table)
| Question Group, Multiple Response | ||
| Worker Name | Yes/No? | Number Value #3 |
|
{tablerow from=$id4 item=_row} {$_row.data.id1} |
{$_row.data.id2} |
{$value = $value + $_row.data.id3} {$_row.data.id3}{/tablerow} |
Total of all Number Value #3: {$value} (place this below the table)
Counter template
Counter Start = {counter start=0 skip=1 direction=up} (place this above the table)
| Question Group, Multiple Response | ||
| Count # | Yes/No? | Number Value #3 |
|
{tablerow from=$id4 item=_row} Counter = {counter} |
{$_row.data.id2} |
{$value = $value + $_row.data.id3} {$_row.data.id3}{/tablerow} |
Cycle template
| Question Group, Multiple Response | ||
| Cycle # | Yes/No? | Number Value #3 |
| {tablerow from=$id4 item=_row}Cycle = {cycle values="odd,even"} | {$_row.data.id2} |
{$value = $value + $_row.data.id3} {$_row.data.id3}{/tablerow} |
Example: summing hours across workers
The form used in this example has four questions:
- Q2: Number Value #1 ({$id2}) — a number field
- Q3: Number Value #2 ({$id3}) — a number field
- Q4: Question Group ({$id4}) — a group question with multiple answers enabled, containing:
- Q4.1: Worker Name ({$_row.data.id1}) — a text field
- Q4.2: Did you Train? ({$_row.data.id2}) — a multiple choice Yes/No field
- Q4.3: Number Value #3 ({$_row.data.id3}) — a number field
The form used in this example: Q2 and Q3 are standalone number fields. Q4 is a Question Group with multiple answers enabled, containing Worker Name, Did you Train?, and Number Value #3.
Using these values entered in the form:
- Number Value #1 (Q2): 10
- Number Value #2 (Q3): 15
- Group responses: Worker 1 / Yes / 8, Worker 2 / No / 10, Worker 3 / No / 12
The template code produces:
| Worker Name | Yes/No? | Number Value #3 |
|---|---|---|
| Worker 1 | Yes | 8 |
| Worker 2 | No | 10 |
| Worker 3 | No | 12 |
The group question table with each worker's response. Number Value #3 is accumulated into {$value} on each row.
After the table: Total of all Number Value #3 responses: 30
Counter
Counter automatically increments or decrements a number on each iteration of a tablerow loop. Use it to add a row number or sequence number to each row in a repeating group question.
|
When to use Counter
|
Syntax
|
Initialise before the table: Counter Start = {counter start=0 skip=1 direction=up}
Inside the tablerow, call {counter} on each row: {tablerow from=$id4 item=_row} Counter = {counter} | {$_row.data.id2} | {$value = $value + $_row.data.id3}{$_row.data.id3} {/tablerow} |
- start: the starting value of the counter (e.g. 0 starts from 0, outputs 1 on first row)
- skip: how much to increment on each row (e.g. skip=1 counts 1, 2, 3; skip=2 counts 2, 4, 6)
- direction: up increments, down decrements
Example output
| Count # | Yes/No? | Number Value #3 |
|---|---|---|
| Counter = 1 | Yes | 8 |
| Counter = 2 | No | 10 |
| Counter = 3 | No | 12 |
Counter automatically numbers each row as the tablerow loop iterates.
Cycle
Cycle alternates between a set of values on each row of a tablerow loop. Use it to apply alternating labels, colours, or categories to rows, for example alternating odd and even row labels for visual distinction.
|
When to use Cycle
|
Syntax
|
Inside a tablerow, define the values to cycle through: $id4 = the group question {tablerow from=$id4 item=_row} Cycle = {cycle values="odd,even"} | {$_row.data.id2} | {$_row.data.id3} {/tablerow} |
- values: a comma-separated list of values to cycle through on each row
- advance: set to y (default) to move to the next value on each iteration, or n to stay on the same value
- delimiter: the character separating values (default is comma)
Example output
| Cycle # | Yes/No? | Number Value #3 |
|---|---|---|
| Cycle = odd | Yes | 8 |
| Cycle = even | No | 10 |
| Cycle = odd | No | 12 |
Cycle alternates between odd and even on each row of the group question.
Things to know
- Math expressions work on Number Field question types. Text fields and other question types will not produce numeric output.
- Running total variables ({$value = 0} pattern) must be declared before the tablerow block, not inside it.
- The variable name ($value in the examples) can be anything you choose as long as it is consistent throughout the template.
- Counter and Cycle are template-side functions only. They do not read from form data.
- Dividing by zero will produce an error in the output. Add conditional logic if a divisor field might be empty.