You are viewing beta documentation for Formie 4.x. View the latest stable version (3.x) →
Fields

Write your own parsing logic for the Calculations field

The Calculations field evaluates a formula from other field values and shows the result in a read-only input. Formie uses a JavaScript implementation of Symfony Expression Syntax for front-end evaluation. When built-in formatting is not enough — currency display, rounding rules, capping input values before they enter the formula — you can hook into evaluation events and adjust the formula, variables, or result.

Prerequisites

  • A form with at least one Calculations field
  • Formie's front-end assets loaded on the page (included automatically when you use craft.formie.renderForm())

How evaluation events work

Formie fires two document-level events around each evaluation:

EventWhen it firesWhat you can change
formie:field:calculations:before-evaluateBefore the formula runsevent.detail.formula, event.detail.variables
formie:field:calculations:after-evaluateAfter the formula runs, before the input updatesevent.detail.result

Each event's detail includes a reference to the Calculations field element. Match the field you care about with dataset.formieInputId (the field handle) or dataset.formieFieldHandle.

Variables in event.detail.variables use keys derived from the referenced fields — typically the field handle or the internal variable name Formie generated for the formula.

Format results as currency

Suppose you have two Number fields and a Calculations field with the formula {fieldA} + {fieldB}. You want the result shown as USD.

Add this script on the page where the form renders:

document.addEventListener('formie:field:calculations:after-evaluate', (event) => {
    const { calculations, result } = event.detail;

    if (calculations?.dataset.formieInputId !== 'result') {
        return;
    }

    if (typeof result !== 'number') {
        return;
    }

    event.detail.result = new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
    }).format(result);
});

The field shows $0.00 on load (rather than 0) and updates as currency when dependent fields change.

Round numeric results

The same pattern works for rounding:

document.addEventListener('formie:field:calculations:after-evaluate', (event) => {
    const { calculations, result } = event.detail;

    if (calculations?.dataset.formieInputId !== 'result') {
        return;
    }

    if (typeof result === 'number') {
        event.detail.result = Math.round(result);
    }
});

Given 1.276 and 7.682 for the two Number fields, the displayed result becomes 9.

Cap values before evaluation

Use before-evaluate when you want to clamp or transform source values without changing what the user typed in the original fields.

If fieldA should contribute at most 20 to the calculation:

document.addEventListener('formie:field:calculations:before-evaluate', (event) => {
    const { calculations, variables } = event.detail;

    if (calculations?.dataset.formieInputId !== 'result') {
        return;
    }

    // Variable keys match what Formie generated for your formula — inspect
    // event.detail.variables in the browser console if unsure.
    Object.keys(variables).forEach((key) => {
        if (key.includes('fieldA') && variables[key] > 20) {
            variables[key] = 20;
        }
    });
});

The user can still enter values above 20 in the Number field; only the calculation respects the cap.

Advanced: modify the formula or inject functions

You can replace the formula string or add custom variable objects (including functions) before evaluation:

document.addEventListener('formie:field:calculations:before-evaluate', (event) => {
    const { calculations, variables } = event.detail;

    if (calculations?.dataset.formieInputId !== 'result') {
        return;
    }

    event.detail.formula = 'fieldA + fieldB + suffix.myMethod("🔥")';

    variables.suffix = {
        myMethod(string) {
            return ' is ' + string;
        },
    };
});

Given 1 and 5, the result becomes 6 is 🔥.

Tips

  • Use the after-evaluate event for display formatting. Use before-evaluate for logic that affects what the expression sees.
  • Prefer the Calculations field's built-in prefix, suffix, and decimal settings when they are enough. Custom events are for behaviour the field settings cannot express.
  • For formula syntax and built-in functions, see Calculations field in detail.