TotalBase
Design Form

Formulas

Computed values over a row or the page: card titles, colors, labels, visibility.

In the admin: Design form › a widget › Bind (ƒ) · Settings › Views › a layout

A formula computes a value: a card's title from two columns, a pin's color from a status, a label with a count, whether a field is visible. Formulas look like spreadsheet formulas, run in the browser as the page draws, and never change data.

Formulas appear in two places:

  • Layouts of the list types: a card's title and image, a kanban card's description, a calendar event's color, a map pin's icon. They read the row's columns.
  • Widget props, with the Bind button (ƒ) in the inspector: a text, a color, a label, Visible, Disabled, Read only. They read the page's variables and widgets.

Writing one

A Text's text as a formula on the Dispatch board: the functions on the left, the formula on the right.
A Text's text as a formula on the Dispatch board: the functions on the left, the formula on the right.
CONCATENATE({{brand}}, " ", {{model}})
IF({{stock}} <= 0, "error", "success")
"Visits (" + {{vars.visits.count}} + ")"
{{vars.record.data.status}} == "COMPLETED"

Tokens

TokenReads
{{column}}a column of the row: a list's row, a select's option, a table widget's row
{{fk}}in a view's title, description, color or icon: a foreign key shows as its row does in a grid (its table's row display), {{work_order}} → WO-1042; compared, it is its key
{{fk.column}}one step through a foreign key: {{site.address}}
{{vars.x.path}}a variable: {{vars.record.data.total}}, {{vars.unassigned.count}}. {{vars.x}} alone is a Value's value, or a Resource's or Call's data
{{controls.x.path}}a named widget's state: {{controls.selectCustomer.item.tax_id}}
{{slot.x.path}}inside a tab or a section: its item

Operators

+ (it joins text when either side is text), -, *, /, %; ==, !=, >, >=, <, <= (they compare dates too); &&, ||, !; and condition ? a : b.

Functions

GroupFunctions
LogicIF, IFS, AND, OR, NOT
TextCONCATENATE, UPPER, LOWER, TRIM, LEN, LEFT, RIGHT, MID, SUBSTITUTE
NumbersROUND, ROUNDUP, ROUNDDOWN, ABS, SUM, MIN, MAX, AVERAGE, PRODUCT, MOD, POWER, SQRT
ChecksISBLANK, ISNUMBER, ISTEXT
DatesDATE, TODAY, NOW, YEAR, MONTH, DAY, EDATE, DATEDIF
Formatting valuesFORMAT_NUMBER(n, decimals or pattern), CURRENCY(n, code), FORMAT_DATE(d, pattern?), in the user's language
Rich textBOLD, ITALIC, UNDERLINE, STRIKETHROUGH, COLOR, BADGE, LINK, NEW_LINE, ICON

A bare {{price}} stays the raw number; CURRENCY({{price}}, "ARS") shows it as money.

Where a formula fits

  • A computed input: an input's value can be a formula instead of a variable: {{vars.subtotal.value}} * 1.21. It then shows the result, read-only, and saves nothing. What must be stored, a trigger computes in PostgreSQL, or Code sets with record.set.
  • Per option: a select's option label or color can be a formula evaluated for each option: {{code}} + " - " + {{description}}, or {{balance}} < 0 ? "error" : "success".
  • Per item: a tab's label, such as "Payments (" + {{vars.payments.count}} + ")", and its Visible and Disabled.

Props that say what a widget is (its variable, its column, whether it's multiple) or its layout (size, orientation) stay fixed: only what can follow the page's data takes a formula.

When it fails

A formula never breaks the page. One that fails (a division by zero, a missing token) gives no value, and the prop's fixed value is used instead. A token with no value reads as empty in a text.

Formulas aren't filters

A Resource's where doesn't use formulas: {{vars.*}} there is bound as a parameter of the query, and PostgreSQL does the filtering. Conditions on a column's look are filters too, evaluated by PostgreSQL. See Variables and Column presentation.

Next steps

  • Code: when a computed value isn't enough.