The Forms add-on consists of an i-doit-compatible add-on and a backend application. The backend is responsible for data storage and is operated via a REST API.
You can use i-doit as a proxy to communicate with the Forms backend. This requires a valid user session in i-doit. Alternatively, you can call the Forms backend API directly. This document assumes direct communication.
No server-side validation
The backend does not contain any logical validations -- this task is handled exclusively by the frontend. When using the API directly, you forgo all control structures entirely. Keep this in mind when using it.
For using i-doit attributes, you additionally require the Forms add-on API to access essential attribute information.
Authentication against the Forms backend is done with a username and API key -- the same configuration parameters that you set in the i-doit configuration:
1234567
POST http://localhost:3000/login
Content-Type: application/json
{
"apikey": "APIKEY",
"name": "USERNAME"
}
Upon successful authentication you receive a JSON Web Token:
123
{
"access_token": "{JWT_TOKEN}"
}
From now on you include the token in every request in the Authorization header, provided the endpoint requires authentication. Example:
12
GET http://localhost:3000/api/form
Authorization: bearer {JWT_TOKEN}
A token is valid for 60 minutes by default. After expiry you must log in again.
GET http://localhost:3000/api/form/6245bf4f36f695945b3df9be
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWU2YThlNmY1ZTMxYjI5NzAwOTMxOWEiLCJuYW1lIjoic2VsY3VrIiwic3ViIjoiJDJhJDEwJFJ4YlRybVpUVXlXc1NSQ2VZTFR6enVBZXJZTUF1dUlsNU5qOWt5RFN4WXlFL0NsdG1iLmY2IiwiaWF0IjoxNjU3MjkyNTAxLCJleHAiOjE2NTcyOTYxMDF9.yEZAjFAGpOCbDsJuI_vqot5J75MOE0bKPPn8osQS0Ik
Via this endpoint you create new forms. The definition is done via JSON with the following structure:
1 2 3 4 5 6 7 8 910
{
// Name of the form
"name": "My Form",
// Structure
"shape": {
...
},
// Publication status
"published": false
}
The structure of the form is specified under shape. It represents a normalized and hierarchical structure. On the first level it contains all available node elements: headings, texts, dividing lines, i-doit category attributes, and pages.
You must ensure that the node IDs (root, PAGE_1, PAGE_2,...) are unique and do not repeat.
The available configuration parameters of a node are type-dependent. The general data structure looks like this:
1 2 3 4 5 6 7 8 910111213141516171819202122
{
"NODE_1": {
// Which nodes are contained in "NODE_1" - specification of the node ID
"children": [
"NODE_1.1",
"NODE_1.2"
],
// Configuration parameters for "NODE_1"
"config": {
// Type of the node
"type": "NODE_TYPE",
// Direct configuration parameters
"props": {
"parameter_1": "",
"parameter_2": "",
[
...
]
}
}
}
}
Particularly important is the root node. It represents the entry point on the basis of which you build the form hierarchically.
In the following you can see the complete structure of a form consisting of two pages ("PAGE_1" and "PAGE_2"). Each page contains a heading and a text description.
{
"Text165729439981501359363935038671": {
"children": [],
"config": {
// Node type: Text
"type": "Text",
"props": {
// Text to display
"text": "Page 2 Text",
// Placeholder: Displayed when the content is cleared in the frontend
"placeholder": "Enter your text",
// Visibility: Should the element be hidden?
"hidden": true
}
}
}
}
This type is more complex than the previous ones and therefore contains more configuration parameters. The parameters differ depending on the type of category attribute.
The basic data structure is described using the example of the attribute General > Title:
{
"Attribute165731273460305039947937820184": {
"children": [],
"config": {
// Node type: Category attribute
"type": "Attribute",
"props": {
// Attribute ID: Composed of the category constant and the technical attribute identifier
"attribute": "C__CATG__GLOBAL.title",
// Default title of the field in the form, if "label" is not specified
"defaultLabel": "Title (General)",
// Field label
"label": "LABEL",
// Is this a required field?
"required": false,
// Is the attribute required by i-doit? Natively or via the validation configuration.
"isSystemRequired": false,
// Label of the category
"categoryLabel": "General",
// Attribute type
"type": "text",
// Is the field visible?
"hidden": false,
// Default value
"defaultValue": "Pre-filled value"
}
}
}
}
Some configuration parameters are provided by the Forms add-on API. They consist of static or dynamic values:
attribute*: static value
type* : static value, indicates the attribute type
isSystemRequired : variable value, calculated based on validation or natively
This parameter overrides required, if the attribute is required by the system.
defaultValue : variable value, pre-filled if the object type references a default template that defines a value for the attribute
An incorrect specification of isSystemRequired will inevitably lead to an error when submitting the form, unless required is set to true. defaultValue is not strictly necessary if the values from the default template should not be considered.
All this information can be obtained via the Forms add-on API:
1
GET https://idoit-instance/forms/api/attribute?category=C__CATG__GLOBAL,C__CATG__ACCOUNTING&class=C__OBJTYPE__SERVER
category contains a comma-separated list of category constants. class contains the object type constant and is required to determine defaultValue. Example response:
i-doit has attributes that depend on another attribute within the category. A simple example is Model > Model, which depends on Model > Manufacturer.
The Forms add-on frontend contains control mechanisms that detect if you use Model > Model (child) without Model > Manufacturer, and automatically add the parent attribute.
You can identify these attributes by their metadata: The child attribute contains a parent entry and the parent attribute contains a children entry: