Custom & Computed Fields
Custom fields add data to a record without changing the application. Three kinds exist, and the difference between them is who fills them in:
| Kind | Who fills it | Example |
|---|---|---|
| Standard | a person, on the record | "Preferred contact method" |
| Calculated | the system, from a formula over this record's own fields | score * 10 + cf_bonus |
| Rollup | the system, by aggregating linked child rows | "Number of open requests" |
Calculated and rollup fields are read-only on the record and recalculate automatically whenever the data they depend on changes.
Where to find it
| Screen | Where it lives | What you need |
|---|---|---|
Custom Fields — /admin/custom-fields | Settings → Data model → Custom Fields | Permission to read custom fields; each target table has its own manage permission for writing |
Pick the table you are designing for at the top — Contacts, People or Scheduled events; the catalogue is per table. Each field's row shows its Label, Key, Type, Kind, Applies to and Enabled, with Required, Encrypted and Disabled badges where they apply, and Enable or Disable and Edit buttons for people who may manage that table's fields.
Creating a standard field
Press + Add field:
- Label — what people read.
- Key — the technical name. Locked after creation.
- Field kind — Standard, Calculated or Rollup. Locked after creation.
- Data type — the kind of value it holds.
- Options (one per line) — for a choice field.
- Required — the record cannot be saved without it.
- Encrypted (sensitive) — see below. Locked after creation.
- Enabled — untick and the field stops being offered without losing its data.
Encrypted fields
An encrypted field stores its values encrypted and shows them masked to anyone without the reveal permission. It must be declared at creation and cannot be turned on later.
Who a field applies to
By default a custom field applies to every contact, and the list says All contacts. The Applies to section of an existing field's Edit form narrows it: pick a role from Add a role… and press Attach role, and the field only shows on contacts holding one of the attached roles — client-only fields, staff-only fields, and so on. Each attach or detach takes effect at once.
Detach takes a role away, after you confirm; detaching every role puts it back to all contacts, and no data is deleted when you do. Roles managed at the global layer show as chips you cannot detach here.
Calculated fields
A calculated field carries a Formula. You reference this table's own columns by name, and sibling custom fields as cf_<key> — for example score * 10 + cf_bonus.
If the formula does not parse, the error tells you where — the parse position comes back from the server verbatim rather than as a generic "invalid formula".
Rollup fields
A rollup aggregates linked child rows onto this record. Its configuration is a short, fixed vocabulary:
| Setting | What it means |
|---|---|
| Source table (schema-qualified) | the child table, written with its group name in front |
| Link field | the child column that points at this record |
| Record id | always the record being recalculated — filled in for you |
| Aggregate | how to combine the rows: count, sum, min, max or avg (the average) |
| Field | the child column being aggregated. Optional with count — set it and only non-empty values are counted |
| Filter | optional; a structured filter, so a rollup can count only some of the child rows. If what you type is not a valid filter, the save stops and says so |
The child table must be event-enabled and linked to this table by the link field — otherwise the recalculation would have nothing to notice.
Which tables may have computed fields
Calculated and rollup kinds are offered for Contacts only at the moment. The kind picker disables them elsewhere and gives the reason: a table earns computed support once its editors prove that every change triggers a recalculation. A rollup that is only sometimes right is worse than no rollup.
When a stored configuration goes bad
If a formula or rollup configuration fails validation, the field comes back disabled, and its editor says This field is disabled: its stored configuration failed validation. with the stored error — not silently broken, and not silently dropped. Fix it and save; a valid save brings the field back through the normal lifecycle.
Cycles and dependents
Two computed fields cannot depend on each other. If a change would create a cycle, the save is refused and the message explains the cycle in plain English.
Deleting a field that other computed fields read is refused too, and the refusal names the dependent fields — you are told what to fix, not just that you cannot proceed.
Converting fields into an extension table
Standard custom fields of contacts can be moved into an extension table — a real table with one column per field — and the values move with them. On the Custom Fields page (Contacts), every standard field has a checkbox in the first column; tick the fields and press Convert to an extension table…. A greyed box instead of a checkbox says, on hover, why that field cannot be chosen: a calculated or rollup field has no stored value to move, a global field is managed from its owning space, a field other computed fields depend on must be freed first, and a field already being moved or already moved shows which table holds it.
The wizard has four steps:
- Table — a new table (give it a name; the key fills in) or an existing contact table of this space. The line under it says how many custom tables the space has used of its limit.
- Fields — one column per field. The column's type follows from the field's type: text stays text, a number becomes a decimal number, a date a date, a choice list stays a choice list with the same options, a multi-select a choice list that takes several. You may edit each column key. A value that cannot be moved as the new type (
n/ain a number field, say) is counted and the record named; choose Fix first (the default — the move is refused while any remain) or Move as text (the column becomes text, nothing is lost, the type is yours to tighten later). A required field becomes an optional column with a soft requirement recorded, so the missing-data alert counts what is empty instead of breaking rows. The SQL the engine will run is under a disclosure. - Who gets it — pre-ticked from where the chosen fields applied; change it if the table should show elsewhere. Also place its widget on the contact page is on by default, so the values do not vanish from the page as the move finishes; clear it to place the table yourself from the Page Designer.
- Check & apply — the dry run in words: how many values in how many contacts will move, which saved views, alert rules and scheduling profiles will be updated (listed), which will not and simply lose the column (listed with the reason), and which forms, widget conditions and import templates name these fields and will need your hand (listed). Apply asks for your password, the same confirm as creating any table, and that one confirm covers the whole move.
What moves: every stored value of the chosen fields, into the new table's columns, copied inside the request itself when the move is small and as a background job when it is large — the conversions panel under the list then shows a progress bar, and Run now asks the move job to continue at once. When the copy is complete and has been checked against the originals, field by field, the move finishes in one step: the table is attached where the fields applied, its widget placed, the views, alert rules and profiles that named the fields rewritten (a before-image kept of each), and the fields marked Moved to <table> — greyed in the list, their values now shown and edited in the table's panel on the contact. A move that cannot prove its copy is marked Failed with both counts in words and never finishes; Retry runs it again.
The original values are never deleted by the move. They stay, frozen, behind the moved fields (a write to a moved field is refused in words while the move runs). What happens to them afterwards is a space setting, crm.cf_convert.purge_after_days, edited where every space setting is (Settings → System settings, the space layer; it needs the settings-manage permission, and the panel row links to it for those who hold it):
- 30 (the default) means the originals are kept, frozen, for 30 days after the move and are then deleted by the system on its own — once a day the maintenance job Delete the original values of moved custom fields after their delay looks at every finished conversion and deletes the originals of those whose 30 days have passed. The deletion is the same soft deletion as Delete the moved values… (matched by the stored field ids), the converter and everyone who may delete the moved values in that space are notified, and Convert back ends for that conversion. The panel's Originals line shows the date: kept, frozen · deleted automatically on <date> (30 days; the daily check has been green since <date>).
- 0 turns automatic deletion off for the space: the originals stay until somebody deletes them by hand, and the line reads kept until you delete them (automatic deletion is off for this space).
- The days only count while the daily Moved custom fields check (Maintenance → Conformance, the
cf-conversionscard) stays green. The first green run only starts the clock — nothing is deleted the day the check first turns green. A red check, a check that has not run recently or one that is switched off holds every automatic deletion everywhere, resets every clock, and the days count again from the next green run; the line then reads deletion on hold: the cf-conversions check was red on <date> — the 30 days count again from its next green run (or has not run recently). A check that cannot vouch for one conversion vouches for none, on purpose. - After an automatic deletion the row reads Originals deleted automatically on <date> · Convert back ended on <date>, when the originals were deleted automatically; after a deletion by hand, Originals deleted by hand on <date>.
Convert back on a conversion row returns the fields: their values come back (an edit made in the table since the move is kept), the conversion's own changes to views, alert rules and profiles are undone (anything changed by hand since stays as it is, and a row it cannot judge is listed for you), the rows the conversion added are removed, and the new table is dropped with its data kept — it appears under Deleted tables (data retained) in Extension tables, where it can be restored or purged. Converting the same fields again into a table of the same name needs that deleted table purged first, or a new name. Convert back ends once the originals are deleted — by hand, or by the system after the space's delay.
Delete the moved values… on a finished conversion deletes the original values of exactly the fields that conversion moved — you type the table key to confirm; the deletion is soft and matched by the stored field ids, never by name — and the row then says Originals deleted by hand on <date>. Deleting needs its own permission, separate from converting and converting back.
A view, rule or profile that would stop working after the change is left as it was and named in the list, and the field's column simply drops out of it, as it would for any turned-off field. Form sections, show this widget when… expressions and import templates that name a converted field are not changed for you: the preview lists each one under needs your hand, with a link, so you can update it yourself. Convert back puts the view back as it was before the conversion, and the same goes for every alert rule and profile it changed, even if you edited them after the conversion.
Deleting a field
Delete is at the bottom of the field's form, and you are asked to confirm first. Deleting is soft: stored values are kept. The field stops being offered; nothing is destroyed.