Logic & Dynamic Binding
Master reference for dynamic variables, formatting, aggregations, dynamic component attributes, conditional rendering, and dynamic collections.
The editor provides a powerful expression and binding engine that lets you connect canvas elements directly to dynamic dataset fields, apply conditional display rules, transform text and numbers, and loop over collections.
1. Working with Variables
Variables insert dynamic text or numerical values into your document output at render time.
Inserting Variables
You can insert variables into your canvas through two methods:
- Drag-and-Drop: Drag a Variable (
{}) block directly from the Block Manager onto the canvas. - Slash Command (
/): Type/inside any active text block to open the cascading path selector dropdown and choose a payload field.
Editing Variables
To configure an existing variable, click the Edit Logic button in the Style Manager or click the Data icon (๐๏ธ) on the floating component toolbar. This opens the Edit Variable modal where you can configure:
- Variable Path: Select or edit the JSON key path mapping to your payload data.
- Default Value: Define fallback text to display if the resolved variable path is
null,undefined, or empty (e.g.,Guest). - Segment Selection Index (
atIndex): Specify an index number to extract a single item from an array path.
2. Formatting & Aggregation Reference
Depending on the variable type and path, you can apply custom data formatting options and mathematical aggregations directly inside the variable settings modal.
Aggregation Configuration (AggregationConfig)
When binding a variable to an array or list of values, you can aggregate the data using the following calculation methods:
| Aggregation Method | Description | Configuration Parameters |
|---|---|---|
join | Combines array elements into a single string. | joinSeparator, joinFinalSeparator |
sum | Computes the numerical sum of the array. | field |
mean | Calculates the average value of the array. | field |
min | Extracts the lowest numerical value. | field |
max | Extracts the highest numerical value. | field |
count | Returns the total item count of the array. | N/A |
first | Returns the first item in the array. | field |
last | Returns the last item in the array. | field |
at | Returns the item at a specific array index. | atIndex |
Formatting Options (FormatOptions)
Apply display transformations for numbers, currency, dates, strings, and charts:
Number & Currency Formatting
- Decimals (
decimals): Controls the number of decimal places to display. - Separators: Customize
thousandsSeparator(e.g.,,) anddecimalSeparator(e.g.,.). - Number Abbreviation (
abbreviate): Compacts large numbers using custom suffix labels (abbreviationThousands,abbreviationMillions,abbreviationBillions,abbreviationTrillions). - Currency Symbol: Define
currencySymbol(e.g.,$,โฌ) and setcurrencyPositionto"before"or"after". - Percentage (
percentage): Formats numbers as percentages (e.g.,0.15renders as15%).
Date & Duration Formatting
- Date Formats: Select standard presets via
dateFormator specify custom syntax usingcustomDateFormat(e.g.,YYYY-MM-DD). - Durations: Convert numerical values into time durations using
durationUnit(seconds,minutes,hours,days) anddurationFormat(shortvs.long).
Text Transformations
- Transform: Modify text case using
uppercase,lowercase,capitalize,truncate, or render inlinemarkdown. - Truncate Length (
truncateLength): Specifies character limits whentransformis set totruncate. - Encoding (
encode): Enables URL or string encoding.
3. Dynamic Component Attributes & Images
Component settings inside the Right Inspector Panel featuring a Data icon (๐๏ธ) can be bound dynamically to payload data paths instead of static values.
Setting Up Dynamic Images
To render dynamic images (such as user avatars, generated charts, or dynamic product photos):
- Select an Image component on the canvas.
- Locate the src field in the Right Inspector Panel.
- Click the Data icon (
๐๏ธ) next to thesrcinput field. - Select the variable path containing your hosted image URL string (e.g.,
{{user.avatar_url}}ordata:image/svg+xml;...).
4. Conditional Logic
Conditional components allow you to show or hide document sections dynamically based on logical rules.
Adding Conditions
- Context Menu Wrapping: Click the More Options (
...) menu on any supported canvas element and choose Wrap in Condition. This wraps the selected block in a conditional statement and keeps theFalse / Elsebranch hidden by default. - Direct Block Insertion: Drag a Condition block directly from the Block Manager. Direct insertion keeps both the
TrueandFalse / Elsecontent blocks visible on the canvas by default.
Editing Conditions
Click the Edit Logic button or Data icon (๐๏ธ) on a condition block to open the Edit Condition modal:
- Logical Operators: Toggle between
AND,OR, andXORlogic for combining multiple rules. - Adding Rules (
+ Rule): Define single comparisons (e.g.,name->startsWith->B). - Adding Groups (
+ Group): Create nested sub-conditions for complex multi-level logic operations.
5. Dynamic Collections & Tables
Collection blocks allow you to repeat visual layouts, list items, or table rows across dynamic data arrays.
Configuring Collections
Click the Edit Logic button or Data icon (๐๏ธ) on a collection container or table block to configure iteration parameters:
- Variable Path: Select the array payload path to iterate over (e.g.,
itemsorinvoice.line_items). - Sorting (
+ Sorting): Add sort criteria to arrange items by specific fields in ascending or descending order. - Filters (
Filter): Build item filter rules using the integrated condition builder (AND/OR/XORrules and groups) to suppress specific array items from rendering.
Grouping Data
Grouping allows you to categorize dynamic collection items by a specific fieldโsuch as region, category, or statusโand render them into distinct sections or sub-tables.
1. Enable Grouping on a Collection
To group your data source:
- Open the Edit Collection modal for your target component.
- In the Group By field, select or search for the property you want to group by (e.g.,
region). - Click Confirm.
2. Understanding the Grouped Data Structure
When grouping is applied, the Collection changes how it iterates over your dataset. Instead of iterating directly through individual records, the Collection now iterates through Group Objects.
Each group context exposes the following variables:
| Variable | Type | Description |
|---|---|---|
groupField | string | The name of the property being grouped (e.g., "region"). |
groupKey | string | The value of the group for the current block (e.g., "North America"). |
items | 1:N Array | The nested array of individual data records that belong to this group. |
index | number | The zero-based index of the current group. |
3. Binding Grouped Data in the Canvas
Once grouping is enabled, you can build grouped layouts by combining group headers with nested elements or tables.
-
Add Group Headers: Insert a text element at the top of your collection row and bind it to
groupFieldandgroupKey.Example text binding:
{groupField}: {groupKey}$\rightarrow$ renders as region: North America -
Render Grouped Items: Insert a Table or nested Collection inside the outer item block and set its data source path to
items(Items (region)). -
Bind Item Columns: Map table cells or child elements to the fields within
items(e.g.,sku,price,category).
Example Output
Given a dataset containing items across multiple regions, applying a group by region will automatically separate your records into categorized sub-tables:
Dynamic Tables
Applying a collection to a Table component automatically creates dynamic repeating rows that expand based on the length of the bound dataset.
6. Data Filters (data-filter)
A Data Filter is closely related to a dynamic collection, sharing the exact same sorting, filtering, and grouping engine. However, while a standard Collection loops over and repeats a visual DOM structure for every item in the dataset, a Data Filter processes an array and allows you to:
- Assign the Result to a Variable: Store the filtered, sorted, or grouped array directly into the runtime context (e.g.,
root.myFilteredList) for use by other components, formulas, tables, or charts. - Display the Result: Output the resulting dataset directly into the document.
How It Compares to Collections
| Capability | Collection (data-collection) | Data Filter (data-filter) |
|---|---|---|
| Primary Purpose | Visual repeater loop (repeats cards, rows, grids) | Data processing, variable assignment, or raw dataset display |
| Output Behavior | Renders template child elements once per record | Assigns array to a variable and/or renders formatted output |
| Variable Assignment | Creates local loop item context | Assigns globally to root.<variableName> |
| Ideal For | Invoice line items, product catalogs, tables | Feeding Charts, calculating subset aggregations, pre-filtering data |
Configuring a Data Filter
To create and configure a Data Filter:
- Insert a Filter component from the Blocks Manager onto the canvas or into your text flow.
- Click the Edit Logic button or Data icon (
๐๏ธ) on the filter component to open the configuration modal:- Variable Path: Select the source array path to process (e.g.,
root.transactionsororder.items). - Sorting (
+ Sorting): Add sort rules to arrange records by specific fields in ascending or descending order. - Filters (
Filter): Build condition rules (AND/OR/XOR) to isolate specific subsets of data (e.g.,status == "completed"andamount > 500). - Grouping (
Group By): Group the filtered items by categorical keys. - Assign Result To Variable: Enter a target variable name (e.g.,
highValueTransactions). The filtered output will be assigned toroot.<variableName>.
- Variable Path: Select the source array path to process (e.g.,
- Click Confirm.
Downstream Usage
Once a Data Filter assigns its result to a variable, you can reference the filtered dataset anywhere downstream in your document:
- Charts: Feed the filtered array directly into chart datasets without needing backend data reshaping.
- Formulas: Pass the filtered variable to calculation formulas (e.g.,
SUM(root.highValueTransactions, "amount")). - Collections & Tables: Bind another visual collection or table directly to
root.highValueTransactions. - Text & Badges: Display counts or stats (e.g.,
root.highValueTransactions.lengthitems matching criteria`).
7. Formulas
You can use the formula component to access the formula builder and perform complex calculations, which can also be stored as variables for reuse.
String Functions
| Function | Signature | Description |
|---|---|---|
UPPER | UPPER(val: string) | Converts string to uppercase. |
LOWER | LOWER(val: string) | Converts string to lowercase. |
TRIM | TRIM(val: string) | Strips leading and trailing whitespace. |
CONCAT | CONCAT(...args: unknown[]) | Concatenates arguments into a single string. |
SLICE | SLICE(str, start, end?) | Returns a section of a string. |
REPLACE | REPLACE(str, pattern, replacement) | Replaces matched text within a string. |
SPLIT | SPLIT(str, sep = ",") | Splits a string into an array by delimiter. |
Array & Statistical Functions
| Function | Signature | Description |
|---|---|---|
SUM | SUM(arr: unknown) | Sums all elements in an array or single number. |
AVG | AVG(...args: unknown[]) | Computes average across numbers and flattened arrays. |
FIRST | FIRST(arr: unknown) | Returns the first element of an array. |
LAST | LAST(arr: unknown) | Returns the last element of an array. |
LEN | LEN(val: unknown[] | string) | Returns length of array or string. |
JOIN | JOIN(arr, sep = ",") | Joins array elements into a delimited string. |
REVERSE | REVERSE(arr: unknown) | Returns a reversed copy of the array. |
SORT | SORT(arr: unknown) | Returns a sorted copy of the array. |
MAP | MAP(arr | obj, expr) | Transforms elements or properties using an expression. |
Mathematical Functions
| Function | Signature | Description |
|---|---|---|
ABS | ABS(n) | Absolute value |
POW | POW(base, exp) | Exponentiation |
SQRT | SQRT(n) | Square root |
MIN | MIN(...args) | Minimum value |
MAX | MAX(...args) | Maximum value |
ROUND | ROUND(n) | Round value |
CEIL | CEIL(n) | Ceiling for value |
FLOOR | FLOOR(n) | Floor for value |
In-Depth Guide: The MAP Function
The MAP function is one of the most powerful tools in the formula engine. It iterates across each element in an array (or properties in an object) and returns a newly transformed dataset.
Signature: MAP(array | object, 'FORMULA' | mapping)MAP is essential for collection transformations, arithmetic reductions, and projecting data for charts:
1. Contextual Keywords in Expressions
Within the formula string (wrapped in quotes), reference the current element and index using intuitive contextual keywords:
- Element Aliases:
item,val,value,element,el,_, or$ - Iteration Index (0-based):
indexori
// Arithmetic on numbers or scalar items
MAP(root["Numbers"], 'val * 2')
// 1-based numbered list prefixing
MAP(root["Labels"], 'i + 1 + ". " + val')
// Accessing fields via element keywords
MAP(root["Items"], 'item.price * item.quantity')2. Direct Property Shorthand
When iterating over an array of objects, each object's properties are automatically injected into the local evaluation scope. You can reference properties directly without needing item. prefixes:
// Automatically resolves 'Price' and 'Quantity' from each object
MAP(root["Line Items"], 'Price * Quantity')
// Concatenates fields directly from employee records
MAP(root["Employees"], 'FirstName + " " + LastName')3. Built-In Function Application
Transform each element with any built-in formula function, either explicitly inside an expression or by passing the function name as shorthand:
// Explicit invocation using 'val'
MAP(root["Descriptions"], 'UPPER(val)')
// Function name shorthand
MAP(root["Names"], 'UPPER')
// Rounding an array of numbers
MAP(root["Amounts"], 'ROUND')4. Object Projection & Chart Data Reshaping
The MAP function can construct new object shapes per item using object literal syntax or arrow notation (-> or =>). This is especially useful for formatting raw payload datasets into the structure required by Chart.js (such as Scatter coordinates or Bubble datasets):
Object Literal Syntax
// Scatter points: produces [{ x: ..., y: ... }, ...]
MAP(root["Records"], '{ x: item["Sales"], y: item["Profit"] }')
// Bubble points: produces [{ x: ..., y: ..., r: ... }, ...]
MAP(root["Campaigns"], '{ x: item.Spend, y: item.Conversions, r: item.ROI * 5 }')
// Key remapping
MAP(root["Categories"], '{ label: item.Title, value: item.Count }')Arrow Syntax (-> or =>)
// Remap Name to label and Score to value
MAP(root["Users"], 'Name -> label, Score -> value')5. Composition & Aggregation
MAP expressions can be combined with reduction and aggregation functions in a single statement:
// Calculate total order value across all line items
SUM(MAP(root["Items"], 'price * quantity'))
// Compute class average from student records
AVG(MAP(root["Students"], 'grade'))
// Create a comma-separated uppercase string
JOIN(MAP(root["Tags"], 'UPPER(name)'), ", ")6. Storing Evaluation Results to Variables
Like all formula components, you can define a Target Variable Name (e.g. chartSeriesData). When set, the evaluated MAP result is saved onto root.<variableName> (e.g. root.chartSeriesData), allowing any downstream Chart, Table, or Data Filter to consume it directly.
Usage Example
data = {
items: [1, 2, 3],
multiplier: 2,
};
'JOIN(SORT(arr(CONCAT(UPPER("hello"), ": ", SUM(items) * multiplier), CONCAT(LOWER("WORLD"), ": ", AVG(2, 4, 6) + 1))), " | ")',
Output: "HELLO: 12 | world: 5"