For the complete documentation index, see llms.txt. This page is also available as Markdown.

Formula Columns

Compute the value of a column with a small JavaScript snippet that runs on the server every time an object is saved.

The Formula Columns plugin (formula-columns) lets you fill a column with a value that is computed from a small JavaScript snippet instead of being entered by hand. The snippet runs on the server during every save, so the calculated value is stored with the object like any other field value.

Typical uses are combining several fields into one display value, calculating a number from other fields, copying a value from a linked object, or generating an identifier. See Examples for ready-to-use snippets.

Enabling the plugin

formula-columns ships with every release. Make sure it is enabled in the Plugin Manager. Once enabled, a new option group "Formula Columns" appears in the column settings of the data model.

Configuring a formula

Open Data model β†’ Object type β†’ Columns, select the column that should hold the computed value, and open its Option tab. Enter the snippet under Formula Columns.

πŸ“· Screenshot: the "Formula Columns" option group in Data model β†’ Object type β†’ Columns β†’ Option, showing the script editor and the Debug toggle.

A column with a formula is still a normal column, so give it a type that fits the value you return (for example a text type for strings, a number type for numbers).

How the snippet runs

The plugin is a db_pre_save callback: it runs on /api/db before the object is written to the database, using the _all_fields mask so all object data is available. Your snippet is the body of an async function, so you can use await:

async function (objNew, objCurr, dataPath, dataPathCurr) {
    // ... your snippet ...
}

The return value of the snippet becomes the value of the formula column. The snippet is run with eval inside a try…catch (see Debugging below).

Available parameters

PARAMETER
DESCRIPTION

objNew

The new data of the object being saved β€” i.e. the fields of the object type (for a top-level object, its record; for a nested object, the nested record). This is where your own columns live, e.g. objNew.title.

objCurr

The data as currently stored in the database (the previous version). It is null on the first save, because there is no previous version yet.

dataPath

The path to the current data, starting at the top level. dataPath[0] is the object envelope β€” this is where the system fields such as _uuid, _id and _system_object_id live.

dataPathCurr

The same as dataPath, but for the current (stored) object data.

A known limitation: when the formula runs for a nested record, it does not know which record index it is currently in.

Utility functions and async

The formula runs inside an async function, so you can use await and standard browser/Node APIs such as fetch.

apiSearchBySIDs(sids, mode)

An async helper to look up objects by their system object id (_system_object_id). It accepts a single id or an array of ids and supports the formats long, short, long_inheritance, full and standard. It returns an array of the found objects (empty if none are found). See Read a value from a linked object.

Debugging and logging

Two tools help while you develop a formula:

  • Debug option β€” enable Debug on the column to store an event of type FORMULA_COLUMNS_DEBUG for each calculation, containing the input data and the result.

  • Errors β€” if the snippet throws, the error is caught and stored as an event of type FORMULA_COLUMNS_ERROR. The column is not changed in that case.

Inside the snippet you also have:

  • log β€” push messages that are stored in the system event, e.g. log.push({ info: info });

  • info β€” instance information such as the API url, useful for API calls.

πŸ“· Screenshot: a FORMULA_COLUMNS_DEBUG event in Events, showing the logged input and result.

Examples

See Examples for complete, copy-ready snippets:

Last updated