A type of field of your app's own: what its values are, how they are checked, how they compare and how they read.
defmodule MyApp.Cardbox.Rating do
@behaviour Cardbox.FieldType
@impl true
def name, do: "rating"
@impl true
def kind(_options), do: :number
@impl true
def cast(value, _field, _opts) when value in 1..5, do: {:ok, value}
def cast(value, _field, _opts), do: {:error, "is from 1 to 5, got: #{inspect(value)}"}
endand in your config, beside Cardbox's own types:
config :cardbox, types: [MyApp.Cardbox.Rating]The types are your app's config, not your Cardbox module's: a value is
read in many places that know only its field (a filter, a table's
column, a board's card, the JSON Schema an agent reads), as Kotoba's
nodes are. A type's name is never one of Cardbox's (Cardbox.Type).
What a type says
Only name/0 and cast/3 are required; the others have defaults.
kind/1: how values compare, for filters and sorts (Cardbox.Type.kind/1)::textby default. A:listdoes not sort or group.check_options/3: the field's options, checked when the field is added or changed, with the collection, so that an option may name another field. By default a type takes no options.cast/3: a value given, checked, as it is kept (JSON):{:ok, nil}for an empty one.load/2: a value kept, read for Elixir (Cardbox.get/3). As it is by default.plain/2: a value as plain words or numbers: what a table sorts and shows, whatCardbox.Record.to_map/2gives, and what a field that changes type converts. As it is by default.text/2: a value in words for a person, in a table's cell and on a board's card.plain/2's, as text, by default.operators/1: the filter operators, those of its kind by default.json_schema/1: the JSON Schema of a value, for agents. A string by default.words/2: the words of a value in the record's search text. None by default.
Summary
Callbacks
@callback cast(value :: term(), Cardbox.Field.t(), opts :: keyword()) :: {:ok, term()} | {:error, String.t()}
@callback check_options(options :: map(), previous :: map(), Cardbox.Collection.t()) :: {:ok, map()} | {:error, String.t()}
@callback json_schema(Cardbox.Field.t()) :: map()
@callback kind(options :: map()) :: Cardbox.Type.kind()
@callback load(value :: term(), Cardbox.Field.t()) :: term()
@callback name() :: String.t()
@callback operators(Cardbox.Field.t()) :: [atom()]
@callback plain(value :: term(), Cardbox.Field.t()) :: term()
@callback text(value :: term(), Cardbox.Field.t()) :: String.t() | nil
@callback words(value :: term(), Cardbox.Field.t()) :: [String.t()]