Loading

Datastore Field Types

Every field type the platform offers, what each one stores, when to reach for it and when not to.

Available Field Types Reference

When you add a field to a datastore, the Field Type dropdown lists over 50 supported types. Each one renders differently, accepts different conditional options, and stores its value in a different way. Use this article as the quick-reference map; each type has its own dedicated article in this section.

Text input

  • Text Box — single-line text.
  • Text Area — multi-line text.
  • Code Editor — text input with syntax highlighting.
  • WYSIWYG Editor — rich-text editor.
  • Password — masked input.
  • Phone Number — international phone-number input with country picker.
  • Random Alphanumeric String — auto-generated string of a chosen length.

Numbers, dates, time

  • Number — integer or decimal with optional Min/Max/Units.
  • Slider — numeric slider with Min/Max/Increment.
  • Date, Date and Time, Time — date/time pickers.
  • Colour — colour picker.

Selection

  • Tickbox (Single) — single checkbox.
  • Tickbox (Multiple) (Manual) / (DB) — multi-select checkboxes from a manual list or DB-driven list.
  • Toggle Switch — single yes/no toggle.
  • Radios — radio buttons from a manual list.
  • Pills — selectable pills with custom CSS.
  • Dropdown Box — Single/Manual, Single/DB, Searchable/DB, Multiple-Linked/DB.

Files and media

  • File Upload — full-featured uploader with image resizing and library access.
  • File Store Selection — pick existing files from a configured file store.
  • Signature — capture a drawn signature.
  • Screen/Media Recorder — record screen, webcam, or audio.
  • Image Plotter — annotate or plot points on an image.
  • Web Video — embed video from a hosting provider.

Location and contact

  • Postal Address — multi-field address with optional Google Places autocomplete.
  • Geolocation — capture latitude/longitude.
  • Credit/Debit Card — PCI-compliant card input.

Lookups and search

  • AJAX Search (DB) / (URL) / (Active Directory) — type-ahead search against different data sources.
  • Active Directory Object — pick an AD user, group, or computer.
  • User Search — type-ahead user picker.

Form structure and conditional logic

  • Conditional Form, Dynamic Conditional Form — fields whose options each reveal their own sub-fields.
  • Dynamic Add/Remove Field — repeatable field group with add/remove controls.
  • Line Item Builder — repeatable row builder for line items.

Display and custom

  • Icon, Icon Select — icon-only display, or single/multi icon picker.
  • SQL Query, Custom, Custom PHP Code — execute SQL/HTML/PHP at render time.
  • Audit Link — link to row history.
  • Hidden, Special Hidden — invisible fields with stored values.
  • Dummy Field — placeholder used by conditional forms.

Text Box

A single-line text field. The most-used type in the platform and the right answer for most short values.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

A single line of text, up to a length you set. No line breaks — pressing return moves to the next field rather than starting a new line.

When to use it

  • Names, references, titles, short codes.
  • Anything free-form that will not run past a line.
  • Values you will search or sort on — text boxes index and sort predictably.

When not to

The temptation is to use it for everything, because it always works. Two cases where it should not be:

  • A value from a fixed set. Use a dropdown or radios. Free text for a status field produces "Open", "open", "OPEN" and "Opne", and no report can group them.
  • A value with its own type. Dates, numbers, phone numbers and addresses all have proper types that validate, sort and format correctly. A date in a text box sorts alphabetically, which puts December before February.

Set the length deliberately

Long enough for real data and no longer. A 20-character surname field will fail somebody eventually; a 500-character one invites people to paste a paragraph into it.

Names and addresses need more room than English-language intuition suggests — allow for longer names, accented characters and double-barrelled surnames.

Use validation

Where the value has a shape — a reference format, a code — validate it. Catching a malformed value at entry is far cheaper than finding it in a report, and it is the difference between a field that stays clean and one that decays.

Watch for the notes field

A text box named "Notes" or "Other" becomes where everything that did not fit goes. When you find yourself reading one to answer a question, that is a signal a real field is missing — and the fix is to add it rather than to widen the box.

Worked example

A customer datastore uses text boxes for first name, surname and a purchase order reference, with the reference validated against the customer's format. Status is a dropdown rather than a text box, so the pipeline report groups cleanly — a decision made at design time that avoided a data-cleaning exercise later.

Recommendations

  • Use a proper type where one exists, rather than defaulting to text.
  • Set realistic lengths — generous for names, tight for codes.
  • Validate anything with a format.
  • Treat a growing notes field as a missing field.

Text Area

A multi-line text field for content that runs to sentences or paragraphs.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

Plain text with line breaks preserved, and no formatting — no bold, no lists, no links. If you need those, the WYSIWYG editor is the right type.

When to use it

  • Descriptions, notes, comments, instructions.
  • Anything a person writes in prose.
  • Content whose length you cannot predict.

It is for prose, not data

The important discipline. A text area is where information goes to become unqueryable — you can search it, but you cannot group by it, count it or report on it meaningfully.

So if somebody will ever ask "how many of these are X", X needs to be its own field. Recording it in prose means the answer is a person reading every record.

Watch what accumulates in it

Text areas attract structure over time. A "Notes" field that consistently contains a date, a name and an outcome is three fields waiting to be created, and the sooner you notice the less history there is to migrate.

Reading a sample of what people have actually written is the quickest way to find the fields your model is missing.

Search finds it; reports do not

Text areas are searchable, so a value in one is findable. That is genuinely useful and it is not the same as reportable — searching finds records containing a word, and reporting needs the value in a field of its own.

Consider the timeline instead

Where a text area is being used as a running log — people appending updates with dates — the activity stream is the better home. It gives each entry an author, a timestamp, a type and a visibility, none of which a text area has.

A note appended to a text area loses who wrote it and when, which is exactly what somebody will want to know later.

Size the box to the content

A box three lines tall invites three lines. Where you want a paragraph, show a box that looks like it expects one — people write to fill the space they are given.

Worked example

A case datastore has a text area for background. Reviewing a sample shows most entries begin with a referral source and a date, so both become proper fields. The text area keeps the narrative, the two new fields make the referral report possible, and running updates move to the record's timeline.

Recommendations

  • Anything you will count belongs in its own field.
  • Read a sample of what people write — it reveals missing fields.
  • Use the timeline for running updates, not a text area.
  • Reach for WYSIWYG only if formatting genuinely matters.

Code Editor

A code editor with syntax highlighting, for storing source, markup or configuration.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

Plain text, exactly as typed, with the editor providing highlighting, indentation and a monospaced font. Nothing is interpreted or reformatted on save — what you typed is what is stored.

When to use it

  • Templates and snippets that are edited by technical users.
  • Configuration in a structured format.
  • Any field where whitespace and exact characters matter.

Not a formatting field

People sometimes reach for this to store rich content because it accepts markup. If the content is prose that needs formatting, the WYSIWYG editor is the right type — it produces markup without asking the author to write any.

Asking a non-technical colleague to maintain content in a code editor is how content stops being maintained.

Exact characters matter

Unlike a text area, this field is used where a stray space or a smart quote breaks something. The editor's monospaced font and highlighting exist to make those visible — which is most of why the type exists at all.

Think about who edits it

Content stored here is usually consumed by something — rendered, executed, parsed. That makes an editing mistake a functional failure rather than a cosmetic one.

Restrict the field to the people who should be changing it, using field security. A code field that anybody with edit access can change is a fragile arrangement.

Consider what happens to bad input

The field stores whatever it is given; it does not validate that the content is correct for its purpose. Malformed markup or a syntax error is discovered wherever the value is used, which may be far from where it was entered.

Where that matters, test after editing rather than assuming a successful save means a working value.

Audit is your safety net

Because the audit trail records before-and-after, a change that broke something can be seen and reversed. That is worth knowing before somebody edits a template in production — the previous version is recoverable.

Worked example

A document template is held in a code editor field, restricted by field security to two administrators. When an edit breaks the rendering, the audit trail shows exactly what changed, and the previous content is restored from it in under a minute.

Recommendations

  • Use WYSIWYG for prose, this for code.
  • Restrict who can edit it with field security.
  • Test after editing — a save is not a validation.
  • Rely on the audit trail to recover a bad change.

WYSIWYG Editor

A rich text editor producing formatted content — bold, lists, links, headings — without the author writing markup.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

Markup generated from what the author formatted. The stored value is markup even though the author never saw any.

When to use it

  • Content that will be displayed formatted — descriptions, articles, letter bodies.
  • Anything authored by somebody non-technical who needs more than plain text.
  • E-mail and document content where emphasis and structure matter.

Pasting from a word processor

The most common practical problem. Content pasted from a word processor brings its own formatting with it — fonts, sizes, colours, spacing — and the result looks wrong wherever it is displayed, often only on some devices.

Tell authors to paste as plain text and format afterwards. It takes a moment and prevents a class of "why does this look strange" that is genuinely hard to diagnose from the stored value.

It is not a page designer

People will try to control layout with it — tables for positioning, repeated line breaks for spacing, fixed widths. That produces content that looks right in one place and breaks everywhere else, particularly in e-mail and on phones.

Keep it to semantic formatting: emphasis, lists, links, headings. Layout belongs to whatever renders the content.

Where the content is going matters

Content destined for e-mail has different constraints from content shown on a page — e-mail clients support far less. Content that will be printed or turned into a PDF has different constraints again.

Author with the destination in mind, and check it there rather than in the editor.

Markup and safety

Because the stored value is markup, what happens to it when displayed matters. Where content is authored by people you do not fully trust — an external portal, a public submission — that is a question to settle deliberately rather than assume.

Search sees the text, not the formatting

Searching finds the words. It does not find "everything with a heading", and the markup itself is not what people are searching for. That is the right behaviour and worth knowing when a search result looks unexpected.

Worked example

A team uses WYSIWYG for e-mail template bodies. After a run of messages displaying oddly in one client, they find authors had been pasting from a word processor. Guidance to paste as plain text, plus a check in a real client before sending, ends the problem entirely.

Recommendations

  • Tell authors to paste as plain text.
  • Keep it to semantic formatting, not layout.
  • Check content where it will be displayed, not in the editor.
  • Use a text area where formatting adds nothing.

Date

A calendar date, with no time component.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

A date. Sorting, comparison and date arithmetic all work correctly, and the display format follows the user's locale rather than being baked into the stored value.

Why not a text box

Because a date in a text box sorts alphabetically, which puts December before February and 2019 before 2020 only by accident. It also cannot be compared, cannot drive a reminder, and accepts "next Tuesday" as readily as a date.

This is the single most common modelling mistake, and it is expensive to correct once there is data.

When to use it

  • Dates of birth, start dates, deadlines, renewal dates.
  • Anything where the time of day is genuinely irrelevant.

Date or date and time?

Ask whether the time will ever matter. A date of birth never needs one. An appointment does. A "date received" probably does, even if nobody thinks so today — and adding time later is harder than ignoring it.

Where you are unsure and the value records an event rather than a plan, prefer date and time.

Time zones do not apply

A date has no time, so it has no time zone — which is exactly why it is the right type for a birthday. Somebody's birthday is the same date wherever they are, and storing it with a time invites a time-zone conversion that can shift it by a day.

Defaults save typing

Where a date is usually today, default it. Most date fields are filled with today's date most of the time, and a default that is right nine times in ten is worth having.

Validate the range where it helps

A date of birth in the future or a start date twenty years hence is almost always a typo — usually a mistyped year. Range validation catches those at entry, where they cost nothing, rather than in a report.

Think about empty

Decide what a blank date means and whether it is allowed. "No end date" meaning ongoing is a legitimate and useful convention; a blank that means somebody did not know is a different thing, and conflating the two makes reports ambiguous.

Worked example

A membership datastore uses a date for joined and a nullable date for left, where blank means still a member. Range validation rejects joining dates before the organisation existed, which caught a run of records mistyped with the wrong century during an import.

Recommendations

  • Never store a date in a text box.
  • Prefer date and time for events, plain date for plans and anniversaries.
  • Default to today where that is usually right.
  • Decide what blank means and write it down.

Date and Time

A date together with a time — a specific moment rather than a day.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

When to use it

  • Appointments, bookings and meetings.
  • When something happened — received, sent, completed, approved.
  • Anything where ordering within a day matters.

Prefer it for events

If the field records something that happened, the time is nearly always worth having even when nobody asks for it today. Two things recorded on the same day are indistinguishable without it, and "which came first" is a question that arrives eventually — usually during an investigation, when it matters most.

Adding time later does not retrofit it to existing records.

Time zones

The question to settle: are your users all in one place?

If they are, this is straightforward. If they are not, be clear whose time a stored moment is in and how it is displayed — an appointment at 2pm means different things in London and New York, and a booking system that gets this wrong fails in a way that is obvious to the customer and confusing to support.

Do not use it for a plain date

A date of birth stored with a time is a date that can shift across a day boundary under time-zone conversion. Use the plain date type where the time genuinely has no meaning.

Automatic timestamps

Where the value records when a record was created or changed, remember the audit trail already captures that — with the acting identity and the before-and-after state, which a field does not.

A "date created" field is still worth having when the value is business-meaningful and needs to be reportable or editable. It is not worth having purely to know when a row appeared.

Defaults

Defaulting to now suits fields recording an action as it happens. It is the wrong default for a planned future moment, where an empty field prompts a real decision and a default invites somebody to accept it.

Displaying it

Seconds are rarely useful to a reader. Where the field is business information rather than a technical timestamp, showing minutes is usually enough — precision that nobody uses is noise on every screen it appears on.

Worked example

A service records enquiries with a date and time received, defaulted to now. Response-time reporting works because the ordering within a day is real. The related "target resolution date" is a plain date, because a target expressed to the minute would be false precision.

Recommendations

  • Use it for anything that happened, even if time seems irrelevant today.
  • Settle time zones before going live with distributed users.
  • Do not duplicate the audit trail with technical timestamps.
  • Display to the precision people use.

Time

A time of day on its own, with no date attached.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

A time — half past nine — without saying which day. That is the whole character of the type and the source of both its uses and its misuses.

When it is right

  • Recurring times — opening hours, a daily deadline, a shift start.
  • A time paired with a separate date, where the two are genuinely independent.
  • Durations expressed as a clock value, where that is the convention.

When it is wrong

For a specific moment. If the answer to "which day?" matters, use date and time rather than a time field alongside a date field.

Two separate fields can disagree, can be filled in half, and have to be recombined for every comparison — sorting by "when did this happen" across a date field and a time field is markedly more awkward than sorting one column.

The recurring case is where it shines

Opening hours are the clearest example: nine to five, every weekday, with no date involved. Storing that as a date and time would require inventing a date, and the invented date would then appear in reports and confuse people.

Watch the midnight boundary

A shift running from 22:00 to 06:00 has an end time numerically smaller than its start. Any comparison or duration calculation needs to handle that, and code that assumes end is after start will produce a negative duration.

This is the classic bug with time fields, and it is worth thinking about before somebody enters a night shift.

Validate the range where it applies

Where a time must fall within a window — appointment slots within opening hours — validating at entry saves a booking that cannot be honoured.

Decide the precision

Most business uses want minutes. Offering seconds invites people to enter them and produces values nobody reads. Match the field to how the value is actually used.

Worked example

A venue datastore stores opening and closing times per weekday as time fields, with no dates involved — which is correct, because they recur. Individual bookings against that venue use date and time, because each is a specific moment. The booking form validates the time falls within the venue's hours.

Recommendations

  • Use it for recurring times, not for moments.
  • Never pair a date field with a time field to represent one moment.
  • Handle the midnight crossing in anything that compares times.
  • Offer minutes, not seconds, unless seconds are genuinely used.

Number

A numeric field, stored as a number rather than as text.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Why the type matters

A number in a text box sorts alphabetically — 10 before 9, 100 before 20 — cannot be totalled, averaged or compared, and accepts "about five". None of that is recoverable without a migration.

If a value will ever be summed, compared or ranked, it belongs in a number field.

Decide the precision

How many decimal places, and be deliberate about it. Two questions settle most cases:

  • Is it a count? Whole numbers, no decimals. Half a person is a modelling error.
  • Is it money? Two decimal places for most currencies — and see below, because money has a second problem.

Money needs more than a number

An amount without a currency is ambiguous the moment you trade in more than one, and adding currency later means interpreting every historical value.

Where amounts matter, look at how the platform's ledger handles it: an amount is stored alongside its currency and the rate applied, so a historical figure still means what it meant. A bare number field is fine for a single-currency business and a trap for one that grows.

Rounding compounds

Store enough precision for the calculation, not just for the display. A unit price rounded to two places and then multiplied by a quantity produces a total that disagrees with the same sum done properly — by pennies, which is exactly the kind of discrepancy that consumes an afternoon.

Where a value feeds a calculation, keep the precision and round at the point of display.

Set a range where one exists

A quantity that cannot be negative, a percentage that cannot exceed 100, an age that cannot be 300. Range validation catches typos — a mistyped extra digit is the commonest data error there is, and it is invisible in a list of numbers.

Zero is not blank

Decide whether the field can be empty and what that means. Zero and "not recorded" are different facts, and conflating them makes averages wrong: a blank treated as zero drags a mean down, and a zero treated as blank hides a real value.

Watch identifiers that look numeric

Reference numbers, account numbers and postcodes are not numbers even when they contain digits. They have leading zeros that matter, they are never arithmetic, and storing them as numbers silently strips the zeros.

If you would never add two of them together, it is text.

Worked example

An order line stores quantity as a whole number with a minimum of one, and unit price to four decimal places even though it displays two — so line totals agree with the invoice. The customer's account number, which begins with a zero, is a text field.

Recommendations

  • Anything summed or compared belongs in a number field.
  • Keep calculation precision, round at display.
  • Validate the range — it catches mistyped digits.
  • Identifiers are text, however numeric they look.

Slider

A numeric field entered by dragging a handle along a range rather than typing.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

A number, exactly as a number field does. The difference is entirely in how it is entered — which means the choice is a usability decision, not a data one.

Where it works well

  • Bounded ratings — satisfaction, confidence, priority on a fixed scale.
  • Approximate values where precision is not the point.
  • Percentages, where the ends are meaningful and the middle is a judgement.
  • Touch interfaces, where dragging beats typing.

Where it does not

Anywhere the exact number matters. A slider makes entering a precise value harder than typing one — try setting 47 on a 0–100 slider on a phone — and users will accept whatever is near enough.

That is fine for a satisfaction rating and unacceptable for a price, a quantity or an age.

It biases the answer

Worth knowing if the value is data you will analyse. Sliders cluster: at the ends, at the middle, and at the position the handle starts in. Somebody who feels roughly positive drags to about three-quarters rather than deciding on 78.

So slider data is coarser than it looks, and treating a 73 as meaningfully different from a 76 is over-reading it.

Set the range and step deliberately

The range defines what is possible and the step defines how fine the choice is. A step of one on a 0–100 slider offers a hundred positions nobody can distinguish; a step of five or ten gives you honest data and an easier control.

Where you want a rating, consider whether five or ten discrete options — as radios or pills — would serve better and read more clearly in a report.

Mind the starting position

Wherever the handle starts is where an untouched field records a value. If it starts in the middle, every skipped question records a neutral answer that looks like a real one.

Decide whether an unanswered slider should be distinguishable from a deliberate middle, and if so do not default it to the middle.

Accessibility

Sliders are harder to operate for some users than a number box or a set of options, and harder still on a small screen. Where a field is on a public form, that matters more than the visual appeal.

Worked example

A feedback form uses a 0–10 slider with a step of one for likelihood to recommend, which is the conventional scale for that question. A separate "hours spent" field on the same form is a number box, because 3.5 hours needs to be exact and nobody should be dragging for it.

Recommendations

  • Use it for judgements, never for exact values.
  • Choose a coarse step — fine ones give false precision.
  • Think about the starting position and what an untouched field records.
  • Consider radios or pills for small rating scales.

Colour

A colour, chosen from a picker rather than typed.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

A colour value, in a form that can be used directly wherever the colour is applied — a status pill, a calendar entry, a chart series, a theme.

When to use it

  • Categorisation people will see — status colours, category colours, calendar colours.
  • Branding, where a tenant or a product carries its own colour.
  • Chart series, where a consistent colour per category makes reports readable.

Colour must not be the only signal

The accessibility point, and it applies every time. Around one man in twelve has some form of colour vision deficiency, and red against green — the most common status pairing there is — is precisely the one that fails.

Always pair colour with something else: a label, an icon, a position. A status shown only as a coloured dot is unreadable to a real proportion of your users, and unreadable in print and in a black-and-white export.

Constrain the palette

Letting users pick any colour produces twelve statuses in twelve shades of blue, none distinguishable at a glance. Where colour carries meaning, a small fixed set works far better than free choice.

Consider whether a dropdown of named options is a better fit than a colour picker — it gives you consistency and a reportable value.

Check the contrast

A colour chosen for its appearance on a white background may be illegible as a pill with white text on it. If the colour will sit behind text, either constrain the choices to ones that work or ensure the text colour adapts.

Pale yellow with white text is a combination somebody will choose.

Colour meaning is not universal

Red for bad and green for good is a convention, not a law, and it does not hold everywhere. Where an application is used internationally, lean harder on labels.

Reporting on it is rarely useful

Grouping by colour is grouping by presentation, which usually means the real grouping field is missing. If you find yourself reporting on colour, the category itself should be a field and the colour should hang off it.

Worked example

A case datastore stores status as a dropdown and holds the colour on the status record rather than on each case. Cases display a coloured pill with the status name in it, so the colour helps people scan and the name carries the meaning. Reports group by status, never by colour.

Recommendations

  • Never let colour be the only signal.
  • Constrain the palette where colour carries meaning.
  • Check contrast if text sits on the colour.
  • Hang colour off the category, not off every record.

Tickbox (Single)

One tickbox representing a yes or no. Stored as a whole number — one or zero.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

When to use it

  • A flag: active, approved, archived, opted in.
  • A confirmation: terms accepted, checked, verified.
  • Anything genuinely binary.

It joins, so it reports well

Single-select types are joinable — the stored value points at one thing, so a report can join through it and group by the source record. That is what makes "count by category" a query rather than an exercise.

The three-state problem

A tickbox has two visible states and often three meanings: yes, no, and nobody has said.

An unticked box on a new record usually means "not answered", not "no" — but it is stored identically to a deliberate no. That is fine for "archived" and actively misleading for "consent given", where "we never asked" and "they declined" are very different facts.

Where the distinction matters, use a dropdown with three options and make the absence explicit.

Name it for the ticked state

"Active" ticked means active. "Not active" ticked means... people will get it wrong, and so will whoever writes a report against it. Avoid negatives entirely — "Inactive" and "Do not contact" produce double negatives in filters that nobody reads correctly.

Set the default deliberately

Most tickboxes should default to unticked, because that is the safe state for a flag that grants something. A field defaulting to ticked is a decision made on the user's behalf, and for anything consent-shaped that is the wrong way round.

Do not use it for a small set

Three tickboxes representing mutually exclusive options is a dropdown wearing a disguise, and nothing stops two being ticked at once. If exactly one should be true, use radios or a dropdown and let the type enforce it.

Tickbox or toggle switch?

They look similar and are not the same. The tickbox stores a whole number and joins; the toggle switch stores a floating-point value and does not. For an ordinary yes-or-no flag on a datastore, the tickbox is the right choice.

Worked example

A contact datastore uses tickboxes for "active" and "staff member", both defaulting to unticked and both named positively. Marketing consent is deliberately not a tickbox but a three-option dropdown — given, declined, not asked — because the difference matters and a blank tickbox could not express it.

Recommendations

  • Name it for the ticked state, and never use a negative.
  • Default to unticked for anything that grants something.
  • Use three options where "not asked" is a real state.
  • Never fake a single choice with several tickboxes.

Tickbox (Multiple) (Manual)

A set of tickboxes where any number may be ticked, with the options defined on the field itself.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

It does not join

Multi-select fields store their selections as text rather than as a single reference, so they are not joinable. A report cannot join through this field and group by it the way it can with a single-select one.

That is not a defect — one value cannot point at three records — but it is the trade you are making. If "how many records are in each category" is a question you will ask often, a single-select field, or a proper linked datastore, will serve you far better.

Where it fits

  • A short fixed list of attributes that will not change — the sort of thing that is part of the form's design.
  • Checklists, where seeing every option matters.
  • Anywhere the user should be aware of what they are not selecting.

Visibility is the reason to choose it

Like radios, every option is on screen. For a checklist that is the entire point — somebody confirming which checks were carried out needs to see the ones they did not tick.

A multi-select dropdown hides the unselected options, which is fine for tags and wrong for a checklist.

Keep it short

Six or eight at most. A long column of tickboxes is slow to scan and easy to mis-tick, and the visibility advantage disappears once the list runs past a screen.

Manual or database-backed?

The same test as the dropdown family. If the business maintains the list, or an option might ever need an attribute of its own, use the database-backed version. If the list is genuinely part of the form's definition, manual is simpler.

Unticked is ambiguous

The three-state problem, multiplied. An unticked box means "no" or "not considered", and across eight options you cannot tell a carefully completed checklist from an untouched one.

Where that matters — and on a compliance checklist it always does — pair it with a confirmation that the checklist was completed, so a blank set is distinguishable from a deliberate one.

Order for the task

Group related options together and follow the order somebody would work through them. A checklist ordered to match the physical process is faster and less error-prone than one ordered alphabetically.

Changing the list

Adding an option to an existing checklist means historical records were completed against a different list. That is not wrong, and it is worth being aware of when comparing across time — a check nobody could have ticked last year will look neglected.

Worked example

A safety inspection form uses a manual multiple tickbox for the eight standard checks, ordered to match the walk-round, with a separate "inspection completed" tickbox. A record with nothing ticked and the completion box ticked is a genuine all-clear; one with neither is an unfinished inspection, and the two are now distinguishable.

Recommendations

  • Use it where seeing the unselected options matters.
  • Six to eight options, ordered for the task.
  • Add a completion flag so blank and deliberate differ.
  • Go database-backed if the business maintains the list.

Tickbox (Multiple) (DB)

A set of tickboxes whose options are records in another datastore, with any number selectable.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • Datastores — the datastore the options come from

It does not join

Multi-select fields store their selections as text rather than as a single reference, so they are not joinable. A report cannot join through this field and group by it the way it can with a single-select one.

That is not a defect — one value cannot point at three records — but it is the trade you are making. If "how many records are in each category" is a question you will ask often, a single-select field, or a proper linked datastore, will serve you far better.

What the database backing gives you

  • The business maintains the list without an architect.
  • Options can carry their own information and their own permissions.
  • Renaming an option updates it everywhere it is displayed.
  • Options can be deactivated rather than deleted.

The control constrains the list

This is the tension in this type. The database backing invites a growing list; the tickbox control needs a short one.

Every option is rendered, so a source datastore that grows to sixty records produces sixty tickboxes on the form. Nobody reads that, and the visibility that justified tickboxes over a multi-select dropdown is long gone.

Filter, and watch the count

Filter to active records, and check periodically how many that actually is. A form that was comfortable with twelve options and now has forty has quietly become unusable, and nobody reports it as a bug — they just stop reading it.

Once past a dozen or so, move to the multi-select dropdown.

Choose this over the dropdown when visibility matters

If the user needs to see the full set to answer well — a checklist drawn from a maintained list of checks — tickboxes are right and the list must be kept short. If they are tagging, the dropdown is right and the list may be long.

Deactivate rather than delete

The standard rule for database-backed options. A deleted record leaves historical selections pointing at nothing.

Consider whether it should be a datastore

The same question as any multi-select: if the pairing needs attributes — when, by whom, at what level — a linking datastore is the right shape and this field is not.

Order them

Because the options come from a datastore, their order comes from it too. Give the source a sort field rather than relying on whatever order records happen to be in, which is otherwise creation order and looks arbitrary.

Worked example

An accreditation datastore lists the standards an organisation holds, drawn from a maintained Standards datastore with an active flag and a sort order. Fourteen active standards render as fourteen tickboxes, which is at the upper limit — a review is diarised to move the field to a multi-select dropdown if the list reaches twenty.

Recommendations

  • Keep the active list short — a dozen or so.
  • Watch the count over time; it grows quietly.
  • Give the source a sort order.
  • Move to a dropdown once visibility stops being achievable.

Toggle Switch

A switch presenting an on or off choice. Visually it is a tickbox with a different control; underneath it is not quite the same.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

The difference that matters

A tickbox stores a whole number and is joinable. A toggle switch stores a floating-point value and is not.

For a straightforward yes-or-no flag on a datastore you will report on, that makes the tickbox the better default. Reach for the toggle when the control is what you want and the reporting characteristics do not matter.

Be careful copying a registration

Because the two types store differently, registering a column as one type when the physical column suits the other causes problems that are awkward to trace — values that will not save, or comparisons that behave oddly.

If you are copying an existing field definition as a starting point, check which of the two you have actually copied.

When a toggle is the right control

  • Settings. A switch reads as "this is on or off right now", which suits configuration better than a tickbox reading as "I am asserting this".
  • Immediate effect. Where flipping it changes something visibly, a switch matches the mental model.
  • Touch interfaces, where a switch is an easier target.

When a tickbox is

  • Anything you will group or report on.
  • Confirmations and agreements — "I accept" is a tickbox, not a switch.
  • Anywhere alongside other tickboxes, for visual consistency.

The same three-state problem

Everything said about tickboxes applies. A switch has two positions and often three meanings, and "off" is indistinguishable from "never touched". Where that matters, use a three-option field instead.

Do not mix the two on one form

A form with some tickboxes and some switches looks unfinished and makes people wonder whether the difference means something. Pick one for a given form and stay with it.

Worked example

An instance configuration screen uses toggle switches, because each one turns a feature on or off and the switch reads correctly for that. The datastores those features write to use tickboxes for their flags, because those are reported on weekly.

Recommendations

  • Default to the tickbox for datastore flags you will report on.
  • Use the switch for settings, where it reads better.
  • Check which type you copied when duplicating a field.
  • Do not mix both on one form.

Radios

A set of options where exactly one may be chosen, all visible at once.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

A whole number identifying the chosen option, which is why it groups and reports cleanly.

It joins, so it reports well

Single-select types are joinable — the stored value points at one thing, so a report can join through it and group by the source record. That is what makes "count by category" a query rather than an exercise.

Visibility is the point

Radios show every option without the user doing anything. That matters when the options themselves carry information — somebody choosing a priority benefits from seeing that "urgent" exists and what sits either side of it.

A dropdown hides that until clicked, and a user who does not know the range cannot judge their answer against it.

Where the limit is

About five or six. Beyond that the form becomes a wall of options, scanning gets slower rather than faster, and a dropdown is the better control.

The test is whether somebody can take in all the options at a glance. If they have to read down a list, you have passed the point.

Order them meaningfully

If the options have a natural order — low to high, first to last — use it. Alphabetical ordering on an ordered set is actively unhelpful: "High, Low, Medium" tells the reader nothing about the scale and makes them think.

Radios or a dropdown?

  • Radios — few options, and seeing them helps the decision.
  • Dropdown — more options, or the choice is routine and the list is just a lookup.

They are hard to unset

Once a radio is chosen, there is usually no way back to nothing. If "no answer" is a legitimate state, include it as an explicit option rather than expecting people to find a way to clear the field.

Defaults change answers

A pre-selected radio is an answer, and a meaningful proportion of people will leave it. That is fine where the default is genuinely the common case and wrong where you want a considered choice.

For anything where the answer matters — a consent question, a risk rating — start with nothing selected and make the field required.

Manual options here

Radios take their options from the field definition rather than from another datastore. That suits a small fixed set; where the options are themselves records you maintain, a database-backed dropdown is the better fit.

Worked example

A triage form uses radios for priority — low, medium, high, urgent — in that order, with nothing pre-selected and the field required. Seeing all four helps the assessor calibrate, and the absence of a default means every record carries a decision rather than an accepted suggestion.

Recommendations

  • Five or six options at most.
  • Order by meaning, not alphabetically.
  • Include an explicit "none" if that is a real answer.
  • No default where you want a considered choice.

Pills

Options presented as buttons rather than as a list or a dropdown.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

The selection as text, and the type is joinable — so it reports better than the multi-select types while presenting more visually than radios.

Where it earns its place

  • Touch interfaces. A pill is a far easier target than a radio button, which matters on a phone.
  • Short labels. Options that are a word or two look good as buttons and terrible as a wrapped list.
  • Filters. Pills read naturally as a set of toggles across the top of a list.
  • Forms people fill in quickly, where a large target speeds things up.

Where it does not

Long labels. A pill containing a sentence stops looking like a button and the layout becomes unpredictable across screen sizes — three pills on one line on a laptop, one and a half on a phone.

If your options need explaining, radios with their explanatory text are the better control.

Keep the set small

The same constraint as radios, and for the same reason. A dozen pills is a wall of buttons that is harder to scan than a dropdown, and the visual appeal that justified the choice disappears.

Order matters more here

Because pills wrap across lines, the order determines the layout. A natural sequence keeps related options together; an arbitrary one scatters them across rows and makes the set look unconsidered.

Test it on a phone

This is the type most likely to look fine in design and wrong in use. Pills wrap, and where they wrap depends on the screen — check the actual layout on a small screen before shipping a form that depends on it.

It is a presentation choice

Worth being clear: pills, radios and a dropdown can all express the same choice. The data is equivalent; what differs is how quickly somebody can answer and how the form reads.

Choose on the strength of who is filling it in and on what device, not because one looks more modern.

Worked example

A mobile inspection form uses pills for condition — good, fair, poor — because inspectors complete it one-handed on a phone and a large target matters. The same value on the back-office screen is a dropdown, since it is one field among thirty and nobody is tapping.

Recommendations

  • Use it for short labels and touch interfaces.
  • Keep the set small — the same limit as radios.
  • Check the wrapping on a phone.
  • Choose on usage, not on appearance.

Dropdown (Single) (Manual)

A dropdown whose options are defined on the field itself rather than drawn from another datastore. One choice, stored as a whole number.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

It joins, so it reports well

Single-select types are joinable — the stored value points at one thing, so a report can join through it and group by the source record. That is what makes "count by category" a query rather than an exercise.

Manual or database-backed?

This is the decision the whole family turns on.

Manual suits a short, stable list that is genuinely part of the field's definition: yes/no/unknown, low/medium/high, a handful of fixed statuses. Changing it means editing the field.

Database-backed suits options that are themselves records — departments, categories, products, locations. Anything somebody might want to add without an architect, or that carries other information, belongs in a datastore.

The test

Ask whether an option could ever need a second attribute. If a category might one day need a colour, an owner or an active flag, it is a record — and putting it in a manual list now means migrating it later.

Also ask who maintains it. If the answer is "the business", it should not require an architect to edit a field definition.

The stored value is an index

The field stores a number identifying the chosen option, not the option's text. That has a consequence worth understanding: reordering or removing options can change what existing records mean.

Add new options at the end. Do not delete an option that has been used — if it is obsolete, leave it in place so historical records still resolve, and stop offering it if the interface allows.

Keep it short

Beyond a dozen or so, a plain dropdown becomes a scrolling exercise. The searchable variant handles long lists far better.

Write the options as the user reads them

They appear verbatim on the form. "Awaiting customer response" is a status somebody understands; "AWAIT_CUST" is an internal code that will need explaining forever.

Include the awkward option

Most lists need an "other" or "not known". Without one, people pick the nearest wrong answer, which is worse than an honest unknown because it looks like data.

Worked example

A case datastore uses a manual dropdown for urgency — three fixed options that are part of the process definition. Case category is database-backed instead, because the business adds categories twice a year and each one carries a default owner. When urgency later needs a fourth option, it is added at the end so existing records are unaffected.

Recommendations

  • Manual for short fixed lists, a datastore for anything the business maintains.
  • Add options at the end; never delete a used one.
  • Write options in the user’s language.
  • Include "other" or "not known" where honest.

Dropdown (Single) (DB)

A dropdown whose options are records in another datastore. One choice, stored as a reference to that record.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • Datastores — the datastore the options come from

This is a relationship

The important framing: this is not a list of words, it is a link between two records. The field stores which record was chosen, so everything about that record is reachable from this one.

That is what a manual list cannot do, and it is why this type is the right default for anything the business maintains.

It joins, so it reports well

Single-select types are joinable — the stored value points at one thing, so a report can join through it and group by the source record. That is what makes "count by category" a query rather than an exercise.

So "cases by category" or "orders by customer" is a report joining through this field, and the source record's other fields are available to it.

What it gives you

  • One place to correct a name. Renaming a category updates every record referencing it, because they reference it rather than copying it.
  • Options that carry data. A category can have an owner, a colour, an active flag — all reachable from the record that chose it.
  • Business-maintained lists. Adding an option is adding a record, which needs no architect.
  • Its own permissions and audit. The option list is a datastore like any other.

Retiring an option

Do not delete a record that has been referenced — historical records point at it and will be left pointing at nothing.

Give the source datastore an "active" flag instead, filter the dropdown to active records, and mark the obsolete one inactive. Existing references keep resolving and nobody can choose it again.

Filter what is offered

A dropdown can be restricted to a subset — active records, or ones matching something on the current record. That keeps the list short and stops people choosing something inapplicable, which is better than validating it afterwards.

When the list gets long

Past a few dozen options, use the searchable variant. A plain dropdown of six hundred customers is unusable, and users will pick something near the top rather than scroll.

Think about what happens on delete

Decide what should happen to records referencing an option if it is ever removed. "Nothing, because we never delete them" is a legitimate answer — but it should be a decision rather than something discovered.

Worked example

A ticket datastore links to a Categories datastore, each category carrying a default team and an active flag. The dropdown is filtered to active categories. When a category is retired it is marked inactive rather than deleted, so two years of historical tickets still report correctly under it.

Recommendations

  • Prefer this to a manual list for anything the business maintains.
  • Never delete a referenced record — use an active flag.
  • Filter the dropdown to what is currently valid.
  • Switch to searchable once the list is long.

Dropdown (Searchable) (DB)

A database-backed dropdown that lets the user type to filter. Same stored value and same relationship as the plain variant; a different control.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • Datastores — the datastore the options come from

It joins, so it reports well

Single-select types are joinable — the stored value points at one thing, so a report can join through it and group by the source record. That is what makes "count by category" a query rather than an exercise.

Use it for anything long

The threshold is lower than people expect — a few dozen options is enough. Scrolling a long list is slow, and worse, it changes behaviour: users pick something visible near the top rather than the right answer further down.

Typing three characters to narrow six hundred customers to two is faster and more accurate than any amount of scrolling.

Search what people actually know

Make sure the searchable text is what the user has in their head. Somebody looking for a customer knows the company name; they may not know the account code. A field searching only on a code fails the person holding a name.

Where several things identify a record, let the search cover them.

Show enough to disambiguate

"Smith" is not a useful result three times over. Include something that distinguishes them — a town, a reference, a date of birth — so the user can pick correctly without opening each one.

This is the commonest complaint about searchable dropdowns and it is a configuration matter, not a limitation.

It still needs filtering

Searchable does not mean unfiltered. Restrict to active records as you would a plain dropdown — a searchable list of every customer who ever existed will surface closed accounts, and somebody will choose one.

Think about the empty state

What a user sees before typing matters. Showing nothing is honest but leaves people unsure whether the field works; showing a first page gives them something to react to. Either is defensible — decide rather than leaving it to chance.

What if it is not there?

Somebody will search for a record that does not exist yet. Make sure there is an obvious next step, because the alternative is a user typing the name into a notes field and moving on — which is how duplicate and unlinked data appears.

Prefer it as the default

For database-backed dropdowns, searchable is a good default even for medium lists. It behaves like a plain dropdown when the list is short and stays usable when the list grows — which it will.

Worked example

An order form links to Customers through a searchable dropdown filtered to active accounts, searching on company name, trading name and account code, and showing the town beside each result. Sales staff find a customer in two or three keystrokes, and the three "Smith Ltd" entries are distinguishable at a glance.

Recommendations

  • Default to searchable for database-backed dropdowns.
  • Search on what the user knows, not only on a code.
  • Show a distinguishing detail in the results.
  • Give people a route when the record does not exist.

Dropdown (Multiple, Linked) (DB)

A database-backed dropdown allowing several selections rather than one.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • Datastores — the datastore the options come from

It does not join

Multi-select fields store their selections as text rather than as a single reference, so they are not joinable. A report cannot join through this field and group by it the way it can with a single-select one.

That is not a defect — one value cannot point at three records — but it is the trade you are making. If "how many records are in each category" is a question you will ask often, a single-select field, or a proper linked datastore, will serve you far better.

When it is the right answer

  • Tags and labels, where the set is descriptive rather than structural.
  • A short list of attributes — languages spoken, accessibility requirements, areas of interest.
  • Anywhere the selections need no information of their own.

When a linking datastore is better

The moment the relationship needs to carry anything. If you find yourself wanting to record when something was selected, who selected it, or any qualifier on the pairing, a multi-select field cannot hold it.

A person's skills is the classic example. "Which skills" fits a multi-select; "which skills, at what level, assessed when, by whom" does not — that is a datastore of its own, with a record per person-skill pairing.

Ask the question early, because converting a populated multi-select into a linking datastore is a migration.

Reporting is the real cost

Because the field does not join, questions like "how many records carry each tag" are meaningfully harder than the same question against a single-select field. If that question is central to why the field exists, reconsider the shape.

Keep the option list disciplined

Multi-selects encourage sprawl — it costs nothing to add another option and nothing to select five. Left alone, tag lists grow to hundreds of near-synonyms, and at that point they describe nothing.

Review the list periodically and merge duplicates. A tag used twice is noise.

Order the options

Long unordered multi-selects are genuinely hard to use, because the user is scanning for several things rather than one. Group or order them meaningfully, and filter to active records as with any database-backed field.

Removing an option

The same rule as single-select: do not delete a record that has been selected. Mark it inactive so existing selections still resolve.

Worked example

A volunteer datastore uses a multi-select for languages spoken — descriptive, no qualifiers needed, and nobody reports on it heavily. Availability is modelled as a separate datastore instead, one record per volunteer per session, because each needs a confirmed flag and a note. The distinction was made at design time and saved a migration.

Recommendations

  • Ask whether the pairing needs attributes before choosing this.
  • Use a linking datastore when it does.
  • Review tag lists and merge near-duplicates.
  • Deactivate, never delete, a selected option.

Icon

Stores a reference to an icon, for display alongside a record.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Where it helps

  • Categories and types, where a consistent icon speeds recognition in a list.
  • Navigation and menus, where an icon anchors a repeated item.
  • Status, alongside a label.

Put it on the category, not the record

The most common mistake. An icon belongs on the thing being categorised — the status, the type, the department — not on every record that has one.

Setting it per record means a thousand records each carrying a choice, inconsistency between them, and no single place to change it. Setting it on the category means one decision and automatic consistency.

Never icon-only

The accessibility rule, and the same one as colour. An icon alone is ambiguous — a symbol meaning "urgent" to the person who chose it means little to everybody else, and nothing at all to a screen reader.

Always pair it with a label. The icon speeds recognition for people who already know the system; the label is what makes it usable for everybody else.

Keep the set small and consistent

Icons work by being distinguishable at a glance. Twelve similar symbols are slower to read than plain text, and a set drawn from different styles looks unfinished.

Pick a small number of clearly different icons from one family and stay inside it.

Meaning is conventional, not inherent

Very few symbols are universally understood — a handful, and the rest are learned. An icon nobody has been taught is decoration.

Where a symbol carries real meaning, make sure it is introduced somewhere, and lean on the label until people have learned it.

Do not report on it

Grouping by icon is grouping by presentation. If you find yourself wanting to, the category behind it is the field you actually want — which is another reason to hang the icon off a category record.

Icon or icon select?

This type stores a reference you set as configuration. The icon select field gives a user a picker. If an end user should be choosing, use that one; if it is part of your design, this is right.

Worked example

A case datastore shows an icon beside each case type, held on the Case Types record rather than on individual cases. Lists show the icon and the type name together. When the icon for one type is changed, it changes everywhere at once, and no case record was touched.

Recommendations

  • Store it on the category, not on every record.
  • Always show a label beside it.
  • One icon family, and a small set.
  • Report on the category, never on the icon.

Icon Select

Presents a browsable, searchable set of icons for the user to choose from.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

When to hand over the choice

  • Configuration screens, where an administrator is defining categories, statuses or menu items.
  • Personalisation, where the icon is the user's own.
  • Anywhere the person choosing knows what it should mean better than you did at design time.

When not to

On ordinary data entry. A user filling in a case should not be choosing an icon for it — that is a decision that belongs to the case type, and asking for it produces inconsistency and slows them down.

If you find an icon select on a record-level form, the icon almost certainly belongs on a category instead.

Expect inconsistency

Given a free choice from a large set, people choose differently. Two administrators defining similar categories will pick different icons, and the result reads as unconsidered even though every individual choice was reasonable.

Where consistency matters, guidance helps more than restriction — a short note on the screen about which family to use, or a convention written down, will do more than hoping.

Search only helps if names match

Users search for what they mean — "customer", "money", "warning" — and icon names are frequently more literal, so the useful icon is often found under a name nobody would guess. Set expectations that browsing may beat searching.

The same accessibility rule

Whatever a user picks, the icon must not be the only signal. Ensure your display shows a label alongside it, because you cannot rely on somebody's choice being self-explanatory to anybody else.

Icons are not status

An icon chosen once and displayed is fine. An icon used to convey a changing state is a poor mechanism — it needs to be understood, cannot be reported on, and is easily missed.

Use a proper status field and let the icon hang off it.

Set a sensible default

Most people will accept it, which is a good thing here — a default that suits the common case produces more consistency than an empty field and better results than a random pick.

Worked example

An administration screen for case types uses an icon select, with a default and a note recommending the outline family. Individual cases have no icon field at all — they inherit their type's — so the icons stay consistent and case entry is one field shorter.

Recommendations

  • Use it on configuration screens, not on data entry.
  • Set a default and give a short convention.
  • Always pair with a label on display.
  • Never convey status with an icon alone.

File Upload

Lets a user attach one or more files to a record.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • File Stores — where uploaded files are held
  • Large Uploads — sessions for files too big for one request
  • Documents — document management, which may suit better

What the field stores

A reference to the uploaded file, not the file itself. The file lives in a file store; the field records which one. Like every media type, it stores text and does not join.

Settle these before going live

  1. What may be uploaded. Restrict to the types you expect. An open field accepts anything anybody can produce.
  2. How large. Both a per-file limit and an expectation of total volume — files grow faster than records.
  3. Where it goes. Which file store, and what its retention and backup arrangements are.
  4. Whether it is scanned. See below.

Uploads are the riskiest input you accept

Everything else a user submits is text you control the interpretation of. A file is arbitrary content that something downstream will open.

Virus scanning is available and ships disabled. If your application accepts uploads from outside your organisation — a portal, a public form, a supplier — turning it on is the single most valuable thing on this page. A detected threat can be quarantined and logged rather than silently discarded.

Restrict the types

Accept what you need and nothing else. "Images only" or "PDF and Word" is both safer and kinder — a user who uploads the wrong thing finds out immediately rather than when somebody tries to open it.

Do not rely on the file extension alone as a security control; treat it as a usability aid and let scanning do the security work.

Large files

Very large uploads are handled as sessions rather than as a single request, which is what makes them survivable on a poor connection. If your users routinely upload video or large scans, that is the path to use rather than raising a limit until it works.

Consider document management instead

If files need versions, approval, retention rules, redaction or generation from templates, a file upload field is the wrong tool. The document features exist for that, and retrofitting them onto an attachment field is not straightforward.

Use this field for genuine attachments — a photo of damage, a signed form, a supporting letter — and document management for documents.

Uploaded documents can be indexed

Text can be extracted from uploaded documents in the background so their contents become searchable. That is a scheduled task and it ships disabled, which is worth knowing if you expected to be able to search inside attachments.

Permissions apply to the record, not the file

Think about who can reach a file once uploaded, particularly where files are shared to another store or system. A file attached to a restricted record is only as protected as wherever it now lives.

Worked example

A claims portal accepts photographs and PDFs up to 10MB, with scanning enabled and quarantine on. Larger files go through the upload session path. Supporting evidence stays as attachments; the claim decision letter is a generated document instead, because it needs a template and a retention rule.

Recommendations

  • Enable scanning for anything accepting external uploads.
  • Restrict the file types you accept.
  • Use document management where versions or retention matter.
  • Decide the store and its retention before go-live.

File Store Selection

Lets a user choose a file already held in a file store, rather than uploading a new one.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • File Stores — the stores selectable files live in
  • Documents — document management

What it is for

Referencing shared material. Where many records point at the same file — a standard terms document, a product image, a policy — uploading a copy per record is waste that gets worse over time.

The argument for a reference

  • One copy to update. Replace the file once and every record referencing it is current.
  • No duplication. A thousand records referencing one document store one document.
  • One place to control access and retention.

And the argument against

A reference changes when the file changes — which is exactly what you want for a current policy and exactly wrong for evidence.

If a record needs to show what a document said at the time, an upload is correct and a reference is not. A quotation referencing "our standard terms" that silently updates when the terms change is a real problem, and it will be discovered during a dispute.

The test

Ask whether this record needs today's version or the version as it was. Current material — reference it. Evidence — attach it.

Keep the store organised

The field is only as usable as the store behind it. A store with four hundred files in no order makes selection slow and wrong choices likely. Structure it, name files meaningfully, and remove what is obsolete.

Removing a referenced file

The familiar rule. Deleting a file that records point at leaves them pointing at nothing, and the breakage appears wherever somebody tries to open it rather than at the moment of deletion.

Check what references a file before removing it.

Permissions are the store’s

Whether somebody can open a referenced file depends on the store, not on the record. A user with access to the record may or may not be able to open what it points at — worth checking rather than assuming, particularly where the store holds a mix of sensitivities.

Worked example

A quotation datastore references the current product datasheet from a file store, so a datasheet revision reaches every open quotation. The customer's signed acceptance is a file upload on the same record, because that must remain exactly as signed — the two fields sit side by side and are deliberately different types.

Recommendations

  • Reference current material, attach evidence.
  • Keep the store tidy — the field inherits its usability.
  • Check references before deleting a file.
  • Confirm store permissions match who can see the record.

Signature

Captures a signature drawn with a finger, stylus or mouse.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Forms:

  • Signature Requests — the stronger, evidenced alternative

What it stores

An image of the drawn mark, as text. It does not join and is not searchable in any meaningful sense — it is a picture.

Where it fits

  • Acknowledgement of receipt — a delivery, a collection, a handover.
  • Confirming attendance or that something was carried out.
  • Anywhere a signature is a familiar convention rather than a legal requirement.

Be clear what it proves

A drawn mark on its own is weak evidence. It shows that somebody drew something on a device at some point. It does not establish who they were, that they saw what they were signing, or that the document has not changed since.

That is fine for a delivery receipt. It is not sufficient where a signature carries legal weight, and it is worth being honest about that with whoever is asking for the feature.

Use electronic signatures where it matters

For agreements, consents and anything contested, the platform's electronic signature features exist precisely for this. They bind the signature to an identity, to the document as it stood, and to a recorded process — which is what makes it evidence rather than an image.

The distinction is worth explaining to stakeholders early, because "we need signatures" usually means one of the two and they are very different pieces of work.

Strengthen it with context

If you are using this field for something that might be questioned, record what surrounds it: who was signed in, when, from what device, and what they were shown. The audit trail gives you most of that.

A signature with a timestamp, an identity and a record of what was on screen is considerably more useful than an image alone.

Design for the device

Signing with a finger on a phone produces a mark that looks nothing like somebody's pen signature. That is normal and does not matter for acknowledgement — but do not build a process that expects to compare it to a specimen.

Give a reasonably sized signing area; a small box produces cramped marks and repeated attempts.

It is personal data

A signature identifies a person and is worth protecting accordingly — restricted like other personal data, and included in retention rather than kept indefinitely.

Worked example

A field service application captures a customer signature on completion, alongside the engineer's identity, the timestamp and the job record. It is an acknowledgement, not a contract. The service agreement the customer signs at sign-up goes through electronic signatures instead, because that one may need to be enforced.

Recommendations

  • Use it for acknowledgement, not for agreements.
  • Move to electronic signatures where the signature must hold up.
  • Record the surrounding context to give it weight.
  • Treat it as personal data for access and retention.

Screen/Media Recorder

Records audio, video or a screen capture from the browser and attaches it to the record.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • File Stores — where recordings are held
  • Large Uploads — the path for larger files

Where it earns its place

  • Fault reporting. Somebody showing a problem in thirty seconds beats a paragraph describing it badly.
  • Site and field notes, where speaking is faster and safer than typing.
  • Support and training, where a screen recording demonstrates the actual sequence.
  • Accessibility, where speaking is easier than writing for some users.

Recordings are not searchable

The important trade. Text can be searched, reported on and read at a glance. A recording must be watched or listened to, in real time, by each person who needs to know what it says.

So a recording is excellent as supporting evidence and poor as the only record. Where the content matters operationally, capture a short text summary alongside it.

They are large

Far larger than anything else you store. A few minutes of video is bigger than thousands of records, which affects storage, backup times and how long an upload takes on a poor connection.

Set an expectation of length in the interface — people record until told to stop, and a five-minute cap changes behaviour more than a note in guidance.

Browser permissions

Recording needs the user's permission for the microphone, camera or screen, requested by their browser. That prompt is unfamiliar to many people and is the commonest reason the feature "does not work".

Tell users what to expect before they hit it, and remember a refusal is often permanent until they change a browser setting.

Screen recording captures whatever is on screen

Including other applications, notifications and anything sensitive that happens to be visible. Warn people to close what they do not want captured — this is a real disclosure risk and it is entirely foreseeable.

Recordings are personal data

A voice identifies somebody; a video shows them and often others. Where recordings capture people who did not consent — a customer in the background of a site video — that needs thinking about, not assuming.

Set retention. Recordings kept indefinitely are the largest and most sensitive thing in your store.

Worked example

A maintenance application lets engineers record up to sixty seconds of video at a fault, alongside a required one-line text description. Supervisors read the descriptions to triage and open the video only when it matters. Recordings are retained for twelve months, the text indefinitely.

Recommendations

  • Always capture a text summary too.
  • Cap the length in the interface.
  • Warn about the permission prompt and about screen contents.
  • Set a shorter retention than for text.

Image Plotter

Displays a fixed image and lets the user mark points on it, storing where they marked.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it is for

Anything whose location is relative to a picture rather than to the world:

  • Damage and defects on a vehicle diagram, a floor plan or an elevation.
  • Body maps in health and care recording.
  • Site plans — where on this layout is the issue.
  • Equipment diagrams — which component.

It is not a map

Positions are relative to the image, not to the earth. If you need a real-world location, that is the geolocation field or a postcode — and those support distance, radius and mapping, which this cannot.

The two get confused because both involve pointing at a picture. The test: would the answer change if the thing moved to another town? If yes, you need a location, not a plot.

The image is part of the data

This is the point people miss. Stored positions mean nothing without the image they were placed on — a mark at a given position on a vehicle diagram is a different panel if the diagram changes.

So changing the background image invalidates every existing record. If you must change it, keep the old image for historical records rather than replacing it, and understand that a new diagram is effectively a new field.

Choose the image carefully and once

Because of the above, this is a decision worth getting right before anyone uses it. A clear, uncluttered diagram at a sensible resolution, with the orientation people expect, and no text that would need translating.

Marks are not categories

The field records where; it does not record what. "Three marks on the nearside" is not the same as "a dent, a scratch and a chip". If the type of each mark matters, that needs its own structure — usually a related datastore with a position and a type per record.

Reporting is limited

Positions are coordinates on an image. You can show them and you cannot easily group by them — "how many defects on the front bumper" requires defining regions, which the field does not do for you.

Where that question matters, a dropdown of named areas alongside the plot will serve you far better than trying to derive regions from coordinates.

It works well on touch

Tapping a diagram is fast and natural on a phone or tablet, which is where this field is usually used. Make sure the image is legible at that size — a detailed plan that works on a laptop can be unusable on a handset.

Worked example

A vehicle inspection uses an image plotter over a standard four-view diagram, with a dropdown for damage type and a named-area dropdown beside it. The plot shows the assessor exactly where; the two dropdowns make the reporting possible. When the diagram is later redrawn, the old image is retained so historical inspections still make sense.

Recommendations

  • Never change the background image without keeping the old one.
  • Use geolocation for real-world positions.
  • Add a named-area field if you need to report.
  • Check legibility on a phone.

Web Video

Stores the address of a video hosted elsewhere and embeds it on the record.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Security:

  • Cookie Consent — the consent an embedded player usually requires

What it stores

A link, not a file. Nothing about the video is held here, which is the whole character of the type.

What that gives you

  • No storage cost, whatever the length or quality.
  • No bandwidth cost — the host serves it.
  • Adaptive playback on poor connections, which a plain file does not get.
  • Nothing to upload, which suits content that already exists.

And what you give up

  • Control. The video can be edited, made private or deleted by whoever owns it, and your record silently stops working.
  • Access control. A video visible to anyone with the link is not protected by your permissions, whatever the record says.
  • Longevity. Links rot. A field of embedded videos will contain dead ones within a few years.

Never use it for anything confidential

The important rule. A record restricted to three people, embedding a video anybody with the link can watch, is not restricted — and it looks restricted, which is worse than an obvious hole.

If the content is sensitive, host it where your permissions apply.

Embeds and cookie consent

Most video hosts set cookies and are treated as third-party services by consent management. On a consent-enabled page an embedded player will be blocked until the visitor accepts, and a blank space where a video should be reads as a broken page.

Provide a click-to-load placeholder explaining why, rather than leaving an empty box.

Validate the address

Accept the hosts you support and reject the rest at entry. An unrecognised address stored happily and failing to embed is a support call, and validation turns it into an immediate, self-service correction.

Check links periodically

Where video matters — training material, product demonstrations — something should notice when a link stops working. Left alone, nobody finds out until a user reports it, and by then it may have been broken for months.

Think about who can edit it

Anybody who can edit the field can point the record at any video on the internet. On a public-facing record that is worth restricting, because the content shown under your branding is then not entirely yours.

Worked example

A training datastore embeds course videos from the organisation's own channel, with the field validated to that host only and edit access restricted to the training team. A consent placeholder explains the block for visitors who decline. Confidential induction material is held as uploaded files instead, so record permissions apply.

Recommendations

  • Never embed confidential content.
  • Validate the host at entry.
  • Provide a consent placeholder, not a blank box.
  • Restrict who can change the address on public records.

Password

A field whose contents are masked as they are typed.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Security:

  • Authentication Methods — how user passwords are actually handled
  • Permissions — restricting who can see a secret

Masking is presentation

The dots hide the value from somebody looking over a shoulder. That is a real benefit and it is the only one the masking itself provides — it says nothing about how the value is stored or who can read it later.

Not for your users’ passwords

The most important thing on this page. Sign-in passwords are handled by the platform's own authentication, which hashes them, applies your policy, and never stores anything reversible.

Creating a password field on a datastore to hold user passwords bypasses all of that. Do not do it — and if you find one in an existing application, treat it as something to remove rather than to improve.

What it is legitimately for

  • A credential for a third-party system that your application must present.
  • A shared secret for an integration.
  • Anything a user should be able to enter without bystanders reading it.

Encrypt it, and restrict it

If the value is a real secret, two things follow. Turn on field encryption so it is not readable in a database backup, and use field security so only the people who need it can see it at all.

A masked field with neither is a secret in plain text with a cosmetic covering, which is a worse position than storing it openly and knowing you have.

Prefer not storing it

The best handling of a credential is not to hold one. Where the platform offers a proper connection type — a data source, an API client, a mail account — use it, because those store credentials encrypted and are built for rotation.

A password field is what you reach for when nothing better fits, not the first answer.

Masking hurts accuracy

People mistype what they cannot see, and a mistyped credential fails somewhere else entirely, often much later. Where the value is not secret from the person entering it, consider whether masking is helping or just making entry error-prone.

Think about the audit trail

Changes are recorded with before-and-after values like any field. For a genuine secret that means the audit trail contains it — worth knowing when deciding who may read the audit log for that datastore.

Worked example

An integration datastore holds a partner's SFTP credential in a password field, encrypted, with field security limiting it to two administrators. User sign-in for the same application uses the platform's own authentication with passkeys — no password field is involved anywhere in it.

Recommendations

  • Never use it for sign-in passwords.
  • Encrypt and restrict anything genuinely secret.
  • Prefer a proper connection type over storing a credential.
  • Consider who can read the audit trail for that field.

Phone Number

A telephone number, held in a form suited to dialling and messaging rather than as loose text.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Communication:

  • Message Log — SMS and WhatsApp, which depend on the format

Why not a text box

Because a phone number in free text arrives in a dozen shapes — with spaces, with brackets, with a leading zero, with a country code, with an extension bolted on the end. All of them look fine to a person and only some of them can be dialled or messaged by a system.

The moment you want to send an SMS, that variation becomes the reason messages do not arrive.

Format is the whole issue

A number stored as 07700 900123 is fine for a person reading it and not necessarily fine for a provider expecting international format. The commonest cause of a text message that never arrives is a number the platform accepted and the provider could not use.

Decide your convention, apply it consistently, and normalise on entry rather than hoping people type it the same way.

Store the country

Even if you only operate in one today. A number without a country code is ambiguous the moment you have a customer abroad, and retrofitting one across existing records means guessing.

Numbers are not numbers

Worth stating because it catches people: a phone number is not numeric data. It has leading zeros that matter, it is never arithmetic, and storing it in a number field destroys it. Use this type, or text if you must.

Extensions

Decide where they go. An extension appended to the main number breaks dialling and messaging; a separate field keeps both usable. If you take switchboard numbers, plan for it rather than letting people improvise.

Mobile or landline?

If you send SMS, you need to know which numbers can receive it. A single "phone" field containing a mix means every send is a guess, and the failures are silent from your side.

Either separate the fields or record the type, so a messaging campaign can select only what will work.

It is personal data

A mobile number identifies somebody and reaches them directly. Treat it accordingly for access and retention, and remember that consent to be contacted is a separate matter from holding the number.

Worked example

A contact datastore holds mobile and landline separately, both normalised to international format on entry, with the country stored. SMS campaigns select on the mobile field, so nothing is ever sent to a landline — which had been about one in six sends before the split.

Recommendations

  • Normalise on entry rather than accepting whatever is typed.
  • Store the country code from the start.
  • Separate mobile from landline if you send SMS.
  • Never store a phone number in a number field.

Credit/Debit Card

Captures card details for payment. The critical characteristic: the card number never reaches your application.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Commercial:

  • Carts — the commerce features that use payments

Architect Panel → Integration & Connections:

  • GoCardless Direct Debit — the direct debit alternative

How it works

The card details are entered into a form served by the payment provider, go directly to them, and what comes back to the platform is a reference. That reference can be used to take a payment; it is not a card number and cannot be turned into one.

Why this design and not another

Because handling card numbers directly brings the full weight of payment card compliance onto your application, your database, your backups and everybody with access to any of them. The scope of that is substantial and ongoing.

Tokenisation removes it. Your systems never see a card number, so there is no card number to protect, leak or account for. That is not a convenience — it is the difference between a manageable obligation and a serious one.

Never work around it

The rule that matters most here. Do not add a text field for a card number "temporarily", do not accept card details by e-mail into a notes field, and do not let anybody photograph a card into a file upload.

Each of those puts card data into your systems and undoes the entire arrangement — and it is usually done with good intentions by somebody solving an immediate problem.

What you can safely hold

The provider's reference, and typically enough to identify the card to its owner — the last few digits and the card type. That is what lets a customer recognise which card they used, and it is not sensitive in the way a full number is.

Use the provider’s form as given

Restyling a payment form to match your branding is a common request and needs care: anything that pulls card entry into your own page risks bringing card data with it. Where the provider offers supported customisation, use that rather than reimplementing.

Consider direct debit for recurring payments

For subscriptions and regular collection, direct debit is often a better fit than a stored card: no expiry to manage, lower fees, and a mandate that survives a card being replaced.

Cards expire and get reissued, which is a recurring cause of failed collections that direct debit does not have.

Test with the provider’s test cards

Never a real card. Providers supply numbers that exercise success, decline and error paths, and testing the decline path matters — it is what your customers will meet.

Worked example

A membership application takes joining payments by card, storing only the provider's reference and the last four digits so members recognise the card. Annual renewals moved to direct debit after a year in which reissued cards caused a run of failed collections in January.

Recommendations

  • Never let a card number into your systems by any route.
  • Store only the reference and enough to identify the card.
  • Prefer direct debit for recurring collection.
  • Test with the provider’s test cards, including declines.

Postal Address

A structured postal address, with address lookup rather than free typing.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Integration & Connections:

  • Postcode Lookup — distance and mapping, which use the postcode

Architect Panel → Activity:

  • Correspondence — letters sent to the address

It is structured, not one box

The address is held as its parts — lines, town, postcode, country — rather than as a block of text. That is what makes it usable rather than merely displayable.

A structured address can be validated, sorted on, grouped by town, mapped, and used for distance. An address in a text area can be printed and nothing else.

The postcode is the useful part

It drives more than delivery. Distance sorting on a browse view, the radius filter and the map all work from the postcode held here, and geographic reporting groups by it.

So an address field with a missing or malformed postcode is not just an incomplete address — it is a record that cannot be placed, sorted by distance or mapped.

Addresses picked from lookup carry their coordinates

When an address is chosen from the lookup, its coordinates come with it. That is worth knowing because it means those records need no separate geocoding — the location is already there, at no cost and with no cache entry.

Typed addresses do not have that, which is one more reason to encourage the lookup rather than free entry.

Encourage the lookup

Typed addresses are inconsistent — abbreviations, missing lines, misspelt towns, postcodes with the space in the wrong place. Lookup produces one canonical form.

Always allow manual entry as a fallback, though. New builds, unusual addresses and addresses abroad are not always found, and a form that refuses to proceed without a lookup match will block real people.

Do not assume a UK shape

If you will ever hold an address outside the UK, be careful about validation that assumes a postcode format, a county, or a particular line structure. Address formats vary enormously, and rigid validation is a common way to make a form unusable for somebody abroad.

One address per purpose

Billing, delivery and correspondence addresses are different things and will diverge. Model them as separate fields where they can differ rather than one address that somebody has to keep changing.

It is personal data

A home address is sensitive, and more so in some contexts than others — a refuge, a safeguarding case, a witness. Where that applies, field security and classification are the tools, and the address may warrant tighter handling than the rest of the record.

Worked example

A service holds separate correspondence and service addresses, both captured through lookup so coordinates come free. The browse view sorts by distance from a visitor's postcode without a single geocoding call, because every address was picked rather than typed.

Recommendations

  • Encourage lookup — it gives you consistency and coordinates.
  • Always allow manual fallback.
  • Separate addresses by purpose.
  • Do not hard-code a UK address shape.

Geolocation

Stores a geographic position — latitude, longitude and an accuracy figure — captured from the device or set on a map.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Integration & Connections:

  • Postcode Lookup — the distance and mapping this feeds

Architect Panel → Layout & Pages:

  • Browse Views — distance sorting and the map view

A point, not an address

The distinction that decides which field you want. An address is where somebody lives or receives post; a position is where something physically is.

Many things have a position and no address at all — a fault in a field, a bin, a lamppost, a tree, an incident on a footpath. For those, this is the right type and an address field is not.

It needs no lookup

Because it already holds coordinates, records using this field need no geocoding and no cache entry. Distance sorting, the radius filter and maps work directly from what is stored.

That makes it the cheapest and most precise option where you can capture it.

Accuracy is stored, and you should use it

The field records how accurate the reading was. A position captured indoors, in a city centre or with a poor signal can be tens or hundreds of metres out, and the accuracy figure is the system telling you so.

Ignoring it means treating a 300-metre estimate as if it were a precise location. Where the position matters, record it, display it, and let people judge — "within 5 metres" and "within 400 metres" are very different facts.

Capture at the point of observation

The reading is only meaningful if taken where the thing is. A position captured back at the office is the office, and a photograph plus a position taken at different times is worse than either alone.

Design the form so capture happens at the moment of recording, and consider warning if the reading is old.

It needs the browser’s permission

Location access is requested by the user's browser and can be refused permanently. Plan for that: a field that cannot be filled because permission was declined must not block a form, and an address or a manual map placement should be available as a fallback.

Position is personal data when it is about a person

Where a position is captured from a member of staff's device it is information about their movements, which is a considerably more sensitive thing than a location on an asset record.

If you are capturing positions from people, be explicit about it — in the interface and in your privacy information. This is an area where quiet collection causes real trouble.

Do not use it as a proxy for an address

Converting a position back into an address is imprecise and costs money. If you need a postal address, capture one.

Worked example

A street maintenance application records faults with a geolocation captured on site, plus a photograph and a description. Accuracy is displayed to the crew so they know how precisely to search. Fault records sort by distance for the nearest crew, with no geocoding involved because the coordinates were captured directly.

Recommendations

  • Use it for things without an address.
  • Record and show the accuracy figure.
  • Capture at the point of observation, not afterwards.
  • Be explicit when capturing positions from people.

Random Alphanumeric String

Generates a random string of letters and numbers.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • Record Numbering — the right tool for human-facing references

What it is for

Values that must be unguessable:

  • A token in a link sent to somebody, letting them reach one record without signing in.
  • A collection or verification code.
  • An external identifier you do not want to be enumerable.

Unguessable is the point

A sequential reference tells anybody who has one that neighbouring values exist. If the value is the only thing standing between a person and a record, that is a problem — somebody who receives /view/1042 will try 1041.

A random string removes that. There is nothing to guess and nothing to enumerate.

Not a reference number

The common misuse. For a human-facing reference — something quoted on the telephone, written on a form, read out to a customer — use record numbering instead.

Random strings are miserable to communicate. They are long, they contain characters people confuse, and they cannot be checked for plausibility. A customer reading one out will get it wrong, and neither of you will know which character.

Length is security

A short random string is guessable by trying. If the value protects access to anything, make it long — the cost of extra characters is nothing, and the difference between short and long is the difference between a control and the appearance of one.

A token is not a permission

Worth stating plainly. Anybody holding the value can use it. It travels in links, sits in mailboxes, appears in browser history and gets forwarded.

So pair it with the things that bound the damage: an expiry, single use where appropriate, and a scope limited to one record and one action. A token that never expires and grants broad access is a permanent credential distributed by e-mail.

Consider what it exposes

Anybody with the link sees whatever it opens. Make sure that is only what the recipient should see — a token intended to let somebody confirm an appointment should not open a record containing case notes.

Generated once

The value is created with the record and stays. If it leaks, the response is to invalidate and reissue rather than to hope — which means having a way to do that.

Worked example

An appointment system sends confirmation links containing a long random token, scoped to that one appointment and expiring after the appointment date. The appointment also carries a human reference from record numbering, which is what staff and customers quote on the telephone. The two do different jobs and neither substitutes for the other.

Recommendations

  • Use record numbering for anything humans communicate.
  • Make it long wherever it protects access.
  • Always add an expiry and the narrowest scope.
  • Have a way to invalidate and reissue.

AJAX Search (DB)

A type-ahead search that looks up records in another datastore as the user types.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Data:

  • Datastores — the datastore being searched

How it differs from a searchable dropdown

Both search another datastore and both store a link, and both are joinable — so the difference is in the interaction rather than the data.

A searchable dropdown presents a list you filter. This presents a search box that suggests as you type. For very large sets, or where the user is starting from something they know rather than choosing from options, the search feels more natural.

In practice either works for most cases. Pick one and use it consistently, because a form mixing the two for no visible reason looks arbitrary.

Search what the user knows

The same rule as any lookup, and it is the thing most often got wrong. Somebody looking for a company knows its name; searching only on a reference code fails them.

Cover the identifiers people actually hold, and prefer matching within a value rather than only from the start — users type the distinctive word, not the first one.

Show enough to choose correctly

Three results reading "J Smith" are not choosable. Include something that separates them — a town, a date of birth, an account number — so the user picks right first time rather than opening each in turn.

Handle the empty result

Somebody will search for something that is not there. Say so clearly, and give them a route — create it, or a note explaining why they cannot.

Without that, people put the value into a nearby free-text field and continue, which produces exactly the unlinked, duplicated data the field existed to prevent.

Filter to what is valid

Restrict to active records, or to records that make sense for the context. A search returning long-closed accounts will have one chosen eventually, and validation afterwards is a worse experience than not offering it.

Mind the responsiveness

The field searches as somebody types, so it runs frequently against a datastore that may be large. If results feel slow, the fix is usually indexing or narrowing what is searched rather than anything on the form.

It is still a relationship

Everything about database-backed dropdowns applies: do not delete a referenced record, use an active flag to retire options, and remember the source datastore has its own permissions — a user who cannot see a record will not find it here either, which is correct and occasionally confusing.

Worked example

A booking form uses AJAX search to find the customer, matching on name, account number and telephone, showing the town and account number in the results, filtered to active accounts. A "not found — create customer" option sits under the results, so nobody types a name into the notes instead.

Recommendations

  • Search on everything the user might know.
  • Show a distinguishing detail in results.
  • Give a route for "not found".
  • Be consistent — do not mix this and searchable dropdowns arbitrarily.

AJAX Search (URL)

A type-ahead search that queries an external service rather than a local datastore.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Integration & Connections:

  • API Clients — outbound connections generally
  • Data Sources — the alternative, for data you want held locally

What it stores

What the service returned, as text. Unlike the database-backed search, this does not join — there is no local record to join to, only a value that came from elsewhere.

That is the fundamental difference and it decides most of what follows.

When it fits

  • Reference data maintained by somebody authoritative — a registry, a directory, a standards list.
  • Lookups you have no wish to hold or maintain copies of.
  • Values that change at the source and should always be current.

What you inherit

A dependency on somebody else's availability and speed, on every keystroke. If the service is slow, your form is slow; if it is down, your form cannot complete.

That is a real operational consideration for a field people use daily, and it is worth deciding deliberately rather than discovering.

Fail visibly, not silently

The most important design point. When the service does not respond, the user must be told — "we cannot reach the lookup service" is actionable; an empty result list is not, because it looks identical to "no matches".

The second reading makes people conclude their search term is wrong and try again, repeatedly.

Allow a manual fallback

Where the field is on a form that must be completable, provide a way through when the lookup fails. A form that cannot be submitted because a third party is having a bad afternoon is your outage, not theirs, as far as your users are concerned.

Reporting is limited

Because the value does not join, you cannot group or report through it as you would a local link. If the value is central to your reporting, a data source that brings the records in locally is the better shape — and that is the main reason to prefer one over the other.

Watch what you send

The user's keystrokes go to the external service. If people search by name, you are sending names to a third party on every character.

Know what that service does with what it receives, and be careful with searches over anything sensitive — this is the kind of outbound flow that is easy to overlook when reviewing what leaves your systems.

Values can go stale

What you stored was current when it was chosen. If the source later changes or withdraws it, your record still holds the old value with nothing to tell you. That is acceptable for many uses and worth knowing for the rest.

Worked example

A registration form looks up company details from an external registry, storing the returned name and number. When the registry is unavailable the field says so and manual entry is offered, so registrations continue. Company records used for reporting are brought in through a data source instead, because those need joining.

Recommendations

  • Say when the lookup failed — never show an empty list.
  • Provide a manual fallback on any form that must complete.
  • Use a data source where you need to report on the value.
  • Know what you are sending on every keystroke.

AJAX Search (Active Directory)

A type-ahead search against Active Directory, for choosing a person from your organisation's directory.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Security:

  • Authentication Methods — directory-backed sign-in

Architect Panel → Integration & Connections:

  • Azure AD Tenants — directory connections

What it is for

Any field naming a member of staff — an owner, an approver, a reviewer, a contact — where your directory already holds the authoritative list.

The argument for it

  • No second staff list to maintain. The directory is already correct and already maintained by somebody whose job that is.
  • Leavers disappear from the picker without anybody remembering to remove them.
  • Consistent naming, rather than three spellings of the same person.

It does not join

Like the URL search, the value comes from outside and there is no local record behind it, so reporting through it is limited compared with a local link.

If you need to report heavily on people — workload by owner, cases by team — consider whether directory provisioning into local user records gives you a better shape, and use those.

Plan for the directory being unavailable

The field depends on it. If the directory cannot be reached, the picker returns nothing, and a form requiring it cannot be completed.

Say so when it happens rather than showing an empty list, and think about whether the form should still be submittable without it.

Search on what people type

Colleagues search by name — usually surname, sometimes first name, occasionally both in either order. Make sure the search handles that, and consider including something distinguishing in the results, because two people share a name in most organisations of any size.

Scope what is searchable

A directory contains more than current staff — service accounts, shared mailboxes, disabled accounts, contacts. Offering all of it makes the picker noisy and lets somebody choose a mailbox as an approver.

Restrict to what should legitimately be chosen.

The value can go stale

Somebody stored as an owner today may leave tomorrow. The stored value does not update, so a record can name somebody who no longer works there — which is correct as history and unhelpful as a current assignment.

Where the field drives work allocation, plan for reassignment when people leave rather than relying on the field to notice.

Directory data is personal data

Names, e-mail addresses and job titles are information about your staff. Ordinary in this context, and still subject to the same care about who can see it and how long it is kept.

Worked example

A change request datastore uses directory search for the approver, restricted to enabled staff accounts and showing the department beside each name. When the directory is briefly unavailable the field explains why rather than appearing empty. A monthly check reassigns open requests whose approver has left.

Recommendations

  • Restrict the search to accounts that should be choosable.
  • Show a distinguishing detail — names repeat.
  • Handle the directory being down explicitly.
  • Plan for leavers named on open records.

Active Directory Object

References an object in Active Directory that is not necessarily a person — a group, a computer, an organisational unit.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Security:

  • Authentication Methods — directory integration

Architect Panel → Integration & Connections:

  • Azure AD Tenants — directory connections

What it is for

  • Groups — recording which directory group governs something.
  • Computers and devices — asset records tied to directory objects.
  • Organisational units — where a record belongs in the directory structure.

Use the person search for people

This field is deliberately broader. If you are naming a member of staff, the directory person search is the better fit — narrower results, better suited display, and clearer intent to whoever reads the field definition later.

It does not join

As with the other directory field, the object lives outside the platform, so reporting through it is limited. Grouping records by directory group means working with stored values rather than joining to records.

Directory structure changes

Groups are renamed, computers are decommissioned, organisational units are restructured — and none of that reaches your stored value. A record can reference an object that no longer exists or has been renamed, and nothing will tell you.

Where the reference matters operationally, something should periodically confirm the objects still exist. That is not automatic.

Referencing a group is not using it

An important distinction. Storing a directory group in a field records which group is relevant; it does not grant access to that group's members.

Access is governed by the platform's own permissions and, where you have configured it, by directory group mapping into security groups. A field is a note, not a control — and treating it as one produces an application that appears to enforce something it does not.

Restrict what is searchable

A directory contains a great deal, much of it meaningless to your users. Scope the search to the object types and the parts of the tree that are relevant, or the picker becomes unusable.

Consider a local record instead

If you are building an asset register, the directory object is one attribute of an asset rather than the asset itself. Model the asset locally, with its own fields, history and permissions, and reference the directory object from it.

Trying to use the directory as your asset datastore leads to a system that cannot record anything the directory does not already hold.

Worked example

An IT asset datastore holds each machine as a local record with its own purchase date, location and owner, and references the directory computer object as one field. Reporting works from the local records; the directory reference is there for administrators who need it, and a quarterly check flags references to objects that have been removed.

Recommendations

  • Use the person search for people.
  • Model your own records and reference the object from them.
  • Never treat a stored group as a permission.
  • Check periodically that referenced objects still exist.

User Search

A search that picks a user of the platform itself.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Security:

  • Permissions — the groups a chosen user belongs to

Architect Panel → Data:

  • Datastores — the record the user is being attached to

What it is for

Any field naming somebody who uses the system: an owner, an assignee, a reviewer, an author, a manager.

Why not a text box

Because a typed name is not a person. It cannot be matched reliably, it appears in three spellings, it does not change when somebody's name changes, and no report can group by it with confidence.

A user search stores a reference to the actual account, which is what makes "cases by owner" a query rather than an approximation.

It joins, so it reports well

Single-select and joinable — so ownership and assignment reporting works properly, and the chosen user's other attributes are reachable from the record.

Platform users, not directory objects

This searches accounts in the platform. Where your users come from a directory and are provisioned in, those accounts are here and this is the right field.

The directory search is for naming somebody who may not be a platform user at all. If the person needs to use the record, this is the one you want.

Assignment implies access

The thing most often missed. Naming somebody as owner does not give them permission to see the record.

If ownership should confer access, that is a record access role — the two work together, and the field alone changes nothing about what they can reach. An application that assigns work without granting access produces people who have been given something they cannot open.

Restrict who can be chosen

Not every account should be assignable. Filtering to a relevant group — the team who handle this kind of work — keeps the list short and prevents work being assigned to somebody who cannot do it.

Leavers

A disabled account can still be named on historical records, which is correct — the history should say who owned it. What needs attention is open work: records still assigned to somebody who has left need reassigning, and nothing does that automatically.

Make it part of your leaver process, and check for it periodically.

Show enough to choose

Names repeat. Including a department or a role in the results avoids the wrong Sarah being assigned, which is otherwise found out days later.

Worked example

A case datastore uses a user search for the owner, filtered to the caseworker group and showing each person's team. Ownership grants access through a record access role, so assigning a case gives the owner the ability to open it. The leaver checklist includes reassigning open cases.

Recommendations

  • Never store a person as typed text.
  • Pair assignment with a record access role if ownership should grant access.
  • Filter to the relevant group.
  • Reassign open work when somebody leaves.

Conditional Form

A set of fields that appears only when a condition is met, so a form asks what applies and nothing else.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it is for

Questions that are relevant to some records and not others. "Do you have a vehicle?" followed by six questions about the vehicle, shown only to the people who said yes.

The alternative — showing everything and asking people to skip what does not apply — makes forms longer, slower and more error-prone.

Shorter forms get finished

Length is the main reason forms are abandoned, and most of the length in a long form is questions that do not apply to the person filling it in. Conditional sections attack that directly.

The gain is real on public-facing forms, where somebody who stops is simply gone.

Hidden is not the same as unanswered

Worth thinking about carefully. If somebody answers a conditional section and then changes the triggering answer, the section disappears — and what happens to what they entered is a decision you should make deliberately rather than discover.

Stale answers to a question no longer asked are confusing at best and misleading at worst, particularly if they appear on a report.

Keep conditions simple

One clear trigger, ideally a single field. Conditions depending on three fields in combination are hard to reason about, hard to test, and produce forms where somebody cannot work out why a section will not appear.

If you find yourself drawing a diagram to explain the logic, the form design is the problem rather than the condition.

Do not hide things people need to see

A conditional section is for irrelevant questions, not for inconvenient ones. Hiding a warning, a cost or a consequence until somebody has committed is a dark pattern, and it produces complaints rather than completions.

Test every branch

Each condition doubles the paths through the form. Walk every one — including changing an answer back — because that is where the surprises are, and it is not somewhere ordinary use will take you.

Consider the printed version

Conditional sections make sense on screen. A printed or exported version showing empty sections, or omitting them entirely with no indication, can be confusing. Check what a completed record looks like outside the form.

Worked example

A grant application asks whether the applicant is a registered charity and, if so, shows four further questions. Roughly a third of applicants see them. Abandonment fell noticeably after the change, and every branch — including switching the answer back and forth — was walked through before release.

Recommendations

  • One simple trigger per condition.
  • Decide what happens to answers when a section is hidden again.
  • Never hide something unwelcome — only something irrelevant.
  • Test every branch, including reversing an answer.

Dynamic Conditional Form

A conditional form whose content or conditions are determined as the form is used rather than fixed when it was designed.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

How it differs

An ordinary conditional form has sections defined in advance, shown or hidden by a condition. This one can determine what to show at the time — driven by data, by earlier answers, or by something looked up while the form is open.

When the extra capability is warranted

  • The questions depend on data that changes — a product's options, a scheme's current rules.
  • The set of sections is genuinely open-ended rather than a fixed list.
  • Maintaining every variation as a separate static section would be unmanageable.

And when it is not

If the variations are known and stable, use the static conditional form. It is easier to reason about, easier to test, and visible in the field configuration rather than determined at runtime.

Dynamic behaviour is harder to support: when somebody reports that a section did not appear, you are reconstructing what the data looked like at that moment rather than reading a rule.

Test with real variety

Because the form differs by situation, testing one path proves very little. Work through a genuine spread of cases, including the awkward ones — the record with nothing configured, the one with far more options than expected.

Think about what happens when the source changes

If the sections depend on data, that data will change. A form completed last year may have asked questions that no longer exist, and a record may hold answers to questions the form would not ask today.

That is not wrong — it is history — but reports comparing across time need to expect it, and somebody reading an old record needs to understand why it looks different.

Keep it explicable

Somebody will eventually ask why a particular person saw a particular set of questions. Make sure that is answerable — from configuration, from data, or from something recorded at the time.

A form whose behaviour cannot be explained after the fact is a problem in any regulated context, and uncomfortable in every other.

Performance matters more here

Working out what to show takes effort, and it happens while somebody waits. If the form feels slow, that is a user-facing problem — check what the dynamic logic is doing rather than accepting it.

Worked example

An application form shows sections based on which funding scheme was selected, with schemes and their questions held as data so the team can add one without a change request. When a scheme's questions are revised, older applications still show what was asked at the time — a behaviour deliberately chosen and written down, so nobody reads it as a fault.

Recommendations

  • Use the static version where the variations are known.
  • Test a real spread of cases, not one path.
  • Make the behaviour explicable after the fact.
  • Expect historical records to differ, and say so.

Dynamic Add/Remove

Lets a user add and remove repeated rows within a single record — several of something, without knowing how many in advance.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it stores

All the rows together, as text on the parent record. It does not join, and the rows are not records.

Should this be a datastore instead?

The question to ask before choosing a repeating field, and the one people wish they had asked. Repeating rows inside a field are convenient and they are not records — they cannot be reported on individually, cannot be searched as records, cannot carry their own permissions, and cannot be linked to from anywhere else.

The test: will anybody ever ask a question about the rows rather than about the parent? "How many lines mention this product", "which of these are outstanding", "show me every one across all records" — if any of those will be asked, the rows want to be a datastore of their own with a link back to the parent.

Converting later means migrating data out of a field and into records, which is real work. Deciding early costs nothing.

When the field is the right answer

  • A short list belonging entirely to the parent — other names somebody is known by, a few phone numbers, previous addresses.
  • Rows nobody will report on individually.
  • Data that only ever makes sense in the context of the parent record.

When a datastore is

  • Rows with their own lifecycle — a status, an owner, dates that change.
  • Anything you will count, total or filter across records.
  • Rows that other records should link to.
  • Rows needing their own permissions — one row visible to more people than another.

Keep the row count small

The field is designed for a handful. Somebody adding forty rows produces a form that is slow to load, awkward to edit and unpleasant to read — and that is a strong signal it should have been a datastore.

Consider setting a maximum, both to keep the form usable and to surface the modelling question before it becomes a migration.

Validate each row

Row-level validation matters more here than on ordinary fields, because bad data is buried inside a field rather than sitting in a record where it is visible. A malformed row can go unnoticed for a long time.

Editing is all-or-nothing

Rows are part of the parent, so changing one is changing the parent record. The audit trail records the whole field before and after rather than "row three changed", which is worth knowing when trying to work out what somebody did.

Ordering

Decide whether the order means anything. If it does, make sure it is preserved and that users can reorder; if it does not, do not let people assume it does.

Worked example

A person record uses this field for previous names — usually none, occasionally two or three, never reported on separately. Their employment history is a datastore instead, because each role has dates, an employer link and a verification status, and the team reports on employers across everybody.

Recommendations

  • Ask the datastore question first, before anything else.
  • Keep it to a handful of rows, and cap it.
  • Validate each row — bad data hides here.
  • Use a datastore the moment rows need a lifecycle.

Line Item Builder

Builds a set of structured lines with calculations across them — the shape of a quotation, an order or an invoice.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → ERP - Setup:

  • Documents — transactional documents, which may suit better

What it is for

Repeating lines where each has the same columns and the set has a total. Description, quantity, unit price, line total — and a sum at the bottom.

It differs from the plain repeating field by understanding that lines have columns and that columns can be calculated.

What it stores

The lines together as text on the parent record. Like the other repeating types it does not join, so individual lines are not records.

Should this be a datastore instead?

The question to ask before choosing a repeating field, and the one people wish they had asked. Repeating rows inside a field are convenient and they are not records — they cannot be reported on individually, cannot be searched as records, cannot carry their own permissions, and cannot be linked to from anywhere else.

The test: will anybody ever ask a question about the rows rather than about the parent? "How many lines mention this product", "which of these are outstanding", "show me every one across all records" — if any of those will be asked, the rows want to be a datastore of their own with a link back to the parent.

Converting later means migrating data out of a field and into records, which is real work. Deciding early costs nothing.

For line items specifically, that question is usually "will anybody ask what we sold most of?" — and if the answer is yes, lines want to be records.

Consider transactional documents instead

The platform has a document layer built exactly for quotations, orders and invoices — with numbering, conversion between document types, ledger posting, tax handling and multi-currency.

If you are building anything commercial, start there rather than assembling it from a line item field. This field is right for a lightweight case: a simple list with a total on a form that is not part of a trading process.

Get the calculations right at the edges

Rounding is where line-based calculations go wrong. Rounding each line before summing gives a different total from summing and rounding once, and both are defensible — but they must agree with whatever else in your business calculates the same figure.

Decide, write it down, and check the total against a hand calculation before anybody relies on it.

Prices change

If a line captures a price, decide whether it is a snapshot or a live lookup. A quotation must keep the price quoted; a live lookup means an old quotation silently revalues, which is a genuine commercial problem.

Snapshot is nearly always what you want, for the same reason time entries store their rate and stock issues store their cost.

Keep the columns few

Lines are entered horizontally and columns compete for width. Beyond five or six the layout suffers, particularly on a smaller screen, and entry becomes fiddly.

Validate per line

A zero quantity, a negative price, a missing description. Catching these at entry is far better than a total that is wrong for a reason nobody can see.

Worked example

An internal requisition form uses a line item builder for a handful of items with a total — no numbering, no ledger, no conversion, so the field is a good fit. The organisation's customer quotations use transactional documents instead, because those convert to orders, post to the ledger and need per-line reporting.

Recommendations

  • Use transactional documents for anything commercial.
  • Snapshot prices, do not look them up live.
  • Settle the rounding rule and verify the total by hand.
  • Five or six columns at most.

SQL Query

Displays the result of a query on the form, rather than holding a value of its own.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → ERP - Trading & Analytics:

  • Analytics — the proper home for reporting

It shows, it does not store

The distinguishing characteristic. There is no value on the record — the field runs a query and displays what comes back, fresh each time the form is opened.

So it does not join, cannot be reported on, and holds nothing historical.

Where it genuinely helps

  • Context while working. Showing a customer's recent orders on their record saves navigating away.
  • Live summaries — outstanding balance, open items, a count that must be current.
  • Related information from elsewhere, presented where somebody needs it.

The misuse to avoid

Using it as a reporting tool. It is tempting because it is flexible, and it is the wrong place: queries embedded in field definitions are invisible to anybody looking at your reports, unmaintained, and impossible to audit as a set.

Analytics exists for reporting, with measures and dimensions defined once and shared. A number that matters belongs there, not scattered across form fields.

It runs every time the form opens

The performance consideration, and it is easy to miss because it does not show up in testing with small data. A heavy query on a frequently-opened record is a slow form for everybody, all the time.

Keep queries tight, ensure what they touch is indexed, and think about how the record will feel in three years with far more data behind it.

Permissions need thinking about

The most important caution. A query can reach data the person viewing the form might not otherwise be allowed to see.

Do not assume the platform's permission layers cover what a hand-written query returns. Check what the field displays for a user with restricted access — as that user, not as an administrator — before it goes anywhere near production.

It is a maintenance liability

A query embedded in a field breaks when the underlying model changes, and it breaks at the point somebody opens a form rather than when the change was made. Whoever renames a field will not think to look here.

Keep a note of where these exist, so a model change can check them.

Prefer a proper relationship

Much of what people use this for — showing related records — is better done with an actual relationship between datastores, which is visible, permission-aware and reportable.

Worked example

A customer record shows the five most recent orders and the outstanding balance through a query field, checked as a restricted user to confirm it reveals nothing they should not see. Sales reporting is built in Analytics, not from query fields, so the figures are defined once and everybody's numbers agree.

Recommendations

  • Use it for context, never for reporting.
  • Check what it shows a restricted user.
  • Keep queries tight — they run on every open.
  • Prefer a real relationship where one would do.

Custom (HTML/JS)

Renders markup and scripting you provide, inside the form.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Layout & Pages:

  • App Code — extensions, which are usually the better home

The escape hatch

Everything else on a form is described as configuration and rendered by the platform. This is where you step outside that, which makes it powerful and makes it the thing to justify rather than reach for.

Where it is warranted

  • A visualisation or control no field type provides.
  • Presenting information in a shape the form cannot express.
  • An interaction genuinely specific to one screen.

What you take on

Custom markup is not maintained by the platform. It does not automatically follow theme changes, does not inherit responsive behaviour, and is not covered by accessibility work done elsewhere.

Every upgrade is a thing to check, and the person who wrote it will not always be there. That is the real cost, and it is paid over years rather than at the point of building.

It is invisible to everything else

Anything this field does is opaque to reporting, to the audit trail and to permissions. A value it manipulates is not a field; a decision it makes is not recorded.

If information matters, it belongs in a real field. Use this to present, not to hold.

Permissions do not apply to it

The most important caution. Field security governs the platform's own fields; it does not govern what your markup chooses to display.

If custom code fetches or renders something, that is your responsibility to gate. It is entirely possible to build a field that shows a restricted user something the rest of the form correctly hides — and it will not look like a permissions failure.

Consider an extension instead

The platform has a proper place for custom code, with version control, review and a defined interface. A field is convenient for something small and self-contained; an extension is the right home for anything that will live, grow or be reused.

Ask which you are building. "Small and self-contained" has a way of becoming neither.

Test where it will actually be used

Different browsers, a phone, a printed record, an export. Custom markup is the most likely thing on a form to behave differently across those, precisely because the platform is not managing it.

Write it for the next person

Comment it, and note somewhere that the field exists. A form containing custom code nobody knows about is a surprise waiting for whoever next touches that screen.

Worked example

A form shows a small custom visualisation of a record's progress, drawing on values held in ordinary fields. The values themselves are real fields, so reporting works and the audit trail is complete; the custom field only draws them. It is documented in the datastore's notes and checked at each upgrade.

Recommendations

  • Present, do not hold — keep data in real fields.
  • Gate what you render yourself; field security will not.
  • Prefer an extension for anything that will grow.
  • Record that it exists for whoever comes next.

Custom PHP Code

Runs server-side code you provide as part of the field.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Layout & Pages:

  • App Code — extensions, the maintained way to add server-side logic

Architect Panel → Security:

  • Permissions — who can create or edit code fields

Treat this as the serious one

Server-side code runs with the platform's own access, not the user's. It is not constrained by field security, row-level access or classification unless you constrain it yourself.

Everything below follows from that.

Who may create one

Creating or editing a code field is equivalent to deploying code. It should be restricted to the people who would be allowed to deploy, and it should not be something an administrator can do because they happen to have edit access to a datastore.

This is worth checking rather than assuming — it is exactly the permission that gets granted broadly for convenience.

Enforce permissions yourself

The platform's layers protect the platform's own operations. Code you write reaches data directly, so if it returns something the viewing user should not see, that is a disclosure the surrounding permissions will not prevent.

Check, in the code, that the person is entitled to what it produces.

It runs where users wait

Code in a field executes as part of loading or saving. Something slow, or something calling an external service, makes the form slow — and an external call that hangs makes it hang.

Anything substantial belongs in a background task, not in a field.

Handle its own failures

An unhandled error here does not fail quietly — it can take the form with it. Assume every external call fails, every value can be missing and every input can be malformed, and make sure the field degrades rather than breaking the screen.

Prefer an extension

The platform has a proper home for server-side logic, with version control, review, testing and a defined interface. Code in a field has none of that: it is edited in a form, invisible to your repository, and reviewed by nobody.

Use a field only for something genuinely small and specific to that screen. Anything else is an extension.

Keep an inventory

Code fields are easy to lose track of. Nobody greps a database, and a field written three years ago runs on every form load with nobody aware of it.

Keep a list of where they are, so a security review or an upgrade can find them.

Never put credentials in one

They belong in the platform's own credential storage, where they are encrypted and rotatable. A secret in a code field is a secret in the audit trail, in backups, and visible to anybody who can view the field.

Worked example

A field calculates a risk score from values on the record — small, self-contained, no external calls, no credentials, and it checks the user's access before returning a figure. Everything more substantial in the same application is an extension, held in version control and reviewed. Both code fields in the system are listed in the technical documentation.

Recommendations

  • Restrict creation as you would deployment.
  • Check permissions in your own code.
  • Use an extension for anything beyond trivial.
  • Keep an inventory — nobody will find these otherwise.

Audit Link

Surfaces audit information about the record directly on the form.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

Architect Panel → Activity:

  • Activity Log — the full change history
  • Audit Chain — the tamper evidence over it

What it is for

Putting "what has happened to this record" in front of the person looking at it, without sending them to the Activity Log and asking them to filter.

For records where history matters routinely — a case, a claim, an asset — that saves a step people otherwise skip.

It surfaces; it does not store

The audit trail is the source. This field is a view onto it, so nothing here is a second copy that could disagree.

Who should see it

The consideration that matters. Audit history includes before-and-after values, so it can show somebody a value that has since been changed — including one they might not be allowed to see now.

Think about that before adding the field to a form used by people with narrower access than the record's editors. History is disclosure.

Do not replace the Activity Log with it

The field is convenience on one record. Investigations spanning records, people or time still belong in the Activity Log, which can filter and search across everything.

Somebody trying to answer "what did this account do last Tuesday" from a field on one record is using the wrong tool.

Keep it out of the way

History is reference material, not something people act on every time. Put it at the end of the form or behind a tab — above the fields somebody came to edit, it is noise on every visit.

It is not the business timeline

Worth separating clearly, because the two get confused. The audit trail is a technical record of changes; the activity stream is the business history written for the people working on the record.

A customer asking what is happening is answered from the timeline. "Why does this field say that" is answered from audit. Do not use one for the other's job.

Volume on busy records

A record edited hundreds of times has hundreds of entries. On such records the field becomes long and less useful — worth limiting what is shown to something readable and pointing at the full log for the rest.

Worked example

A complaint record shows an audit link at the foot of the form so a handler can see who changed the outcome and when, without leaving the record. It is not shown on the customer-facing view of the same complaint, because the history contains internal values. The customer sees the activity stream instead.

Recommendations

  • Think about who sees history — it is disclosure.
  • Place it out of the working area.
  • Use the Activity Log for anything spanning records.
  • Keep it off external-facing views unless you have checked its contents.

Hidden and Special Hidden

Two types that hold a value on a record without displaying it on the form.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

They are not the same underneath

Worth knowing before choosing, because the difference is invisible on a form:

  • Hidden stores a whole number and joins, so it can be reported through like any other reference.
  • Special Hidden stores a much larger text value and does not join.

So a hidden reference you will report on wants the first; a larger stored payload wants the second.

What they are for

  • A value set by the system rather than by the user — a source marker, a token, an internal reference.
  • Something carried through a process without a person needing to see or change it.
  • Context captured at creation — which form, which campaign, which route.

Hidden is not protected

The single most important point. Hidden means "not shown on this form". It does not mean the value cannot be seen, and it does not mean it cannot be changed.

The value is on the record. It appears in exports and in the API, it is visible to anything with access to the datastore, and it is in the audit trail.

If a value needs protecting, that is field security, which is enforced on the server — no-access fields are removed from the data before it is sent, and protected fields are stripped from every write. Hiding is presentation; field security is a control.

Never put a secret in one

It follows directly. A credential, a token or anything sensitive placed in a hidden field is not hidden from anybody who matters — it is merely absent from one screen.

Do not use it to smuggle data past validation

A tempting pattern: hide a field so its rules do not inconvenience anybody. It works and it produces records that pass validation while holding values nobody checked, which surfaces later as data nobody can explain.

Document what fills them

Hidden fields are invisible by definition, so nobody discovers what sets them by looking at a form. A hidden field with no note is a value somebody will eventually have to reverse-engineer.

Record what populates it and what it is for, in the datastore's own documentation.

Review them occasionally

They accumulate. A field added for a campaign three years ago is still being populated by something, and still appearing in every export. Because nobody sees them, nobody prunes them.

Worked example

A public form sets a hidden field recording which page the visitor arrived from, used for reporting on campaign effectiveness. It is documented in the datastore notes. The API token the form uses is not in a hidden field — it is not on the record at all, because a hidden field would have exposed it to every export.

Recommendations

  • Never treat hidden as protected — use field security.
  • Choose Hidden for references you will report on.
  • Document what populates each one.
  • Review them periodically — nobody sees them decay.

Dummy Field

A field that stores no data. It exists to structure or annotate the form.

Where to find it

Architect Panel → Data:

  • Datastores — the datastore, then Table Designer to add or edit a field

What it is for

  • Section headings, breaking a long form into readable parts.
  • Instructions — explaining what a section wants, where it will actually be read.
  • Spacing and separation between groups of fields.
  • Warnings at the point they are relevant.

Structure makes long forms usable

An unbroken run of thirty fields is exhausting to complete and easy to lose your place in. The same thirty divided into four labelled groups is a different experience, and the difference shows in completion rates and in error rates.

It is one of the cheapest improvements available on a form.

Put guidance where it is needed

Instructions in a separate document are not read. Instructions immediately above the section they concern are. Where a question is regularly misunderstood, a sentence in the right place removes the misunderstanding permanently.

It still occupies the definition

Although it holds nothing, it is a field on the datastore — it appears in the field list and adds to what somebody maintaining the model reads through.

That is a small cost and worth spending deliberately. A form with fifteen dummy fields is harder to maintain than one with four well-placed ones, and the visual benefit does not scale.

Do not use it for content that belongs elsewhere

A dummy field is not a place for policy text, long explanations or anything that changes. Content maintained here is content maintained by an architect editing a field definition.

Where guidance is substantial or changes regularly, link to it rather than embedding it.

Keep the text short

People skim forms. A paragraph above a section will be skipped; a single clear sentence will be read. If you need more than a couple of lines, the form itself probably needs simplifying.

Mind the other renderings

A record printed, exported or shown through the API will not include these — they are form furniture, not data. Do not put anything in one that somebody needs when reading the record elsewhere.

Anything that must travel with the record is a real field.

Check it on a phone

Headings and spacing that look right on a wide screen can look odd on a narrow one. Since the whole point is presentation, it is worth confirming the presentation actually works where the form is used.

Worked example

A twenty-eight-field application form is divided into four labelled sections with a dummy field heading each, plus one short instruction above the section people most often filled in wrongly. Completion improved and queries about that section stopped. No other guidance was embedded — the scheme rules are linked, because they change each year.

Recommendations

  • Break long forms into labelled sections.
  • Put guidance where the question is, not in a separate document.
  • Keep the text to a sentence.
  • Link to anything that changes rather than embedding it.