Skip to main content

Introduction to content types

iCL allows you to quickly create powerful checklists to gather information on various things. In many cases, you will want to track those "things" as separate data. For example, when doing building inspections, it is advisable to store all the data of a building in a separate table. Then, whenever that building is inspected, you can use its data to pre-fill parts of your checklists.

Buildings, fire fighting equipment, elevator types, customer information, ... in iCL these can be modeled with content types.

  1. General content types may represent anything that exists in the real world. From objects that are inspected like elevators, machines or entire buildings, to any supplemental information that should be stored separately to inspections so it can be reused, like contact information, a list of customers and so on.

  2. Defect content types have the same basic feature set as normal content types. In addition, they define the object that they belong to (we call it "parent") and the state they are currently in (like: open, in progress, resolved). The parent can be any basic content type, although it makes much more sense to have a defect on a building than a customer, obviously.

Defining a content type​

A content type defines

  • the fields that it stores (name, address, building year, ...)
  • the relationships to other content types (e.g. an elevator belongs to a building)
  • the form to edit its data
  • advanced rules regarding how it is synchronized and more.

This *.json file will then be uploaded to the iCL Portal and also imported to the iWorkbook via the iCL Designer.


Note that currently defining a content type is not an easy task and therefore should be done by somebody with software development skills!

1 The required attributes​

There are several parameters, which have to be set before creating the fields themselves.

"$type":"contentType"Defines the type of this json file as content type.
"name":"lowercase_name"Defines the name for the database. Only lower case and _ for spaces allowed.
"displayName":"What suits you the most"Defines the Title of the Content Type for the iCL Portal and the iCL Filler.
"canBeInspected":trueIf this content type should be inspectable using a workbook, set "canBeInspected": true
"builtinTypeId":6In case you want to create a content type to collect defects, specify 6, otherwise 0. These content types will be shown in the defects-section of the iCL Filler inspection.
"titleFieldName":"the_name_of_an_existing_field"Defines, which field shall be displayed, when selecting a content item or viewing the defects-list.
"icon":""Defines the displayed icon in the iCL Filler content item list.
"fields":[] see topic belowDoes contain all fields, which shall be shown as columns on the iCL Portal.
"relationships":[] see topic belowCreates a connection to another content item.
"formTemplate":{} see topic belowThis parameter will be automatically generated, if it is left empty, but certain field types have to be defined there manually. More information about this you can find in the following chapters.
"id":2f4fa47a-faba-4748-bb80-a37e1040b1e8Defines a identifier for the iCL Portal database. Every content type has to be unique in this regard. You can use this free online GUID generator
"version":1The version of that content type.

Example for an inspectable content type:

"$type": "contentType",
"name": "building",
"displayName": "Building",
"canBeInspected": true,
"titleFieldName": "building_number",
"fields": [],
"relationships": [],
"formTemplate": {},
"id": "12345678-abcd-1a2b-3c4d-1234567890",
"version": 1

Example for a defect content type:

"$type": "contentType",
"name": "defect",
"displayName": "Defect",
"builtinTypeId": 6,
"titleFieldName": "title",
"fields": [],
"relationships": [],
"formTemplate": {},
"id": "87654321-dcba-b2a1-d4c3-0123456789",
"version": 1

2. The title field​

Every content type must have a title field. This field then has multiple special roles:

A) Whenever there is the need to show a short information about a particular content item, the value of the title field is displayed​

Therefore, the title field should contain human readable information helping the end user to identify a particular item or understand what it is.

In the case of a building, you may prefer the unique building number e.g. "bldng 2019-02-18 001288" In case of a content type "contact_person" which contains information about a contact person of a given customer, you may choose the full name of the contact (e.g. 'Robert Petterson')

To understand where this information is displayed, let us assume the following scenario:

  • You design a content type "customer"

  • It has a relation to another content type "contact_person" (i.e. lets the user specify the contact person for a given customer)

  • The content field for storing the "customer"s "contact_person" is called "customer_contact" with the display name "Contact"

    • Portal: The create/edit/delete form of "customer" will allow you to choose a "contact_person" and display the value of its title field in the form itself as well as the drop down selection control.
    • Portal: The data grid "customer" will have a column "Contact" (the display name of the field "customer_contact") also showing the value of that items title field
    • Filler: When the app lists all known items of "contact_person" for the user to select one (e.g. a checklist has a content field that allows to choose a "contact_person", or the inspection requires the user to select a "contact_person" prior to starting the inspection), the value of the "contact_person" title field is shown in the list.
    • Filler: When a checklist has a content field that is filled with a "contact_person" item, its title field is be displayed in the checklist.
    • Reporting: When a checklist has a content field that is filled with a "contact_person" item, its title field is be displayed in the report just as it is in the checklist
  • Portal: When the user opens the drop down in order to select an item, (s)he can type some text in order to filter that potentially long list
  • Filler: When the list of items is shown, the user selects a content item prior to starting an inspection or when filling in a content item field in a checklist, (s)he, again, can type some search expression in order to filter that potentially long list.

This also applies when the user scans a QR code in order to search for a particular item.

The title field can be defined in two ways:

  1. specifying a titleFieldName,
  2. or using the titleFieldExpression.

2.1 Specifying the title using a titleFieldName​

When specifying a titleFieldName, you have to choose the name of a required content field that is of type ShortText. This is for the aforementioned two reasons (A) and (B)

  • If it wasn't short text, it would have a negative impact on search
  • If it wasn't required, users could leave it blank resulting in e.g. blank items being shown in a selector control for that content type.

Specifying a titleFieldName is required anyways. If a titleFieldExpression is also defined, it takes precendence over the titleFieldName

2.2 Specifying the title field using titleFieldExpression​

Sometimes, a single field is not sufficient in order to create an indexable and easy-to-read title for a given content item. For example, the "building" content type might not have an easily readable building number like "B 2019-02-18 001288", but instead spread this information across multiple fields:

  • The field 'construction_date' with the value 2019-02-18
  • The field 'idx_number' with the value 001288

For such occasions, you can use the titleFieldExpression. It allows you to specify an expression that is evaluated dynamically every time a content item is created or edited and may combine multiple fields. To achieve a building number like above ("B 2019-02-18 001288"), you may use the following expression: B <%construction_date%> <%idx_number%>

"$type": "contentType",
"name": "building",
"displayName": "Building",
"canBeInspected": true,
"titleFieldName": "building_number",
"titleFieldExpression": "B <%construction_date%> <%idx_number%>",
"icon": "",
"fields": [],
"relationships": [],
"formTemplate": {},
"id": "12345678-abcd-1a2b-3c4d-1234567890",
"version": 1

Note, that the titleFieldExpression is optional and a titleFieldName is still required to remain compatible with older versions of our software. It behaves the following way:

  • If a content type has a titleFieldExpression, it is favored over the titleFieldName evaluated to determine the items title whenever it is created or edited.
  • You can use any field that is defined by that content type to put together the title, not only fields of type ShortText
  • If one of the fields you use does not exist or has no value, or if there was any error evaluating its value, it will be replaced with empty text.

For example, if you mistype construction_date as cnstructiondate in the expression (B <%cnstructiondate%> <%idx_number%>), the result would be "B 001288"

  • While you will most of the time just use simple place holders to create your title field (e.g. <%confirmation_date%>), you can actually specify a JavaScript expression. For example, let's assume that the field <%construction_date%> is of type Date, then the construction_date will actually hold an EcmaScript 5 date object

Thus, you can do something fancy like this: <% construction_date.toLocaleDateString("de-DE, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }") %> which would result in "Montag, 18. Februar 2019"

  • While you are free to define any expression you want, note that the resulting string will be truncated in case it is longer than 200 characters!

2. Content fields​

By defining the (content) fields of a content type, you can specify what data is actually stored.


The order of the fields set in the *.json file will be the order of the columns of the content types data grid in iCL Portal.

A content field can specifiy the following attributes

ParameterValue SchemeDescriptionMandatory Field
"$type":"contentField"Every column has to be defined as contentField. Relationships will be defined as contentRelationship.x
"type":"ShortText","Boolean","Number",...specifies the type of data that this field can hold. Default is ShortText. See field types table
"name":"test"The internal field name for the database. Has to be lower case.x
"displayName":"Test 123"The displayed column title of the field.x
"isRequired":true / falseA boolean value which determines, if the field must have a value or not.
"isIndexed":true / falseA boolean value which determines, if a search index should be created for this field.
"builtInField":either one of ExternalId,ParentContentItemId,StatusThis allows for setting internal fields of iCL.
indexed fields

As all content types are stored in a SQL database, you can and should use indexes to speed up search queries. As indexing every possible column would make updates of content items slower, you should only index fields that are actually used for searching.

The iCL Portal, however, is smart and will automagically index certain fields for you:

  • the title field
  • the externalid field
  • any field that is used in a relationship

2.1 Field Types​

The following field types exist

"ShortText"200 characters
"LongText"4 294 967 295 characters
"Number"-2147483648 - 2147483647
"Boolean"false, true
"Guid"Globally Unique Identifier.
"ContentItem"Allows to store ids of other content items to referenece them - similar to a SQL foreign key
"FileEntry"Allows a content type to store files such as images. E.g: 90e0ef39-74c2-4f6d-b78a-6e1a76303112
"User"⏳for future use
"Plan"Allows to store a plan (file). For more information, read the guide on plans.
"PlanLocation"Allows to store the location on a plan as a POINT(x y) or a POLYGON((x1 y1,x2 y2,x3 y3,...)). For more information, read the guide on plans.


"$type": "contentField",
"type": "Number",
"name": "price",
"displayName": "Price",

3. Relationships​

Content types can relate to other content types. For example, an elevator may belong to a building, so this relationship can be configured. This later allows to synchronize hierarchies of objects.

  "relationships": [
"$type": "contentRelationship",
"name": "building",
"displayName": "The building",
"foreignKeyField": "buildingid",
"targetContentType": {
"$type": "contentTypeRef",
"id": "98589aab-1b51-40d9-9a4b-9430859e7b8e",
"version": 1
"$type":"contentRelationship"Defines the connection to another content type.
"name":"building"relates to the field, where the connected content type will be shown in.
"displayName":"The building"
"foreignKeyField":"buildingid"The name of the (external) field, which shall be linked in the specified field
"$type":"contentTypeRef"Use always this value.
"id":"98589aab-1b51-40d9-9a4b-9430859e7b8e"The id of the content type, you are referring to - may also be the own content type id, if you are referring just to another field.
"version":1The version of that content type.
Defects and ParentContentItemId

For defects, a special relationship is recommended: Every defect belongs to a specific object. In iCL, this is implemented using the BuiltInField ParentContentItemId Defects must define this mapping. That way, whenever their parent object is synchronized to a user's device, the defect will be sent along with it. For this, they need to specify a content field

"$type": "contentField",
"type": "ContentItem",
"name": "parent",
"displayName": "The parent object",

4. Form Template​

For every content type, a form template is needed for showing and editing its data. This template is automatically generated based on the defined content fields when uploading the .json file to the iCL Portal.

You can change the form template by

  • specifying a form field for every content type field
  • or by just specifying those fields that should be different.

In the latter case, iCL Portal will automatically detect that some fields are missing and will add them on-the-fly.

For example, if a field shall be a dropdown, the form template parameter "$type": "options" can be set. This dropdown values have to be specified below the definition. Here is an example of an option-type field:

"$type": "options",
"name": "personal",
"properties": {
"title": "Personal"
"available values": [
"$type": "value",
"name": "nopersonal",
"value": 0,
"properties": {
"title": "No"
"$type": "value",
"name": "yespersonal",
"value": 1,
"properties": {
"title": "Yes"
"$type": "value",
"name": "finishedpersonal",
"value": 10,
"properties": {
"title": "Finished (hidden)"

The following table will explain the details of the values fields:

"$type":"value"This Parameter will define the section as a value-field-block.
"name":"databasename"Defines the name for the database. Only lower case and _ for spaces allowed.
"value":0, 1, 2, ...the positon number in the dropdown list.
"title""How it looks like"The title of that section - this part will be displayed in the dropdown list.

Keep in mind, that value 10 is always used for a value to hide an entry.

use iCL Designer to define a custom form template

Technically, form templates are stored in the same *.json format as checklists of a workbook. Therefore, you can use iCL Designer to create a new "checklist" and configure the fields as required. After storing the workbook, open it with a ZIP tool and search for the .json file in iclx\forms

5. List Item Template​

List item templates allow you to customise how the content items are displayed in iCL Filler.

By default, each item has the same height and the title of the items can have a maximum of 3 lines.

However, you can customise these attributes using the listItemTemplate.

"$type": "listItem",
"type": "default",
"dynamicHeight": true,
"maxLines": 5
"type":"default"The name of the template.
"dynamicHeight":true/falseSpecifies whether the items should have same height or their height should be adjusted individually. False by default.
"maxLines"1, 2, 3, ...The maximum number of lines allowed in the title of the content item. Maximum 10 lines are allowed. Default: 3.