Skip to main content

Specific form component types

info

This content is intended for all Studio users.

Here are some additional information for the most frequently used form components.

Input fields​

Input fields are components intended for entering or selecting values. All template leaf nodes (fields that can't have any children) are input fields. Besides templates, you can also pick generic input fields from Generics component panel and add them to a form.

Inputs

Some configurations are common to all fields, while some are specific to the type of input field you are working with.

The configuration options that are common for all input fields are:

  • The alias of an input field allows it to be referenced by a custom name.
  • The label, which allows you change the name of a field shown to you while using the form.
  • The default value, which allows you to define the default value of an input field.
  • You can set the input fields status to required, hidden, or readonly.
  • You can change how a field behaves in the presentation mode.
  • The settings the layout of a field (where the label resides).
  • Size changes of an entire input field.

Design panel for an input field component

Field layout and size​

In the Layout section of the Design panel, you can change the label position of a field. A field can have a label on top, on the left side, or hidden.

If none of these options is selected, the label layout is inherited from its parent container, with global settings being the top-most ancestor.

To revert the layout options to its default state inherited from its parent:

  1. Click on a input field component on the canvas.
  2. Deselect the currently active layout option in the Layout section of the Design panel.

Layout options

The layout you specify for your input field components will be reflected in their presentation on the canvas.

You can change the size of a field by moving the slider in the size configuration option. Fields with labels on the left size have one additional configuration that allows you to change the amount of blank space a label needs relative to the input space.

Persistent property​

Input field components can be marked as persistent.

Persistent property

Although this is not a template field, when a generic component is marked as persistent, its value will be stored within the composition. This allows it to be reloaded into the form whenever the composition is applied. This way, you can manage additional values that are needed on the form, even if they are not part of the template model.

Specific input field configurations​

Some input field components can be configured in ways specific to a certain type or types of fields.

Almost all fields have a placeholder option that lets you define a placeholder value that is displayed before data is inputted.

Placeholder

Input text​

This is the most basic input type and as the name denotes, it serves as an input to which users can write text.

On the text field you can set additional validation in the form of a RegEx. There are four predefined ones you can choose from:

  • email
  • only letters
  • only numbers
  • URL

If none of predefined ones suits you, you have the option to write your custom one and create an error message to display if the text does not meet criteria.

You can increase these input fields' height by changing the display in 1 line/s configuration. Additionally, you can configure text fields to automatically resize depending on the text's length.

Input fields options

good to know

Most common input text field types are DV_TEXT and GENERIC_INPUT_TEXT, but many other openEHR-related text inputs are available.

Numeric, count, and proportion fields​

Numeric, count, and proportion fields only accept numerical input. Count only allows whole numbers, while numeric and proportion allow numbers with as many decimal places as configured.

The only specific configuration for these fields is the field validation located in the Content tab of the Property panel.

Field validation allows you to validate inputs based on:

  • How many decimal places are allowed.
  • A boundary value, which the input values either mustn't surpass or be lower than.

Here is an example of a validation for generic numeric:

Numerical input options

good to know

DV_COUNT and DV_PROPORTION are openEHR fields frequently named as Count and Proportion. GENERIC_NUMERIC_FIELD and GENERIC_PROPORTION_FIELD are generic components that reside in the Generics panel. In the Generics panel they are named Numeric and Proportion.

The configuration of dropdown fields is the most complex of all field categories. They can be set to any of the four available presentation options, they have three different ways of defining their selection values, and a specific number of allowed values settings.

There are five different input field components in this category:

Field component typeField component nameGeneric fieldDescription
DV_TEXTInput textNoTexts can have selections values defined. These values can just be suggestions, and the end user can input something else.
DV_CODED_textCoded textNoSelections are stored in EHR Server as code (abstract code of the selection) and label (user-facing label of the value). ️
DV_ORDINALOrdinalNoDV_ORDINAL is equal to DV_CODED_TEXT, except that it also holds ordinal number which is an integer.
DV_SCALEScaleNoDV_SCALE is equal to DV_ORDINAL, except that instead of the ordinal number value, it holds scale number value which is a real number.
GENERIC_CODED_TEXTGeneric coded textYesActs as coded text, except that it is generic.
GENERIC_ORDINALGeneric ordinalYesActs as ordinal, except that it is generic.

In the Design tab of the Property panel, under the Field section, you can choose among four different Presentation options of these fields:

  • combobox
  • checkbox
  • button group
  • interactive image

The combobox presentation option allows picking values from a dropdown menu when filling in forms. This is the best presentation option for fields that have lots of possible values.

BMI combobox

The logic behind checkbox and button groups presentation options is very similar. The main difference is that button groups do not have to necessarily be distributed among columns. They can also be distributed depending on the field configuration. If we allow more than one selection value, radios simply become checkboxes.

Button groups

The last presentation option on the list is interactive image. This option is used for fields residing within an image map. Image maps allow you to create clickable pressure points on an image. See below under Image map for more

Multiplicity of a dropdown field​

By setting the minimum multiplicity of a field, you are setting how many selection values are mandatory. By setting the maximum multiplicity of a field, you are setting how many values can be selected.

The two most common examples are:

  1. min multiplicity = 0, max multiplicity = 1. This means that the user can select one value from a list, but it is not required
  2. min multiplicity = 1, max multiplicity = 1. User must select one value from a list of values.

If the min multiplicity = 4 and max multiplicity = 6, then the user must select at least four values, but not more than 6. More concretely, user must select between 4 - 6 options.

Multiplicity

Selection values of a dropdown elements​

Selection values are all the possible values for the user to choose from. If these selection values are already defined on the openEHR template, then the user can only hide them by clicking the eye icon on the left or change the label of them.

If the selection values are not defined, either because a field is generic or because template does not have them defined, then you can add selection values in one of the following ways:

  • by adding internally defined selection values manually
  • by getting them from external API through datasource
  • by getting them from AQL variable

Boolean​

Although it is a very simple field component with only three possible values (null, true, false), it still offers rich configuration options.

You can present a boolean field component in four different ways:

  • checkbox
  • three-state
  • toggle switch
  • yes/no question

Boolean

Three state boolean and yes/no question are the only presentation where user has total control regarding the null value of the field. For other presentations the second "switch" or "check" simply changes the value to false instead of null. If the configuration of boolean field in archetype designer does not allow false values then the second switch switches to null instead of false.

Boolean

Quantity​

Quantity is a composite field that has two input values:

  • magnitude part where you write the number
  • unit part where you select the unit

Quantity

Units will be presented in dropdown if more than one value is available otherwise it will be shown as a simple readonly label. You can make unit read only (where units can only change through dependencies), or you can also hide units on the Content tab, so they aren't presented to the end user.

Quantity read-only

When quantity value is empty, unit will be shown at the end of the field since it is not yet associated to a value. Once value is entered a unit will stick to the value for easier reading. The magnitude part allows you to add validation as on numeric fields.

Empty quantity

Layout group fields and containers​

Layout group fields are used for two purposes:

  1. To change the layout of the fields by adding rows and columns.
  2. To group fields together.

For your convenience, layout groups are provided in a single-column layout by default, with the option to add or remove columns and rows.

Layout options

Layout options​

We differentiate between the following layout options:

  • V Stack: Arranges its child fields in a single column, one below the other.
  • H Stack: Arranges its child fields side by side in a single row.
  • Grid: Lays out child fields in a defined number of rows and columns, giving you precise control over the placement of each field.
  • Group: A named container that visually and semantically ties a set of fields together without changing their individual layout.
  • Spacer: Inserts a fixed or flexible gap between fields, letting you control whitespace without adding a visible element.

V Stack​

Use V Stack when you want fields to flow downward. This is the most common default arrangement for a form section. Children are stacked top to bottom, with consistent gaps between them. You can control whether child fields distribute from top to bottom or spread out to fill the available vertical space. If V Stack is placed inside another layout component, you can set its width to Fixed (a specific pixel value) or Fill (takes up a proportional share of the remaining space). Enable Wrap to allow children to continue into a new column when they exceed the available height.

H Stack​

Use H Stack to arrange fields in a row. An example would be to have a first-name and last-name field sitting next to each other. Children are distributed left to right by default, or you can change this setting to spread them evenly across the full width of the row. Each child field can be set to Fixed or Fill width, which controls how much horizontal space it claims relative to its siblings. Enable Wrap to let children overflow onto a new row when the total width of children exceeds the container width.

Grid​

Use Grid when you need a structured, table-like arrangement that cannot be achieved by nesting stacks alone. An example would be a form section with three columns of varying widths. Each column can be set to a Fixed pixel width or a Fill fraction (fr), which distributes remaining space proportionally, following the same behaviour as column widths in a column list. Grid is not responsive by default; On narrow screens you should test how the layout behaves with your chosen column widths.

Group​

Use Group when you want to label or visually enclose a set of related fields, without restructuring how the fields themselves are arranged. An example would be a "Contact details" section. A group adds a visible header (the group label) above its children. You can show or hide a border around the group. Unlike other layout options, a group does not control the flow direction or sizing of its children. Those properties are determined by the stacks or grid components placed inside it. You can add a dependency to the whole group to show, hide, or disable all its contents at once.

Spacer​

Use Spacer to push fields apart or to create breathing room between sections of a form. When placed inside an H Stack, a spacer with Fill width pushes subsequent fields to the right edge of the row. When placed inside a V Stack, it adds vertical space between fields. A spacer has no visible output in the rendered form, it is a layout-only element.

Adding Rows and Columns​

If you want to have fields distributed among rows and columns, you must have a layout group on the canvas and click on the cogwheel on the right side of the cell and then add rows or columns.

Adding rows and columns

These columns are responsive to the environment they are in, and they stack on mobile device.

If Show borders is deselected, the end users won't see that this is a layout group. They will only see fields distributed among columns and rows.

warning

Before layout group fields were introduced containers were used to create a layout for the form. Since version 3.2.0 all previous containers, that had their header hidden, were automatically converted into layout groups. Containers have no longer the ability to add rows and columns, they are used only for grouping fields together.

Grouping fields together​

By adding fields in one layout group or container you are able to visualize them as one group of items.

You can achieve this by adding fields to a layout group:

Adding fields to a group

You can add fields into a container (but note that here you can no longer add rows or columns):

Adding fields to a container

You may also insert a layout group with rows and columns inside a container:

Adding layout group to a container

Consequentially, you can add a simple dependency on the whole container or layout group instead of adding it to individual fields separately:

Container dependency

Using containers on the canvas reduces the speed of your application, as rendering them is a performance-intensive operation. The alternative is to use tags to group elements together.

Multiplication of data​

This is only possible with non-generic containers that have max multiplicity > 1. The minimum setting will set the required data.

An example would be setting the minimum to 1. The end user will need to fill at least one set of the container components.

The maximum setting will set the number of available duplicates of components within a container.

When setting design rules to your container field or component, click the ellipsis (...) to duplicate or copy the field or component:

By setting the Height measurement event to min one and max two, the height measurement is required (at least one measurement), and it is limited to two measurement events.

List presentation of multiplied containers​

If you have a container that allows multiplication and does not contain containers within itself you can change the presentation of it to list.

Presentation of multiplied containers

The list presentation will create a list of columns with the field names as headers. The functionality is the same as with multiplied containers above, the difference is the presentation, which might be more suitable for certain situations.

List presentation

Layout group settings​

Layout group settings include:

  • Required: The user can set the layout group to behave as required or not.
  • Readonly: All fields inside the layout group will be readonly.
  • Hidden: The layout group and all its fields will be hidden.
  • Show border: The user may choose to show the borders of the layout group field.
  • Layout group settings

Layout group settings

Apart from the widely used readonly and hidden, other containers settings are:

  • Show borders: The user can show the border of a container.
  • Enable collapse: Containers can be collapsed.
  • Collapse by default: You can set a container to be collapsed by default if Enable collapse is set to true.
  • Hide multiplication buttons: This will hide the + and - multiplication buttons (Note that this setting only appears if the container can be multiplied to begin with).
  • Presentation: The user can choose the presentation of the container to be as container or list. Note that this setting only appears if the container can be multiplied to begin with and if it doesn't include any containers in itself.
  • Container settings

Container settings

When a container presentation is changed to list you get an additional setting group for Table. Here you can set:

  • Hide header: Hides the header of the list.
  • Show all borders: Shows all borders of the list.
  • Set custom height: Opens up a input field where you can set a custom height expressed in pixels.
  • Sticky header: Sets the header to sticky when scrolling through the list. Only available if you set a custom height.
  • Sticky columns: You can set one or more columns to remain sticky when scrolling horizontally.
  • Container list table settings

Container presentation

To remove a container from the canvas without removing the components that are in the container, you can click the red frame button on the right side of the container:

Remove a container

Buttons​

Buttons are generic components that allow you to attach actions to them.

The button does not have any actions set and by itself does not do anything. You can hook actions to the button.

Button component

The most common examples are:

  • Saving the composition or incomplete composition
  • Toggling the visibility of some components.
  • Moving to another page.
warning

When adding the When clause dependency, you cannot add an Otherwise clause. Buttons do not have this option available.

Button example

You can change the style of a button by setting the style in the property panel's Design tab. You can switch between four different styles:

Button styles

Column and stacked lists​

Lists are generic elements that allows you to display repeated sets of data in a tabular format. Data is obtained through APIs or AQL variables.

Column and stacked lists

Imagine you're building a form for a patient's medical history. You can use a list to display information about the patient's visits, such as the date of the visit, the doctor's name, and the diagnosis. You can also use a list to display a list of medications, a list of allergies, etc. You can also control how data is displayed in the list. For example, you can sort the data, use widgets to convey complex information, or use generics to display simple data.

There are two kinds of lists to choose from:

  1. Column list: Displays data in a table format that consists of rows and columns.
  2. Stacked list: Display data in a single column format.

Column list​

Column lists are used to display data in a table format. The data is displayed in rows and columns. Each column can contain any type of data, such as text, numbers, images, etc.

To add a column list to the form:

  1. The column list is available in the Containers & lists section of the Generics components.
  2. Drag the Column list option to the canvas.
good to know

You can also double-click any components onto the canvas. By dragging and dropping, you can place the component wherever in the Form builder canvas. Double-clicking will add the selected component to the bottom of your form.

The column list has a header row and a data row. The header row usually contains column names that give an indication oo what kind of data is in that column, and can also contain sort indicators if sorting is enabled. If you have multiple rows in your source data set, the data row is repeated for each item in your source data set.

Column list

Setting data sources​

A list can receive data from an API or an AQL variable.

To set an API as the data source:

  1. Ensure you have an API connector that returns a list of objects.
  2. Select the Content tab in the right panel.
  3. Select the desired API as the data source.
  4. Set the source to value (list).

Column list data source

Binding data to columns​

Each column has a rich text generic by default, which uses the Mustache templating engine. The default variable to bind data to is {{datasource}}.

You can bind data in the right panel under the Content tab by setting a label for {{datasource}}. Studio previews sample data when you bind.

Column list bind data

When an array of data is bound to one data source, you can access each item using dot notation, for example {{datasource.name}}.

Column list bind data with dot notation

Adding, removing, and reordering columns​

To add a column, click the Add column button in the Design tab or on the column list itself. Both methods add a column to the end of the list.

To remove a column, click the Remove column icon in the Property panel or on the column list. Either method removes the selected column.

To reorder columns, use the drag handle icon next to the column name in the Property panel.

Column list manipulation

Column widths​

Three properties control column widths:

  • Fixed: Sets a fixed width in pixels. The column width does not change regardless of content.
  • Fill: Divides the remaining space between columns set to Fill, according to their fraction unit (fr). For example, in a two-column layout where both columns are set to Fill with 2fr and 1fr respectively, the first column is twice as wide as the second.
  • Fit: Sets the column width to fit its text content.
  • Add min: Adds a minimum pixel width.
  • Add max: Adds a maximum pixel width.
warning

Fit does not calculate the width of generic input fields. If a column contains input fields, it will shrink to the width of the generic input.

warning

If a column contains a widget, set the column width to Fixed or Fit to prevent the widget from spilling into other columns.

Column list width examples

Column widths and backwards compatibility​

Studio 3.9 introduced column width, content alignment, and text overflow. These features are not backwards compatible with renderer version 3.8 or earlier.

danger

If you are using Studio 3.9 with renderer 3.8 or earlier, column lists created in version 3.8 or earlier will still render, provided you do not edit any properties. Once you edit any property, the column list updates to the new version and cannot be used with renderer 3.8 or earlier. Updating converts all columns to Fill width.

List settings​

The Property panel provides additional settings for the list:

  • Set custom height: Sets the height of the entire list.
  • Hide header: Hides the header row.
  • Sticky header: Makes the header sticky (only available when a custom height is set).
  • Enable pagination: Enables pagination and allows you to set the number of rows per page.
  • Vertical dividers: Shows vertical dividers between columns.
  • Alternate row colours: Applies a different background colour to every other row.
  • Text overflow: Controls the behaviour of text that does not fit in a cell.
  • Content alignment: Defines the alignment of content in cells.
  • Sticky columns: Sets one or more columns to remain visible when scrolling horizontally.

Column list settings panel

Text overflow​

Three options are available:

  • One line: Text is displayed on one line and is not cut off.

One line text overflow

  • Truncate: Text is displayed on one line and cut off with an ellipsis if it does not fit.

Truncate text overflow

  • Wrap: Text wraps to multiple lines if it does not fit.

Wrap text overflow

Content alignment​

Two options are available:

  • Top: Content is aligned to the top of the cell.

Top content alignment

  • Middle: Content is aligned to the middle of the cell.

Middle content alignment

Sorting​

Sorting arranges column data in ascending (ASC) or descending (DESC) order. When a column is sortable, arrow icons appear to indicate that sorting is available and to toggle between orders.

To enable sorting, select columns in the Sortable columns section. Remove a column from sortable columns by clicking the x next to the column number.

Sortable columns

For each sort group, you can define key-value pairs for ASC and DESC directions. These pairs are appended to the data source URL. You can define successive key-value pairs — for example, sort first by date, then by name within the same date.

Sort group properties

Each sortable column has a toggle to set it as the default sort order. This default is applied when the user first opens the form.

Sort persistence​

The last selected sort order can be saved to your server and applied each time the user opens the form. To enable sort persistence, scroll to the bottom of the Sort section in the Properties panel and configure the Persist last selected sort to and Retrieve last selected sort from dropdowns.

Sort persistence properties

Saving: The form renderer binds sort values to the datasource body before sending to the API endpoint. Two predefined values are required in the API call body: order and column. These values are replaced by the renderer with the actual sort order and column number.

POST datasource for sort persistence

Retrieving: Any API call with a GET method can be used. After selecting a datasource, bind the return properties (ASC/DESC and column number) to the order and column properties.

Sort persistence retrieve binding

Stacked lists​

Stacked list is available in the Containers & lists section. Drag it to the canvas.

Stacked list is similar to column list, with two differences: It has no header row and it has only one column.

Stacked list

The example shows a stacked list connected to a weight_aql variable and displays the result in one column.

Stacked list AQL variable

Manipulating data inside a list​

Column list and stacked list support adding any type of field to columns. Every column also contains a rich text area with the Mustache template engine, enabling a range of display solutions.

To-do list with a status image​

The following example shows a list of to-do tasks, each with name and completed properties. A red icon is displayed when a task is incomplete; a green icon when it is complete.

To-do list with status image — Preview

To-do list with status image — Configuration

Template text for the to-do list with status image

Connect the column list to an API returning the list of tasks. Drag an HTML component into the complete row. Using Mustache templating, check whether the data source variable is true or false and display the appropriate icon.

Measurements with a status image​

This example shows how to display different images based on patient mood measurements.

Measurement status image — Preview

Since the Mustache engine can only check true/false values, use Studio's interaction dependencies. Add an input field, bind the mood data to it, and hide the input. Then set dependencies based on the input value to show or hide mood images.

Measurement status input configuration

Measurement status interaction configuration

Rich text​

Rich text is a generic component that allows users to create and edit formatted content and to dynamically template content using variables. The component is split into two parts: an input area and a toolbar.

Rich text component

Formatting​

The rich text component supports the following formatting options:

  • Headings (H1–H5, paragraph)
  • Unordered lists (bulleted)
  • Ordered lists (numbered)
  • Links
  • Bold, italic, underlined, and strikethrough text
  • Subscript and superscript text
  • Indentation
  • Text alignment (left, centre, right)
  • Text colour (black, grey, blue, red, orange, green, purple)
  • Clear format

To format content, select it in the input area and choose the desired option from the toolbar.

warning

Pasting rich content from other sources may contain unsupported formatting, which Studio will strip from the content for visual and safety reasons.

Templating​

Users can dynamically create content using the Mustache templating engine, with the same syntax and tags as the HTML component. Tags are indicated by opening delimiter {{ and closing delimiter }}.

warning

Formatting rendered variable values requires that the whole tag is formatted, not just the content between the delimiters.

For a full reference of templating syntax and examples, see the HTML section below.

HTML​

HTML is a generic component that allows users to write HTML code and dynamically template it using variable values. The component has two tabs: a Visual tab that previews the rendered HTML, and an HTML tab that provides an input area for writing code.

HTML component

Templating​

HTML templating uses the Mustache templating engine. Tags are indicated by {{ and }}.

Basic tags​

A basic tag renders the value of the named variable. If the key is empty or the variable does not exist, nothing is rendered.

Variables:

{
name: Michael
}

Template:

* {{name}}
* {{age}}

Output:

* Michael
*

Use dot notation to access object properties:

Variables:

{
person: {
name: Michael
}
}

Template:

* {{person.name}}

Output:

* Michael

Use index and dot notation to access array items:

Variables:

{
people: [
{ name: Michael },
{ name: John },
{ name: David }
]
}

Template:

* {{people.0.name}}

Output:

* Michael

Section tags​

A section tag uses a # symbol before the variable name for the opening tag and a / symbol for the closing tag. The section block is rendered based on the variable's value.

False value — if the variable does not exist or has a false value (null, undefined, false, 0, NaN, empty string, or empty array), the block is not rendered:

Variables:

{ person: false }

Template:

* Shown
{{#person}}
* Hidden
{{/person}}

Output:

* Shown

True value — array: If the variable is an array, the block renders once for each item, with the context set to the current item.

Variables:

{
people: [
{ name: Michael },
{ name: John },
{ name: David }
]
}

Template:

{{#people}}
* {{name}}
{{/people}}

Output:

* Michael
* John
* David

For an array of strings, use . to refer to the current item:

Variables:

{ names: [Michael, John, David] }

Template:

{{#names}}
* {{.}}
{{/names}}

Output:

* Michael
* John
* David

Inverted section tags​

An inverted section uses a ^ symbol before the variable name. The block is rendered only if the variable has a false value:

Variables:

{ person: false }

Template:

* Shown
{{^person}}
* Also shown
{{/person}}

Output:

* Shown
* Also shown

Notification fields​

The notification component is a generic form element for displaying important information.

It can have one of four styles:

  • Basic
  • Info
  • Warning
  • Draft

Notification field styles

The styles let you quickly communicate the type of information — whether it is urgent or informational. You can format the text inside a notification field in the same ways as a rich text field.

Notification field formatting

Use dependencies to control when a notification appears on the form by toggling its visibility. If you use more than one notification on a form, it is good practice to change their labels in the Design panel to avoid confusion when multiple notifications are all labelled "Notification".

tip

To dynamically change the content of a notification, use a variable within the notification and change it using dependencies, in the same way as with rich text elements. See the Rich text section for details.

Image canvas​

Image canvas allows a user to draw on a selected image and then upload the image to an external server.

Image canvas icon

The image canvas component is available in the Multimedia section. Before using it, you must select and upload an initial image. Image canvas must be connected to a POST API endpoint to store the images.

Setting up an upload API endpoint​

To save an image, set up an API endpoint using the POST method. The method receives form data and saves a file.

Upload API endpoint example

The example above expects three parameters: resource, mimeType, and alternateText.

Add a sample response of the API endpoint to the Response for initialization field, then click Start test call to initialise the API.

Response for initialization field

Adding the upload API to the image canvas​

To connect the upload API to the image canvas, go to the Content panel in the right panel, select the API you created for the file upload, and configure the parameters.

Upload API connected to image canvas

When you save a composition, the image with the drawings is sent to the API endpoint.

For further details on using APIs in forms, see API connectors. For authorisation handling, see Upload below.

Image map / Interactive image​

Image map lets clinicians select a part of a patient's body — or another predefined location — from clickable hot-areas on an image, rather than searching a dropdown. Areas are bound to specific values of a field, so the resulting composition is the same as with a standard dropdown presentation of coded text.

good to know

Interactive image presentation is available only for coded text and its generic counterpart.

Showing a field as an interactive image​

Place a coded text, ordinal, or scale field with predefined values on the canvas and go to the Design panel in the Property panel. Under Field, select Interactive image from the presentation dropdown.

Presentation dropdown showing Interactive image option

Once selected, an Interactive image properties section appears below the presentation dropdown and the field on the canvas changes to show "no image uploaded". Click Upload image to select an image from your file system. Once uploaded, the image appears on the canvas and the button changes to Change image.

warning

The uploaded image is not responsive due to technical limitations. Keep this in mind when choosing an image.

Adding interactive areas​

Under the hood, the interactive image uses the Image map concept. To create an image map, use the image map generator to define areas on your image, then copy the generated code.

To add the code to the interactive image:

  1. Click Add next to the Image map code label.
  2. Paste the copied code into the text box.
  3. Click Save.

Studio automatically transforms the code into areas on the image.

Binding interactive areas to the data model​

After adding the image map code, the canvas displays the image with shaped areas, and a mapping table appears in the Interactive image properties section. Each row represents an area; hovering over a row highlights the corresponding area on the image.

Each row must have a corresponding value. Select a value for each row from the dropdown. Rows without a value will not function correctly.

Area names appear as tooltips when the user moves the cursor over the area. You can rename areas for easier orientation or toggle Auto-define area title from field labels to automatically bind area names to field labels.

Choosing colours for areas​

  • Area colour: Changes the background colour of the area when selected.
  • Borderline: Changes the colour of the border. This colour does not change based on selection state.

Upload​

Upload is a field that allows users to upload files such as documents or images. It can be part of a template or added from the Generics tab.

Upload field

The Upload property panel exposes two independent tabs:

  • Upload — the API call that receives the file when the user adds it. Returns a response from which the form bindings extract the URI, media type, and alternate text stored on the field.
  • Download — the API call used when the user previews/downloads the attachment, and when an inline thumbnail is rendered for image attachments. Optional: if not configured, the renderer falls back to fetching the URI on the model directly, reusing the Upload API's authentication headers.

Upload and Download can point at different APIs — for example a write-only upload service plus a read-only CDN URL — but most setups use the same backend for both.

Setting up an upload API​

  1. In the left panel, go to API and create a new API connector. For example, name it "Upload API".
  2. Create a call named "Upload" with the POST method and enter the upload URL.
  3. Since POST is used, provide a Response for initialization so a test call can be made. For Better Store, you can use this example response:
{
"mimeType": "application/pdf",
"href": "https://store.better.care/rest/5d87731d-1782-4d6e-bcf4-820525503cbc",
"fileName": "summary.pdf",
"size": 39149,
"resourceId": "5d89951d-1782-4h6e-bcf4-821525503cbc"
}
  1. Set the body type (in this example, FORM_DATA) and add the required parameters: resource, mediaType, and alternateText.
  2. Click Start test call, then save the API connector.
  3. In the API call parameters, bind the form data fields using the Multimedia dropdown: bind resource to file, mediaType to fileType, and alternateText to fileName.
  4. Select the Upload field on the canvas, go to Content in the Property panel, find Upload, and select your upload API call from the dropdown.
  5. Bind the fields: uri to href, mediatype to mimeType, and alternatetext to fileName.

File substitution keywords​

Whatever the body type, the renderer substitutes three reserved keywords into the API call's parameters when uploading:

KeywordReplaced with
fileThe file itself — as a Blob for FORM_DATA, base64 string for JSON and X_WWW_FORM_URLENCODED
fileTypeThe file's MIME type (e.g. image/png)
fileNameThe original file name

Use these as the value of a dynamic param (for FORM_DATA / X_WWW_FORM_URLENCODED) or as the value of a <placeholder> referenced from the JSON body template (for JSON).

JSON body uploads​

If your upload endpoint expects a JSON document with the file content embedded as a base64 string, configure the API call as JSON body type and write a body template under Body using <placeholder> markers:

{
"attachment": {
"content": "<contentPlaceholder>",
"mimeType": "<mimePlaceholder>",
"filename": "<filenamePlaceholder>"
}
}

Then add dynamic params whose name matches each placeholder and whose value is the file keyword:

Dynamic param nameValue
contentPlaceholderfile
mimePlaceholderfileType
filenamePlaceholderfileName

At upload time, the renderer:

  1. Reads the JSON body template.
  2. Resolves each <placeholder> against the matching dynamic param.
  3. For the file keyword, base64-encodes the blob (no data: prefix); for fileType / fileName it substitutes the plain string; for any other value, the literal expression value.
  4. Sends the resulting JSON as the request body.

Other dynamic params can still reference normal form expressions (e.g. %EHR_ID%) alongside the file keywords in the same payload.

Setting up a download API​

Configure a Download API when:

  • The platform stores attachments behind an authenticated endpoint that needs the same headers as the upload (most common).
  • The download URL is derived from the stored URI but not identical to it (e.g. attachments stored on a separate service from where they were uploaded).
  • You need offline-mode support for previewing attachments later (see Offline mode).
  1. In the API panel, create or reuse a GET API call.
  2. Set Response type to blob so the response comes back as a binary Blob rather than parsed JSON.
  3. Use the reserved tokens in the URL template or path parameters when the request URL needs to encode the attachment URI. Example URL template: /attachments/{attachmentUri}.
  4. In the Upload field's property panel, switch to the Download tab and select the API call.

Reserved attachment tokens available in the Download API call URL and path parameters:

TokenReplaced with
{attachmentUri}The |uri value stored on the field
{attachmentMediaType}The |mediatype value
{attachmentAltText}The |alternatetext value

The tokens are substituted anywhere in the URL, including the query string. For example, when the stored |uri is already a complete URL and the server expects the media type as a query parameter, the URL template is simply:

{attachmentUri}?mediaType={attachmentMediaType}

The same Download API is used for inline image thumbnails and for the explicit preview/download button.

Handling authorisation​

When creating the upload or download API, add the appropriate authentication to the call:

  • Basic authentication: Username and password
  • Bearer authentication: Token
  • EHR platform credentials

The authentication headers are automatically appended to every request the renderer makes through that API call — uploads, downloads, and thumbnail fetches alike.

Upload, download, and offline mode​

Both Upload and Download API calls flow through the renderer's offline request-handler contract when the form runs with mode: 'offline':

User actionResource request emittedWhere to handle it
User adds a file to the fieldattachment-addedHost persists the binary; returns a synthesised response shaped like the field's upload bindings expect.
User previews or downloads the attachmentattachment-fetchHost returns the cached Blob for the resourceId.
Image attachment renders an inline thumbnailattachment-fetchSame — same handler serves the same Blob.

The resourceId on attachment-fetch equals the uploadId minted on attachment-added, so the offline handler can use it as a deterministic lookup key. See Offline mode → Handling attachments for an end-to-end example, including a reference implementation in apps/renderer-app/src/app/app.component.ts.

tip

If the Download API is not configured, the renderer falls back to a direct GET on the stored URI (with Upload API headers applied for auth). In offline mode this bypasses the request handler, so attachments cannot be previewed offline. Always configure a Download API when the form is intended to run offline.

Frequently asked questions (FAQs)​

What is the difference between a layout group and a container?

Layout groups support rows and columns and are used to change the layout of fields. Containers are used only for grouping fields together. Since version 3.2, containers no longer support rows or columns; containers that had their header hidden before that version were automatically converted to layout groups.

Can a generic input field be persistent?

Yes. When marked as persistent, a generic field's value is stored in the composition and reloaded whenever the composition is applied, even if the field is not part of the template model.

What presentation options are available for dropdown fields?

Combobox, checkbox, button group, and interactive image.

What is the difference between a column list and a stacked list?

A column list displays data in a table with rows and columns. A stacked list displays data in a single column with no header row.

What templating engine do rich text and HTML components use?

Both use the Mustache templating engine with the same tag syntax.

What field types support the interactive image presentation?

Interactive image presentation is available only for coded text and its generic counterpart.

What authentication methods are supported for the upload API?

Basic authentication (username and password), Bearer authentication (token), and EHR platform credentials.