Computed Fields
Computed fields are values calculated automatically from form data. They update in real-time as users fill out the form.
Structure
Define computed fields in the computed property:
{
"computed": {
"fieldName": {
"expression": "...",
"label": "Display Label",
"format": "currency",
"display": true
}
}
}
Properties
| Property | Type | Required | Description |
|---|---|---|---|
expression | string | Yes | FEEL expression to calculate the value |
label | string | No | Display label when shown in form |
format | string | No | Display format (see Formats) |
display | boolean | No | Whether to show in the form UI |
Basic Example
{
"schema": {
"properties": {
"quantity": { "type": "integer" },
"unitPrice": { "type": "number" }
}
},
"computed": {
"total": {
"expression": "quantity * unitPrice",
"label": "Total",
"format": "currency",
"display": true
}
}
}
Expression Syntax
Arithmetic Operations
{
"sum": { "expression": "a + b" },
"difference": { "expression": "a - b" },
"product": { "expression": "a * b" },
"quotient": { "expression": "a / b" },
"power": { "expression": "base ** exponent" }
}
Referencing Form Fields
Reference any field by its name:
{
"fullName": {
"expression": "firstName + \" \" + lastName"
}
}
Referencing Other Computed Values
Use the computed. prefix to reference previously defined computed fields:
{
"computed": {
"subtotal": {
"expression": "quantity * unitPrice"
},
"tax": {
"expression": "computed.subtotal * 0.1"
},
"total": {
"expression": "computed.subtotal + computed.tax"
}
}
}
Note: Computed fields are evaluated in dependency order (topological sort). A computed field can reference any other computed field regardless of declaration order.
Conditional Expressions
Use if-then-else for conditional logic:
{
"discount": {
"expression": "if quantity >= 10 then 0.1 else 0"
},
"tier": {
"expression": "if total > 1000 then \"gold\" else if total > 500 then \"silver\" else \"bronze\""
}
}
Null Handling
Handle cases where values might be missing:
{
"safeTotal": {
"expression": "if quantity = null then 0 else quantity * unitPrice"
}
}
Formats
The format property controls how computed values are displayed:
| Format | Description | Example Output |
|---|---|---|
currency | Currency format (USD) | $1,234.56 |
percent | Percentage | 25% |
decimal(N) | N decimal places | 3.14 |
date | Date only | 1/15/2024 |
datetime | Date and time | 1/15/24, 10:30 AM |
{
"taxRate": {
"expression": "0.0825",
"format": "percent",
"display": true
},
"total": {
"expression": "subtotal * (1 + taxRate)",
"format": "currency",
"display": true
}
}
Common Patterns
Calculating Totals
{
"subtotal": {
"expression": "quantity * unitPrice"
},
"tax": {
"expression": "computed.subtotal * taxRate"
},
"total": {
"expression": "computed.subtotal + computed.tax",
"label": "Order Total",
"format": "currency",
"display": true
}
}
Percentage Calculations
{
"percentComplete": {
"expression": "completedTasks / totalTasks * 100",
"format": "percent",
"display": true
}
}
Conditional Status
{
"status": {
"expression": "if score >= 90 then \"Excellent\" else if score >= 70 then \"Good\" else \"Needs Improvement\"",
"display": true
}
}
Date Calculations
{
"daysUntilDue": {
"expression": "date(dueDate) - date(today())"
}
}
BMI Calculator Example
{
"schema": {
"properties": {
"weight": { "type": "number", "description": "Weight in kg" },
"height": { "type": "number", "description": "Height in cm" }
}
},
"computed": {
"heightInMeters": {
"expression": "height / 100"
},
"bmi": {
"expression": "weight / (computed.heightInMeters ** 2)",
"label": "BMI",
"format": "decimal(1)",
"display": true
},
"category": {
"expression": "if computed.bmi < 18.5 then \"Underweight\" else if computed.bmi < 25 then \"Normal\" else if computed.bmi < 30 then \"Overweight\" else \"Obese\"",
"label": "Category",
"display": true
}
}
}
Using Computed Values
In Visibility Conditions
{
"discountCode": {
"visibleWhen": "computed.total > 100"
}
}
In Validation Rules
{
"validations": [
{
"rule": "computed.total <= budget",
"message": "Order exceeds budget"
}
]
}
Display Options
Set display: true to show the computed value in the form:
{
"total": {
"expression": "quantity * price",
"label": "Total Price",
"format": "currency",
"display": true
}
}
Computed fields with display: false (or omitted) are calculated but not shown. They can still be used in other expressions and validation rules.