Skip to main content
Arcanflows

Calculated Fields

Create fields that automatically calculate values based on other form inputs.

Overview

Calculated fields automatically compute values based on other form inputs. Use them for totals, prices, dates, and dynamic content.

Basic Calculations

Simple Formula

json
{
  "type": "calculated",
  "name": "total",
  "label": "Total",
  "formula": "{{quantity}} * {{price}}"
}

Reference Syntax

SyntaxDescription
{{fieldName}}Get field value
{{fieldName.property}}Get nested property
{{fieldName[0]}}Get array item
{{fieldName.length}}Get array length

Arithmetic Operations

Basic Math

json
{
  "formula": "{{price}} + {{shipping}}"
}
OperatorDescriptionExample
+Addition{{a}} + {{b}}
-Subtraction{{a}} - {{b}}
*Multiplication{{a}} * {{b}}
/Division{{a}} / {{b}}
%Modulo{{a}} % {{b}}
**Power{{a}} ** 2

Order of Operations

json
{
  "formula": "({{subtotal}} + {{shipping}}) * (1 + {{taxRate}} / 100)"
}

Built-in Functions

Math Functions

FunctionDescriptionExample
round()Round to nearestround({{value}}, 2)
floor()Round downfloor({{value}})
ceil()Round upceil({{value}})
abs()Absolute valueabs({{value}})
min()Minimum valuemin({{a}}, {{b}})
max()Maximum valuemax({{a}}, {{b}})
sum()Sum of arraysum({{items}})
avg()Average of arrayavg({{scores}})

String Functions

FunctionDescriptionExample
concat()Join stringsconcat({{first}}, ' ', {{last}})
upper()Uppercaseupper({{name}})
lower()Lowercaselower({{email}})
trim()Remove whitespacetrim({{input}})
substr()Substringsubstr({{text}}, 0, 10)
length()String lengthlength({{text}})

Date Functions

FunctionDescriptionExample
today()Current datetoday()
now()Current datetimenow()
daysBetween()Days between datesdaysBetween({{start}}, {{end}})
addDays()Add days to dateaddDays({{date}}, 30)
formatDate()Format dateformatDate({{date}}, 'MMM D, YYYY')
year()Extract yearyear({{date}})
month()Extract monthmonth({{date}})
day()Extract dayday({{date}})

Conditional Logic

If/Else

json
{
  "formula": "if({{quantity}} >= 10, {{price}} * 0.9, {{price}})"
}

Multiple Conditions

json
{
  "formula": "if({{quantity}} >= 100, {{price}} * 0.8, if({{quantity}} >= 50, {{price}} * 0.9, {{price}}))"
}

Switch

json
{
  "formula": "switch({{plan}}, 'basic', 9.99, 'pro', 29.99, 'enterprise', 99.99, 0)"
}

Common Use Cases

Order Total

json
{
  "fields": [
    {
      "type": "number",
      "name": "quantity",
      "label": "Quantity",
      "min": 1
    },
    {
      "type": "number",
      "name": "unitPrice",
      "label": "Unit Price",
      "prefix": "$"
    },
    {
      "type": "calculated",
      "name": "subtotal",
      "label": "Subtotal",
      "formula": "{{quantity}} * {{unitPrice}}",
      "format": "currency"
    },
    {
      "type": "calculated",
      "name": "tax",
      "label": "Tax (8%)",
      "formula": "{{subtotal}} * 0.08",
      "format": "currency"
    },
    {
      "type": "calculated",
      "name": "total",
      "label": "Total",
      "formula": "{{subtotal}} + {{tax}}",
      "format": "currency",
      "highlight": true
    }
  ]
}

Age Calculator

json
{
  "type": "calculated",
  "name": "age",
  "label": "Age",
  "formula": "floor(daysBetween({{birthDate}}, today()) / 365)"
}

Full Name

json
{
  "type": "calculated",
  "name": "fullName",
  "label": "Full Name",
  "formula": "concat({{firstName}}, ' ', {{lastName}})"
}

Dynamic Pricing

json
{
  "type": "calculated",
  "name": "price",
  "label": "Price",
  "formula": "switch({{plan}}, 'monthly', 29, 'quarterly', 79, 'annual', 290, 0)",
  "format": "currency"
}

Discount Calculation

json
{
  "type": "calculated",
  "name": "discount",
  "label": "Discount",
  "formula": "if({{couponCode}} == 'SAVE20', {{subtotal}} * 0.2, if({{couponCode}} == 'SAVE10', {{subtotal}} * 0.1, 0))",
  "format": "currency"
}

Event Duration

json
{
  "type": "calculated",
  "name": "duration",
  "label": "Event Duration",
  "formula": "concat(daysBetween({{startDate}}, {{endDate}}), ' days')"
}

Line Item Totals

For repeating/array fields:

json
{
  "type": "calculated",
  "name": "orderTotal",
  "label": "Order Total",
  "formula": "sum(map({{lineItems}}, item => item.quantity * item.price))",
  "format": "currency"
}

Display Options

Formatting

json
{
  "type": "calculated",
  "name": "total",
  "formula": "{{subtotal}} + {{tax}}",
  "format": {
    "type": "currency",
    "currency": "USD",
    "decimals": 2
  }
}
FormatDescriptionExample Output
currencyMoney format$1,234.56
numberNumber with separators1,234.56
percentPercentage12.5%
decimalFixed decimals12.50
integerWhole number13

Read-Only Display

json
{
  "type": "calculated",
  "name": "total",
  "formula": "{{a}} + {{b}}",
  "display": {
    "style": "highlight",
    "size": "large",
    "prefix": "Total: $"
  }
}

Hidden Calculations

json
{
  "type": "calculated",
  "name": "internalScore",
  "formula": "{{a}} * 10 + {{b}} * 5",
  "hidden": true
}

Update Behavior

Real-Time Updates

json
{
  "type": "calculated",
  "formula": "{{quantity}} * {{price}}",
  "updateOn": "change",
  "debounce": 100
}
TriggerDescription
changeUpdate immediately on input
blurUpdate when field loses focus
manualOnly update on button click

Recalculation

json
{
  "type": "calculated",
  "formula": "{{a}} + {{b}}",
  "recalculate": {
    "onFieldChange": ["a", "b"],
    "onPageChange": true
  }
}

Error Handling

Default Values

json
{
  "type": "calculated",
  "formula": "{{quantity}} * {{price}}",
  "defaultValue": 0,
  "errorValue": "N/A"
}

Null Handling

json
{
  "formula": "coalesce({{discount}}, 0)"
}

Safe Division

json
{
  "formula": "if({{divisor}} != 0, {{dividend}} / {{divisor}}, 0)"
}

Advanced Examples

BMI Calculator

json
{
  "fields": [
    {
      "type": "number",
      "name": "weight",
      "label": "Weight (kg)"
    },
    {
      "type": "number",
      "name": "height",
      "label": "Height (m)"
    },
    {
      "type": "calculated",
      "name": "bmi",
      "label": "BMI",
      "formula": "round({{weight}} / ({{height}} ** 2), 1)"
    },
    {
      "type": "calculated",
      "name": "category",
      "label": "Category",
      "formula": "if({{bmi}} < 18.5, 'Underweight', if({{bmi}} < 25, 'Normal', if({{bmi}} < 30, 'Overweight', 'Obese')))"
    }
  ]
}

Loan Calculator

json
{
  "fields": [
    {
      "type": "number",
      "name": "principal",
      "label": "Loan Amount"
    },
    {
      "type": "number",
      "name": "rate",
      "label": "Annual Rate (%)"
    },
    {
      "type": "number",
      "name": "years",
      "label": "Term (years)"
    },
    {
      "type": "calculated",
      "name": "monthlyPayment",
      "label": "Monthly Payment",
      "formula": "round(({{principal}} * ({{rate}}/100/12) * ((1 + {{rate}}/100/12) ** ({{years}}*12))) / (((1 + {{rate}}/100/12) ** ({{years}}*12)) - 1), 2)",
      "format": "currency"
    }
  ]
}

Best Practices

  1. Test edge cases - Zero, negative, empty values
  2. Use meaningful names - Clear field naming
  3. Format appropriately - Currency, percentages, etc.
  4. Handle errors - Default/fallback values
  5. Optimize performance - Debounce rapid updates
  6. Document formulas - Add comments for complex calculations