Prerequisites
Before diving in here, one should have at least a basic understanding of JSON schema. Carium uses JSON schema, with some
additional custom properties, to define the data being presented/requested in a Form.
A fantastic place to start is with the aptly named article/book: Understanding JSON Schema. It's
particularly important to have a decent understanding of the object
type. The top-level definition for
a Form is a JSON schema definition of an object
, with each entry in properties
representing a
Field in the Form.
At both the Form level, as well as individual Fields, any attributes that aren't standard JSON schema
are nested under the x-form
key.
The top-level definition for a Form is a JSON schema object
, with additional attributes nested underneath the x-form
attribute. All the JSON schema attributes are required. The only required additional attribute is order
.
Standard attributes
Attribute | Required | Type | Description |
---|
properties | x | object | A key-value pair of string names to Field definitions. |
required | x | string[] | An array of field names (keys in properties ) that are required. |
type | x | string | Must be the literal string "object" |
Custom attributes
Attribute | Required | Type | Description |
---|
labels | | object | A key-value pair of string names to Label definitions. |
layout | | object | The Layout defining how the Form should be laid out. |
limits | | object[] | An array of Limit definitions used to validate the Form |
order | x | string[] | An ordered array of Field or Label names (keys in properties or x-form.labels ). |
sections | | object[] | An ordered array of Section definitions. |
Simple example
{
"properties": {
"first": { "title": "First name", "type": "string" },
"last": { "title": "Last name", "type": "string" }
},
"required": ["first", "last"],
"type": "object",
"x-form": {
"order": ["last", "first"]
}
}
Field
Some attributes are available for every Field, while others are specific to certain Field Types. Some of
the attributes are official JSON schema, while others are custom to Carium. The custom attributes are nested under the
x-form
key in the Field definition.
Standard attributes
Attribute | Required | Type | Description |
---|
default | | string | The default value for the Field that will be filled in when the Form is first rendered. |
enum | | string[] | An array of valid values for this Field. Anything that's not one of those values will be considered invalid. |
format | | enum[string] | One of (date , datetime , uuid ). Special case formats for the Field. |
maxLength | | number | The maximum length of the entered string value. |
minLength | | number | The minimum length of the entered string value. |
title | x | string | User-visible display label for this Field |
Custom attributes
Attribute | Required | Type | Description |
---|
condition | | object | A Field Condition definition. |
hideOptionalLabel | | boolean | Unless true , optional Fields have (Optional) appended to their labels. |
multiline | | boolean | Determines if the Field input supports newlines being entered by the user. |
layout | | FieldLayout | Determines how this Field is laid out within the layout of the containing Form or Section |
readOnly | | boolean | When true , this Field won't allow the user to change its value. |
Field Layout
Attribute | Required | Type | Description |
---|
data | x | object | The type-specific data for this FieldLayout |
type | x | string | The type of FieldLayout being specified, currently, the only option is "grid" |
Field Grid Layout
Attribute | Required | Type | Description |
---|
alignSelf | | string | How to align this cell within the grid (align-self ) |
col | | number | The amount of space rendered between rows in the grid ([grid-row-gap][grid-col-row-gap]). |
colSpan | | number | How to break up consecutive elements into columns ([grid-template-columns ][grid-template-cols-rows]). |
horizontal | | boolean | Only used for Fields of type Checklist, render options horizontally when true . |
justifySelf | | string | How to justify this cell within the grid (justify-self ) |
row | | number | The amount of space rendered between rows in the grid ([grid-row-gap][grid-col-row-gap]). |
rowSpan | | number | How to break up consecutive elements into columns ([grid-template-columns ][grid-template-cols-rows]). |
Example
{
"data": {
"colSpan": 3
},
"type": "grid"
}
Field Condition
Conditions allow a Field to only be displayed to the user if certain criteria are met. These criteria are
based on the values of other Fields in the Form. Whenever the FieldCondition is
met, that Field will be displayed and considered required. If the FieldCondition isn't
met, that Field won't be displayed and won't be required.
Field types
Forms support a wide variety of Field types, which map to different UI components that will be displayed and different
experience for the user. While each Field's value will be stored as a string, the UI components can limit the user's
input to match an integer
, number
, or boolean
.
Checkbox
This Field type renders a single checkbox. When the checkbox is checked, the value of the
Field is "true"
. When it's un-checkecked, the value will be removed from the Form value altogether.
Attribute | Required | Type | Description |
---|
booleanField | | object | A BooleanField definition. |
choiceType | X | string | The string literal "Boolean" |
Boolean Field
Attribute | Required | Type | Description |
---|
default | | boolean | Default value for this Field to be set on initial Form rendering. |
title | X | string | User visible display label for this Field. |
type | X | string | The string literal "boolean" . |
Example
{
"title": "",
"type": "string",
"x-form": {
"booleanField": {
"default": false,
"title": "I accept these terms and conditions.",
"type": "boolean"
},
"choiceType": "Boolean"
}
}
Checklist
Sometimes, a user needs to be able to select multiple options from a list. This Field type renders a
list of checkboxes, allowing the user to select multiple options. The value of the schema will be a comma-delimited
string
of all the selected options, such as "option1,option2,option3"
Attribute | Required | Type | Description |
---|
choiceType | X | string | The string literal "Checklist" |
options | X | array[object] | An array of ChecklistOption definitions. |
optionsLayout | | object | A Layout definition. |
Checklist Option
Attribute | Required | Type | Description |
---|
label | | string | The user-visible label for this checklist option. When omitted, the value will be displayed directly. |
layout | | object | A FieldLayout definition. |
value | X | string | The value of this option |
Example
{
"title": "Favorite falvor(s)",
"type": "string",
"x-form": {
"choiceType": "Checklist",
"options": [
{ "label": "Vanilla", "value": "vanilla" },
{ "label": "Chocolate", "value": "chocolate" },
{ "label": "Strawberry", "value": "strawberry" }
]
}
}
Date
When a user needs to enter a date, this Field type renders a date input with a calendar icon in it. The
user can either type in a date manually, or click the calendar icon to display a date picker in a modal. When a date is
entered, the field's value will be a string
in the format YYYY-MM-DD
(such as "2024-02-26"
)
Example
{
"title": "Birth date",
"type": "string",
"x-form": {
"choiceType": "Date"
}
}
Date/time
When a user needs to enter both a date and time, this Field type renders a date/time input with a
calendar icon in it. The user can either type in a date/time manually, or click the calendar icon to display a date/time
picker in a modal. When a date is entered, the field's value will be a string
in the format YYYY-MM-DD HH:mm:ss
(such as "2024-02-26 13:14:15"
)
Example
{
"title": "Appointment time",
"type": "string",
"x-form": {
"choiceType": "Datetime"
}
}
Dropdown
To display a dropdown with multiple options, use the choiceType
of Select
. This will render a dropdown with the
possible values as options. When an option is selected, the value of the Field will be the string
value of
the selected option.
Standard attributes
Attribute | Required | Type | Description |
---|
enum | X | array[string] | The array of possible string values for the dropdown |
title | X | string | User-visible display label for this Field. |
Custom attributes
Attribute | Required | Type | Description |
---|
choiceType | X | string | The string literal "Select" |
enumLabels | | array[string] | An array of user-visible string labels for each value in enum , when omitted, the enum values will be displayed directly. |
Example
{
"default": "morning",
"enum": ["morning", "afternoon", "evening"],
"title": "Preferred contact time",
"type": "string",
"x-form": {
"choiceType": "Select",
"enumLabels": ["Morning", "Afternoon", "Evening"]
}
}
Integer
This Field type renders a numeric input, that validates the user's input is an integer
. When the input
is filled in, the value of the Field is the string
representation of the entered integer
.
Attribute | Required | Type | Description |
---|
integerField | | object | An IntegerField definition. |
choiceType | X | string | The string literal "Integer" |
Integer Field
Attribute | Required | Type | Description |
---|
default | | integer | Default value for this Field to be set on initial Form rendering. |
excusiveMaximum | | integer | An exclusive maximum value for this Field, meaning the entered value must be less than this value. |
excusiveMinimum | | integer | An exclusive minimum value for this Field, meaning the entered value must be greater than this value. |
maximum | | integer | An exclusive maximum value for this Field, meaning the entered value must be less than or equal to this value. |
minimum | | integer | An exclusive minimum value for this Field, meaning the entered value must be greater than or equal to this value. |
title | X | string | User visible display label for this Field. |
type | X | string | The string literal "integer" . |
Example
{
"title": "",
"type": "string",
"x-form": {
"choiceType": "Integer",
"integerField": {
"default": 5,
"maximum": 7,
"minimum": 0,
"title": "How many days a week do you work?",
"type": "integer"
}
}
}
Number
This Field type renders a numeric input, that validates the user's input is a number
. When the input
is filled in, the value of the Field is the string
representation of the entered number
.
Attribute | Required | Type | Description |
---|
numberField | | object | An NumberField definition. |
choiceType | X | string | The string literal "Number" |
Number Field
Attribute | Required | Type | Description |
---|
default | | number | Default value for this Field to be set on initial Form rendering. |
excusiveMaximum | | number | An exclusive maximum value for this Field, meaning the entered value must be less than this value. |
excusiveMinimum | | number | An exclusive minimum value for this Field, meaning the entered value must be greater than this value. |
maximum | | number | An exclusive maximum value for this Field, meaning the entered value must be less than or equal to this value. |
minimum | | number | An exclusive minimum value for this Field, meaning the entered value must be greater than or equal to this value. |
title | X | string | User visible display label for this Field. |
type | X | string | The string literal "number" . |
Example
{
"title": "",
"type": "string",
"x-form": {
"choiceType": "Number",
"numberField": {
"default": 33.3,
"maximum": 100,
"minimum": 0,
"title": "What percent of your time is spent on this activity?",
"type": "number"
}
}
}
Label
A Label is a way to display static text to a user. It's in no way associated with any Field, but is referenced
similarly within the order
attribute of a Form, or Section definition.
Two types of Labels are supported: text
and markdown
.
Markdown Label
Attribute | Required | Type | Description |
---|
type | x | string | The literal string "markdown" |
value | x | string | The Markdown text that will be rendered and displayed to the user. |
Example
{
"type": "markdown",
"value": "# Hello, World!"
}
Text Label
Attribute | Required | Type | Description |
---|
bold | | boolean | When true , the value will be rendered as bold text. |
color | | string | The CSS color to use for the displayed text. |
fontSize | | string | The CSS font-size to use for the displayed text. |
italic | | boolean | When true , the value will be rendered as italic text. |
type | x | string | The literal string "text" |
value | x | string | The user-visible text that will be displayed to the user. |
Example
{
"bold": true,
"color": "blue",
"fontSize": "2rem",
"italic": true,
"type": "text",
"value": "Hello, World!"
}
Section
Sections are a way to group Fields and/or Labels together within a Form. All Sections are
collapsible and opened initially by default. However, they can be configured to be collapsed by default.
Attribute | Required | Type | Description |
---|
collapsed | | boolean | Should this Section start out collapsed on initial render? |
layout | | object | A Layout definition. Determines how the Fields and Labels within this Section will be laid out. |
order | x | string[] | An ordered array of Field or Label names (keys in properties or x-form.labels ). |
title | | string | The user-visible name of this Section. |
Example
{
"collapsed": true,
"layout": {
"data": {
"columnGap": "1rem",
"templateColumns": "3fr 1fr 2fr"
},
"type": "grid"
},
"order": ["address1", "address2", "city", "state", "zip"],
"title": "Address"
}
Layout
Attribute | Required | Type | Description |
---|
data | x | object | The type-specific data for this Layout |
type | x | string | The type of Layout being specified, currently, the only option is "grid" |
Grid Layout
Attribute | Required | Type | Description |
---|
columnGap | | string | The amount of space rendered between columns in the grid (grid-column-gap). |
rowGap | | string | The amount of space rendered between rows in the grid (grid-row-gap). |
templateColumns | | string | How to break up consecutive elements into columns (grid-template-columns ). |
templateRows | | string | How to break up consecutive elements into rows (grid-template-rows ). |
Example
{
"data": {
"columnGap": "1rem",
"templateColumns": "1fr 1fr"
},
"type": "grid"
}
Limit
Forms can define Limits that allow the values of multiple Fields to be compared to each other. The individual schema for
one Field can't reference the value of another Field, but the Form can define a Limit that checks how the values of two
Fields compare to each other.
Attribute | Required | Type | Description |
---|
error | x | string | The user-visible error message to display if this Limit isn't satisfied. |
lhs | x | string | The Field name (key of properties ) for the left hand side of the comparison. |
op | x | enum[<, <=, >, >=] | The operator used to compare the lhs and rhs values. |
rhs | x | string | The Field name (key of properties ) for the right hand side of the comparison. |
Example
{
"error": "Start date must be before end date",
"lhs": "start-date",
"op": "<",
"rhs": "end-date"
}