Cardbox.Type (Cardbox v0.1.0)

Copy Markdown View Source

The types of fields: what each takes, how it keeps a value, and how it filters.

TypeA valueOptions
texta textlong: a text of several lines
numberan integer or a numberformat: number, integer, percent or currency; decimals; currency ("EUR")
checkboxtrue or false
datea day, or a moment with timetime: a day and a time, kept in UTC
selectone of the choiceschoices (Cardbox.Choice)
multi_selectsome of the choiceschoices
statusone of the choices, each of a group (to do, doing, done)choices
personthe id of a person or an agent of your appmultiple: several
url, email, phonea text of that form
relationrecords of a collectioncollection_id (required); limit: at most so many; two_way: the other collection shows the links too, in a field named reverse_name (its own name unless given)
created_at, updated_atwhen the record was made, changedread-only
created_by, updated_bywho made it, changed it lastread-only

How values are kept

A record's values are one JSON map, by field key (Cardbox.Record). An empty value is no key at all: a text of no characters, an empty list and an unticked checkbox are kept as nothing, so "is empty" is one question whatever the type. A day is "2026-10-25", a moment "2026-10-25T14:30:00Z", both of which sort as text; a choice is its id; a relation a list of record ids.

The four read-only types are the record's own columns, and are not in its values.

Values given

cast/3 takes what a form posts, what an agent sends and what Elixir code has: "12.5" and 12.5 for a number, "2026-10-25" and a Date for a date, a choice's id or its name for a select. Each value is checked against its field, and an error says what the field takes.

Summary

Types

How a type's values compare, in Elixir and in SQL.

Functions

Checks a value given for a field, and returns it as it is kept: nil for an empty value.

Checks a type's options, with previous, the field's options before (so a choice renamed keeps its id). Returns them as they are kept.

How a field's values compare: :text, :number, :boolean, :date (a day), :datetime, :choice (one id) or :list (several).

A value as it is kept, read for Elixir: a Date or a DateTime for a date, false for an unticked checkbox, [] for an empty list.

The types, by name.

The filter operators of a field (Cardbox.Filter).

Whether a field sorts: every field but those of several values.

Whether a type is one of the record's own columns, which nobody writes.

Types

kind()

@type kind() :: :text | :number | :boolean | :date | :datetime | :choice | :list

How a type's values compare, in Elixir and in SQL.

Functions

cast(field, value, opts \\ [])

@spec cast(map(), term(), keyword()) :: {:ok, term()} | {:error, String.t()}

Checks a value given for a field, and returns it as it is kept: nil for an empty value.

opts: :time_zone, where a day and a time given without an offset are (UTC unless given).

check_options(type, options, previous \\ %{})

@spec check_options(String.t(), map(), map()) :: {:ok, map()} | {:error, String.t()}

Checks a type's options, with previous, the field's options before (so a choice renamed keeps its id). Returns them as they are kept.

kind(map)

@spec kind(map()) :: kind()

How a field's values compare: :text, :number, :boolean, :date (a day), :datetime, :choice (one id) or :list (several).

load(field, value)

@spec load(map(), term()) :: term()

A value as it is kept, read for Elixir: a Date or a DateTime for a date, false for an unticked checkbox, [] for an empty list.

names()

@spec names() :: [String.t()]

The types, by name.

operators(field)

@spec operators(map()) :: [atom()]

The filter operators of a field (Cardbox.Filter).

sortable?(field)

@spec sortable?(map()) :: boolean()

Whether a field sorts: every field but those of several values.

system?(type)

@spec system?(String.t()) :: boolean()

Whether a type is one of the record's own columns, which nobody writes.