The advanced form was introduced to provide more flexibility when building compilations used to capture user input. It is based on the react-jsonschema-form library.

The advanced form offers many features that are not explained in detail here but are described on the library documentation pages. The live playground is also a very useful resource to interactively experiment with the various form options. Additionally, also have a look at the JSON Schema online documentation.

## Model

``````{
"data": {},       // form field data object
"schema": {},     // Define the structure of the form data
"uischema": {},   // Define which input control to use when editing a field
"formOptions": {} // Define field specific actions and styling
}``````

## Data

Refer to the generic widget page for a description of the general principles governing the treatment of data retrieved from a dataSource

The advanced form `data` element is an object with structure that matches the `schema` definition. It can be a flat set of key-value pairs but may also contain nested complex elements. For example:

``````{
"street": "7 Church Street",
"city": "Digby"
},
"firstName": "Joe",
"lastName": "Bloggs",
"age": 27,
"telephone": "555 123 456"
}``````

## Schema

The schema element serves to define the structure of the form data.

``````{
"type": "object",
"definitions": {},
"dependencies": {},
"description": "Form description",
"title": "Form tile",
"required": [],
"properties": {}
}``````
Field Description

`definitions`

The definitions property can be used to declare one or more named composite object types which are referenced when defining `properties`. This is particularly useful when multiple fields in the form have the same object structure. `$ref` is used to reference the declared `definitions` (See address field in the example below) Note: If a particular object field only appears once in the form, the nested structure can be declared in situ by directly providing the object `properties`. `description` Optional description, shown after the title. `dependencies` Used to define inter-field dependencies. `properties` Contains the declarations for the named form fields. They are always nested in schema elements of type "object". Refer to the properties section below for more detail. `readonly` Render all the fields in the form read-only. Individual fields can be be made `readonly` by using the `ui:readonly` property `required` List of required fields which must have a value before the form can be submitted. Required fields without appropriate values will be shown with a red border when a submit is attempted. The entries in the list refer to fields at the current object level. If the form contains nested fields, such as street and city in the example above, and these are `required`, then the property must be included at the schema level where they are declared as shown in the example below. `title` Optional form title shown at the top of the form. `type` Defines the top level type of form data and needs to be of set to object ## Properties The `properties` element, inside the `schema` section, is used to declare named fields shown on the form and save in the data. At the `schema` level it defines the root data properties, which may in turn be complex objects containing their own `properties`. Each property needs a `type` and may be further qualified using a number of available attributes, some of which are highlighted in the table below: Field Description `allOf`, `anyOf`, `oneOf` These properties allow different elements of a schema to be selected from an array of possibilities providing a means to dynamically control which fields ultimately appear in the data. When using `oneOf` or `anyOf` a specific field is typically configured to make the selection of the schema structure to activate and will be shown as a dropdown letting the user choose the fields to populate. The `ui:widget` for this field should therefor be set to "select" in the `uischema`. `default` Optional default value to assign if none is provided. `definitions` The definitions property can be used to declare one or more named composite object "types". This is particularly useful when multiple fields in the form have the same object structure. `$ref` is used to reference the definitions from a property (See address field in the example below)

Note: If a particular object field only appears once in the form, the nested structure can be declared in situ by directly providing the object `properties`.

`description`

Optional field description, shown after the title.

`dependencies`

Used to define inter-field dependencies.

`enum`

Enumeration used to define selectable options for a field. Note: When using enum fields be sure to select the appropriate `ui:widget` in the `uischema`.

`enumNames`

Custom labels used to provide readable names for numeric enum fields.

`items`

Defines the type of elements in array fields. This can be a simple type such as `string` or `number`, etc or it can be a composite type containing other fields. (refer to the Nested and Array examples live playground for more detail)

`properties`

Named properties of the root or nested form elements of type "object".

Note that the fields appear on-screen in the same order as they do in the `properties` section. The order can be explicitly set in the `uischema` using the `ui:order` property.

Refer to the library documentation for more details.

`title`

The field `title` is optional. If it is not provided, the field name (key) is used as the title.

`type`

Defines the type of the enclosing element. The root element must be of type object since it contains all the form fields. Individual form fields can have any of the following types:

• array: Used for lists of data. Needs to have an `items` property set to declare the type of the array elements. (also see `uischema` for matching input controls.)

• boolean: True/False value. Will be rendered as a check-box by default.

• integer: Whole numbers. The form will do type validation to check that the provided input is an integer number.

• number: Any number including decimals. The form will do type validation to check that the provided input is a integer or real number.

• null: "dummy" entry used to provide extra information to form users. Null fields don’t present an input field nor do they appear in the data.

• object: Object with named fields. Fields are declared in the `properties` of the enclosing object. (see example below)

• string: Generic text input. Note that date fields need to be declared as strings since they are stored in ISO 8601 strings format.

The field type can also be an array of two elements. One being the base type, the other "null" if the field in question is nullable. (For example “type”: ["integer", "null"]). Since a null cannot be entered, the field default would also need to be set to `null`.

`uniqueItems`

Apply this property to array type fields to ensure that a specific entry can only be selected once.

### Schema Examples

#### Definition and reference

In this example a number of schema options are shown. Note the use of `definitions` to define the address object with two fields and its use in the house_address field by referring to it with a `$ref` path. ``````{ "type": "object", "required": [ "firstName", "lastName", "age" ], "definitions": { "address": { "type": "object", "properties": { "street": { "type": "string", "title": "Street" }, "city": { "type": "string", "title": "City" } }, "required": [ "street", "city" ] } }, "properties": { "firstName": { "type": "string", "title": "First name" }, "lastName": { "type": "string", "title": "Last name" }, "age": { "type": "number", "title": "Age", "minimum": 18, "maximum": 67 }, "birth_month": { "type": "integer", "title": "Month of Birth", "enum": [1,2,3,4,5,6,7,8,9,10,11,12], "enumNames": [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] }, "telephone": { "type": "string", "title": "Telephone", "minLength": 10 }, "house_address": { "type": "object", "title": "House Address", "$ref": "#/definitions/address"
},
"email": {
"type": "string",
"title": "Email",
"format": "email"
}
}
}``````

#### Composite array values

In this schema, the input field, called tuples, is an array containing objects with a name and a value declared directly in the property, rather than using a definition and reference as in the example above:

``````{
"type": "object",
"properties": {
"tuples": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "number",
"enum": [ 1, 2, 3, 4 ]
}
}
}
}
}
}``````

Refer to the `uiSchema` example to see how to set the input controls to use for each of the fields.

### Schema validation properties

The following schema validation properties are provided in the `schema` section of the form. Also refer to the `uischema` for additional validation options.

Field Description

`exclusiveMinimum`, `exclusiveMaximum`

Validate number to be strictly larger than or less than the stated minimum or maximum

`exclusiveMinimum` < Field Value < `exclusiveMaximum`

`format`

Allows a set of pre-defined schema formats to be used to validate strings. The Advanced Form supports the standard JSON Schema formats and adds two extra custom formats as defined here

`minimum`, `maximum`

Enable validation on the allowed values of `integer` and `number` field

`minimum`Field Value`maximum`

`maxItems`, `minItems`

Set limits on the number of elements allowed in an array field.

`maxLength`, `minLength`

Set limits on the allowed length of a string property

`multipleOf`

Constrain the numeric field value to be a multiple of the `multipleOf` property, for example:

``````{
"type": "number",
"multipleOf" : 10
}``````

`pattern`

Validation regular expression to applied to string fields. Patten validation is only done on fields which contain data. This implies that to enforce patterns which require the text to contain a minimum number of characters, the field must also be `required`.

## UI Schema

The UI Schema is used to manage the appearance of the form fields and specify which controls to use to edit them. It is recommended that a `ui:widget` be assigned to all form fields to ensure the edit controls used adhere to the overall styling of the WebStudio compilation and the selected theme.

The `uiSchema` property contains elements for all form-fields requiring configuration to be applied, the model for which looks something like this:

``````{
"ui:order" : [] // Optional array used to set the display order of the form fields
"<field-name>": { // Entry for each field requiring ui-configuration
"<ui:xxx>" : "value" // See table below for available options
"<nested-field-name>": {
// configuration detail for fields in nested objects.
}
}
}``````

The angle brackets in the above fragment are used to indicate placeholders for implementation specific content.

Field Description

`classNames`

String field containing the names of one or more style classes to assign to the field. Refer to `formOptions.styleByClassName` for more details.

`ui:description`

Alternative / override field description. This one takes precedence over the `description` in the `schema`

`ui:disabled`

Set to true to disable the field and prevent the content from being selected. This setting on the face of it does the same as `ui:readonly`, the difference is that the latter still allows the content to be selected.

`ui:enumDisabled`

This array property can be used to disable one or more options from an enum list. For example:

``````{
"schema" : {
"enumField": {
"type" : "string",
"enum" : ["One", "Two", "Three"]
}
},
"uiSchema" : {
"enumField": {
"ui:enumDisabled" : ["Two"]
}
}
}``````

`ui:help`

Display an additional help string after the field input control.

`ui:options`

This is a composite property with the following fields:

`inline`

when set to true, radio buttons and check-boxes can be shown in-line rather than on separate lines. For example, using an array field to allow users to select multiple options, the following setting could be used:

``````{
"schema": {
"type": "object",
"properties": {
"hobbies": {
"type": "array",
"title": "Hobbies",
"description": "Check all that apply",
"items": {
"type": "string",
"enum": [ "sports", "camping", "travel", "reading", "making" ]
},
"uniqueItems": true
}
}
},
"uiSchema": {
"hobbies": {
"ui:widget": "checkboxes",
"ui:options": {
"inline": true
}
}
}
}``````

`inputType`

Note: Not all the options from the underlying library have been fully integrated with WebStudio yet. These will be documented as they are introduced.

• color: The input control used for the field is a color-picker

• file: Allows a file name to be picked from the local file system. The field name will be the path to the selected file.

• password: Causes the field text to be obscured. Don’t set the `ui:widget` property with this setting yet.

• text: Treat the input as a regular text box.

`label`

Setting the `label` property to false will cause the field name to be hidden.

`placeholder`

Place-holder text shown in the input box to provide users with a hints of the expected content.

`rows`

Used with a "textarea" `ui:widget` type, sets the number of rows in the edit box.

`ui:placeholder`

This is the same as the placeholder in the options field.

`ui:readonly`

When set to true, the field value cannot be edited but is still selectable and can be copied to the clipboard.

`ui:title`

Overrides the field title provided in the `schema` section

`ui:widget`

This property is used to select the specific widget to use as the input control for the field. Available options are:

• checkbox: Shows a single checkbox, typically used with a boolean field.

• checkboxes: Shows a set of check-boxes. Can be used with array properties where multiple selections are made from an enum as shown in the `inline` example above.

• datepicker: Provides an input box with an icon to bring up a date-time picker dialog.

• hidden: Hides the field in the form.

• password: Obfuscates entered characters. The same outcome can be achieved by setting the `inputType` equal to password

• radio: Shows a radio-button associated with boolean or single selectable enum value. In case of the latter one radio button is shown for each enumeration.

• range: Shows a range slider. The minimum and maximum values for the slider are taken from the `schema` `minimum` and `maximum` settings.

• select: Drop-down list. When this `ui:widget` is used with properties of type array, multiple items can be selected.

• text: Text input box

• textarea: Shows a multi-line text input field

• updown: Input field restricting the values that can be entered to a number, either integer or decimal.

### uiSchema examples

#### Nested Fields:

Referring to the "Definition and Reference" example above, the `uiSchema` to set the address input controls for the `street` to a text-box and the `city` to a regular input would look something like this.

``````{
"street": {
"ui:widget": "textarea"
},
"city": {
"ui:widget": "text" // Not really needed since string fields use this widget by default
}
}
}``````

The outer object name used is that of the containing field "house_address", rather then the type "address"

#### Nested fields in an array:

When the fields are contained in an array as is the case for the second schema example and require specific `ui:widget` specs, an `items` element needs to be added to the specification as shown:

``````{
"tuples": {
"items": {
"name": {
"ui:widget": "text"
},
"value": {
"ui:widget": "select"
}
}
}
}``````

## Form Option

The form options provide further customization features that are specific to WebStudio. The `formOptions` property has the following structure:

``````{
"formOptions" : {
"entryOptions": {
"<field-name>" : {
"actions": { }
}
},
"styleByClassName": {
"<custom-class-name>" : { }
}
}
}``````
Field Description

`entryOptions`

Action pipelines can be triggered on changes to individual fields. To do so, add the field-name as a key under the `entryOptions` element and implement the desired pipeline in the relevant `actions` entry. Fox example, say we wanted to perform some action when the firstName field gets the input focus.

``````{
"formOptions" : {
"entryOptions": {
"firstName" : {
"actions": {
"onFocus" : {
"type" : "notify"
}
}
}
}
}
}``````

The actions available at field level are: `onBlur`, `onChange`, `onChanged` and `onFocus`.

Field level actions for nested entries can be declared by providing the dot-notation path. Consider a form with the following schema:

``````{
"schema": {
"type": "object",
"properties": {
"nested": {
"type": "object",
"properties": {
"field1": {
"type": "string",
"title": "Field 1"
}
}
}
}
}
}``````

To define an action pipeline to trigger when `field1` gets the input focus, the `entryOptions` would look like this:

``````{
"formOptions": {
"entryOptions": {
"nested.field1": {
"actions": {
"onFocus": {
"type": "notify"
}
}
}
}
}
}``````

`styleByClassName`

This property is used to add custom styling to form fields. Let’s say for some fields in the form we want to use a different font. The style can be declared as follows:

• In the `formsOptions.styleByClassName` add a property for the custom class name, let’s call it customFontClass. Add the style options in the style body.

• In the `uischema`, include a `classNames` property with all fields where we want the new style to be applied and set the value to customFontClass

``````{
"schema": {
"type": "object",
"properties": {
"monoTextField": {
"type": "string"
}
}
},
"uiSchema": {
"monoTextField": {
"ui:widget": "textarea",
"classNames": "customFontClass",
"ui:title": "Mono-space Text Field"
}
},
"formOptions": {
"styleByClassName": {
"customFontClass": {
"fontFamily": "Monaco",
"fontSize": "larger"
}
}
}
}``````

`showValidationErrors`

Validation error can be shown directly as annotations in the form by setting this property to true, or suppressed entirely by setting it false

## Options

Set widget options.

``````{
"options": {
"showRefreshButton": true,
"showToolbar": false,
"refreshInterval": 10
}
}``````
name description

`showRefreshButton`

Set this to false to hide the refresh button. By default the refresh button is visible.

`showToolbar`

Use to hide the complete toolbar.

`refreshInterval`

Refresh with an interval in seconds.

## Actions

The Advanced Form supports a number of action hooks in addition to the default lifecycle ones, most of which can be used at form and field level by defining `entryOptions` as described above. The exceptions are `onSubmit` and `onValidationError`, which are not triggered separately for each field.

• onBlur : This event fires whenever a field loses input focus.

• onChange : Triggers on every input change.

• onChanged : The action only triggers if the content of the field, when it loses input focus, is different from that when it received focus.

• onFocus : Triggers when a field receives input focus.

The message payload for these actions contains the name of the affected field expressed, in dot-notation if it is nested, and optionally the current value. The `value` is omitted if the field is blank. For example:

``````{
"name": "nested.field1",
"value": "some text"
}
}``````
• onSubmit : Gets called when the form submit button is pressed. The submit will not fire if there are validation error on the page.

When the form is valid, the message payload will be the form data object. Only fields containing values will be present in the output.

• onValidationError : Triggers when the form is submitted but there are validation errors.

The message payload in this case is an array of error messages for all invalid fields.

### Collect

The collect action can be used in an action pipeline to retrieve the current form data. The message payload will contain an object with entries for all fields that have a valid value.