Skip to content

Calculations and piped answers

Turn answers into numbers such as prices and scores, and show answers or results inside later questions and the ending of a trulyform form.

View as Markdown

All docs pages
On this page

What you need to know

  • A calculation is a named number computed from answers, such as a price, a score or a count.
  • It is a small expression tree: read answers with answer, add up choice scores with option_score, and combine values with operations that each take exactly two arguments.
  • If an input has not been answered, the calculation has no value yet.
  • Piping shows an earlier answer, or a calculation's result, inside a later question or on the ending screen.
  • Calculations and piping are available on every plan.
  • trulyform does not take payments. A calculation can show an amount, but collecting it happens elsewhere.

Calculation format

Calculations live in the definition's calculations list:

Key Notes
id A UUIDv7, unique within the form.
name Required, up to 100 characters. The form owner sees it next to each response.
decimals Required. Decimal places of the result, from 0 to 6.
expression The root expression node.

Expression nodes

Node Shape Value
constant {"type": "constant", "value": "1.5"} A decimal number, written as a string.
answer {"type": "answer", "ref": "<question id>"} The answer to a number, nps, opinion_scale question.
option_score {"type": "option_score", "ref": "<question id>"} The total score of the options chosen in a single_choice, dropdown, multiple_choice, ranking, matrix question.
calculation {"type": "calculation", "ref": "<calculation id>"} The result of another calculation.
add {"type": "add", "args": [a, b]} a + b
subtract {"type": "subtract", "args": [a, b]} a − b
multiply {"type": "multiply", "args": [a, b]} a × b
divide {"type": "divide", "args": [a, b]} a ÷ b, to 6 decimal places. Dividing by zero gives no result.
min {"type": "min", "args": [a, b]} The smaller of a and b.
max {"type": "max", "args": [a, b]} The larger of a and b.
round {"type": "round", "args": [a, {"type": "constant", "value": "0"}]} a rounded half up to the number of decimal places in the second argument, 0 to 6.

Operations take exactly two arguments, and an expression can be nested up to 12 levels deep. A form can have up to 100 calculations.

How results are worked out

  • Arithmetic is exact decimal arithmetic: 0.1 + 0.2 is 0.3.
  • Every step keeps 6 decimal places, rounded half up. Division also stops at 6 places, so 1 ÷ 3 is 0.333333.
  • The final result is rounded half up to the calculation's decimals.
  • A calculation node uses the referenced calculation's unrounded value, not the result shown with its decimals. If one shows 1.5 as 2, another that doubles it gets 3. To build on the shown value, wrap the reference in a round node.
  • Results must stay below 10^18 in size.
  • An option without a score counts as 0. For multiple choice the scores of every chosen option are added; for a matrix, the score of the chosen column in every row.
  • A calculation has no value while an input is unanswered or hidden, after dividing by zero, or when a reference is missing. get_response reports the reason as the calculation's error.
  • A choice question with nothing chosen counts as unanswered, not as 0. For optional extras that feed a price, make the question required and add an option such as "No extras" with a score of "0".

Example

The workshop registration prices a booking: each ticket option has a score (its price), and each "number of people" option a score (the count). The calculation multiplies the two.

Workshop registration: calculations

[
    {
        "id": "01990000-0000-7000-8000-000000000131",
        "name": "Total price",
        "decimals": 2,
        "expression": {"type":"multiply","args":[{"type":"option_score","ref":"01990000-0000-7000-8000-000000000103"},{"type":"option_score","ref":"01990000-0000-7000-8000-000000000104"}]}
    }
]

Select the text to copy it.

The customer feedback survey averages a matrix: the scores of the three rows are added up and divided by 3, with one decimal place.

Piped answers

An answerToken node shows an answer or a calculation result inside rich text:

Thanks, followed by the name the person typed

{
    "type": "paragraph",
    "content": [
        { "type": "text", "text": "Thanks, " },
        {
            "type": "answerToken",
            "attrs": { "source": "answer", "ref": "01990000-0000-7000-8000-000000000001", "fallback": "there" }
        },
        { "type": "text", "text": "!" }
    ]
}

Select the text to copy it.

  • source is answer with a question ID in ref, or calculation with a calculation ID.
  • fallback is shown when there is nothing to show yet. It is required and may be an empty string. Write the text around a token so it still reads well with the fallback, such as "Estimated price (USD): " with the fallback "to be confirmed".
  • A piped answer must come from an earlier question, and never from a statement. A piped calculation may only use questions that come earlier.
  • The welcome screen comes before every question, so it cannot pipe answers. The ending can pipe any answer or calculation.

Piped answers appear as respondents see them: choice labels, several choices separated by commas, a consent answer as Yes or No, and a score followed by its comment. A piped calculation shows exactly decimals places, such as 120.00, with no thousands separator or currency symbol; write the symbol in the text around it.

The workshop registration's ending greets the person by name and shows the price:

Workshop registration: ending

{
    "title": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"You are booked in, "},{"type":"answerToken","attrs":{"source":"answer","ref":"01990000-0000-7000-8000-000000000101","fallback":"friend"}},{"type":"text","text":"!"}]}]},
    "description": {"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Total to pay on the day (USD): "},{"type":"answerToken","attrs":{"source":"calculation","ref":"01990000-0000-7000-8000-000000000131","fallback":"to be confirmed"}},{"type":"text","text":"."}]}]}
}

Select the text to copy it.

Ready to build?
Connect your assistant.

Pick your assistant, sign in to trulyform, and ask for the form you need.

Choose your assistant