UI Command Protocol

Dialob client user interface is controlled using action-based protocol between client (browser) and server (Dialob runtime). Both REST and WebSocket transports are supported with the same action protocol. REST transport is working in request-response style while WebSocket transport also supports server initiated UI updates.

Client initiates connection to Dialob filling session by opening WebSocket connection to session's socket URL or doing a GET request to session's REST URL. Server responds to that with first message. Further client -> server messages can then be sent over WebSocket connection or with POST request to session URL to which server responds with next message and so on.

Message protocol is using JSON format.

UI State

A client implementing Dialob protocol, needs to keep track of following state during session:

  • Items by ID
  • Valuesets by ID
  • Session state revision token

Items

Items are building blocks for Dialob user interface. Every item has an unique identifier and type. Items may have a list of sub-item ID-s. Items are organized in hierarchy:

Questionnaire(1) --> Page(0..n) --> Group(0..n) --> Question(0..n)

Top level item is a questionnaire that defines the title, page structure and allowed actions. There is always exactly one questionnaire item present in session.

Page item defines group structure.

Group is logical grouping item for questions.

Question is an item having user interaction.

Value sets

Value sets are lists of possible values used by selection-type questions and survey groups. One value set can be shared between several items. Value sets have unique identifier and a list of entries. Values are have key and value, where key is the answer stored in session and value is for display.

Session state revision token

Session state revision tokens are used to keep track of user interaction sequence and ensure that no messages have been lost in transit. Every message sent by server has nextRev token attached. UI needs to keep track of this value and use it for sending the response message. Server sends back previous token value as prevRev (omitted from first server message).

Message

Actions are encapsulated in a message structure. A message has following attributes:

  • nextRev -- Session state revision token for current revision. Only used for messages coming from server.
  • prevRev -- Session state revision token for previous revison. Omitted from first message coming from server.
  • actions -- An array of zero or more actions.

General message object structure

{
  "nextRev": "0002",
  "prevRev": "0001",
  "actions": []
}

Action

Actions are used to communicate user interaction commands from client to server and UI change commands from server to client. One message can contain zero or more actions.

Every action has type attribute defining the type of the action. The rest of attributes, if any, are dependent on the action type.

General action object structure

{
  "type": "NEW_QUESTION",
  ... payload ...
}

Actions from server to client

Action: REMOVE_ALL

On reception of this action, client is expected to clear its internal state of all items and value sets and remove all items from the UI. This action is typically sent as first action for full state dump, such as first message to client.

{
  "type": "REMOVE_ALL"
}

Action: NEW_QUESTION

Server sends a new item for client to display. It has question attribute as a payload that defines the item's properties. Every item has an unique identifier id and a type type. The rest of the attributes are dependent on item's type, please refer to "Handling of item types" below.

{
  "type": "NEW_QUESTION",
  "question": {
    "id": "question1",
    "type": "text",
    "label": "A label",
    ...
  }
}

Action: UPDATE_QUESTION

Server requests an update to an item. It has question attribute as a payload that defines the item's properties. Every item has an unique identifier id and a type type. The rest of the attributes are dependent on item's type, please refer to "Handling of item types" below.

{
  "type": "UPDATE_QUESTION",
  "question": {
    "id": "question1",
    "type": "text",
    "label": "A label",
    ...
  }
}

Action: ANSWER_QUESTION

Server requests an update to an item's answer. It has questionId attribute for target item and answer attribute with the value to set.

{
  "type": "ANSWER_QUESTION",
  "questionId": "question1",
  "answer": "Some value"
  }
}

Action: REMOVE_QUESTION

Server requests to remove an item from UI state. It has questionId attribute for target item.

{
  "type": "REMOVE_QUESTION",
  "questionId": "question1"
  }
}

Action: NEW_ERROR

Server sets an validation error for an item. Action has an 'error' object payload with following attributes: id target item ID, description error message to display. One item may have more than one validation error active at once.

{
  "type": "NEW_ERROR",
    "error": {
      "id": "question1",
      "description": "An error message"
    }
  }
}

Action: REMOVE_ERROR

Server requests an validation error to be removed for an item. Action has an 'error' object payload with following attributes: id target item ID, description error message. Matching should be done using description attribute.

{
  "type": "REMOVE_ERROR",
    "error": {
      "id": "question1",
      "description": "An error message"
    }
  }
}

Action: NEW_VALUE_SET

Defines a value set used by choice-based questions. It has id attribute for identifying the value set, items refer to this. entries is an array of key - value pairs, where key is the key of the entry and value its display label.

{
  "type": "NEW_VALUE_SET",
  "id": "valueSet1",
  "entries": [
    {
      "key": "a",
      "value": "First option"
    },
    ....
  ]
}

Action: UPDATE_VALUE_SET

Updates a value set, see NEW_VALUE_SET for details.

{
  "type": "UPDATE_VALUE_SET",
  "id": "valueSet1",
  "entries": [
    {
      "key": "a",
      "value": "First option"
    },
    ....
  ]
}

Action: REMOVE_VALUE_SET

Server requests a value set to be removed from client's UI state. Items referring to this value set lose their options. id is the identifier of the value set to be removed.

{
  "type": "UPDATE_VALUE_SET",
  "id": "valueSet1"
}

Action: ADD_ROWS

Note No handling needed as this action will be deprecated in future versions.

Action: COMPLETE_QUESTIONNAIRE

Server confirms successful completion of the session. Also this action is sent by server if connection is opened to a session that is already completed. questionnaireId contains session identifier.

{
  "type": "COMPLETE_QUESTIONNAIRE",
  "questionnaireId": "e58befaf6b15c6bc304ff10ae000b328"
}

Action: WILL_PASSIVATE

Server indicates that current session will be passivated to conserve resources. Next message sent from client to server will re-activate the session.

Note No handling needed as this action will be deprecated in future versions.

{
  "type": "WILL_PASSIVATE",
  "questionnaireId": "e58befaf6b15c6bc304ff10ae000b328"
}

Action: ACTIVATED

Server indicates that a passivated session was re-activated.

Note No handling needed as this action will be deprecated in future versions.

{
  "type": "ACTIVATED",
  "questionnaireId": "e58befaf6b15c6bc304ff10ae000b328"
}

Action: NOTIFY_SERVER_ERROR

Notifies about server error. This usually indicates a misconfiguration or programming issue and it shouldn't happen in normal circumstances. It is up to client how to display this for user. The session should be ended as it might be unreliable.

{
  "type": "NOTIFY_SERVER_ERROR"
}

Actions from client to server

Action: ANSWER_QUESTION

This action must be sent to backend for every user action answering a question. To enable live input validation for entry fields, it could be sent for every keypress. questionId is the item ID answered, answer is the value.

{
  "type": "ANSWER_QUESTION",
  "questionId": "question1",
  "answer": "Some value"
}

Action: NEXT_PAGE

User wishes to navigate to next page. No additional attributes.

{
  "type": "NEXT_PAGE"
}

Action: PREVIOUS_PAGE

User wishes to navigate to previous page. No additional attributes.

{
  "type": "PREVIOUS_PAGE"
}

Action: GOTO_PAGE

User wishes to navigate to a specific page. page is the identifier for the target page item.

{
  "type": "GOTO_PAGE",
  "page": "page2"
}

Action: COMPLETE_QUESTIONNAIRE

User wishes to complete (submit) the session. No additional attributes.

{
  "type": "COMPLETE_QUESTIONNAIRE"
}

Action: ADD_ROW

User wishes to add a new row to a multi-row group. id is the identifier for the target multi-row group.

{
  "type": "ADD_ROW",
  "id": "group1"
}

Action: DELETE_ROW

User wishes to delete a row from a multi-row group. id is the identifier for the multi row group row.

{
  "type": "DELETE_ROW",
  "id": "group1[1]"
}

Handling of different question types

General item structure used for all items is as follows:

{
  "id": "question1",
  "type": "group",
  "label": "Time",
  "description": "Item description",
  "className": ["styleClass1", "styleClass2"],
  "answered": true
  ...
}

Mandatory attributes are:

  • id - Unique identifier of the item
  • type - Type of the item
  • label - Display label of the item
  • answered - true if the item (question) is answered

Optional attributes for all item types:

  • className - an array of user-entered "style class" names
  • description - markdown text for longer description of the item
  • value - current value (answer) of the question, in case answered=true

Other attributes are depending on the item type

Item type: questionnaire

For every session there is exactly one item of questionnaire type. It should be considered as a root item from which the UI rendering should get started.

Attributes

  • items - array of page item IDs, in that order, that are defined for this questionnaire
  • activeItem - ID of the currently active page item
  • availableItems - array of page item ID's that can be navigated to
  • allowedActions - array of action types that are accepted by server at this moment. Should be used to render navigation elements in UI
{
  "id": "questionnaire",
  "label": "Example dialog",
  "type": "questionnaire",
  "className": [],
  "items": ["page1"],
  "activeItem": "page1",
  "availableItems": ["page1"],
  "allowedActions": ["ANSWER_QUESTION"],
  "answered": false
}

Item type: group

A normal item group or a page. If this is referenced from items list from questionnaire item, it should be considered as a page, otherwise it is a guestion group.

A group referenced by items of a rowgroup is a row within that multi-row group.

Attributes

  • items - array of item IDs, in that order, contained withing this group

Special case If this group has a className of survey then this group is considered a "Survey Group". This group has also a valueSetId attribute pointing to a value set that has defined common options for all survey questions contained within this group.

An example of a group or page

{
  "id": "group1",
  "label": "Question group",
  "description": "Question group description\n",
  "type": "group",
  "className": [],
  "items": ["question1", "question2"],
  "answered": false
}

An example of a survey group

{
  "id": "group3",
  "label": "Survey group",
  "type": "group",
  "className": ["survey"],
  "items": ["question8", "question9", "question10"],
  "answered": false,
  "valueSetId": "group3_valueset1_valueSet"
}

Item type: rowgroup

A group that can contain several rows of questions.

Attributes

  • items - array of zero ro more item IDs, in order, pointing to group items for rows.
{
  "id": "group2",
  "label": "Multi-row group",
  "type": "rowgroup",
  "className": [],
  "items": ["group2[1]"],
  "answered": false
}

Item type: text

A text entry field. Should be rendered as a single line text input box.

Special case: textbox If textbox is defined as one of the className items, it should be rendered as a multi-line text box. Could be rich text.

Special case: choice If text question has valueSetId attribute defined, it should be rendered as a single selection, for example, a dropdown.

Special case: survey If survey is defined as one of the className items, it should be rendered as a radio-selection of items defined in enclosing survey-group's value set.

Answer format is "string"

A single-line text entry

{
  "id": "question1",
  "label": "A text question",
  "type": "text",
  "className": [],
  "answered": false
}

A multi-line text entry

{
  "id": "question1",
  "label": "A text box question",
  "type": "text",
  "className": ["textbox"],
  "answered": false
}

Single choice question

{
  "id": "question1",
  "label": "A single choice question",
  "type": "text",
  "className": [],
  "valueSetId": "question1_valueset1_valueSet",
  "answered": false
}

Survey choice question

{
  "id": "question8",
  "label": "First question",
  "type": "text",
  "className": ["survey"],
  "answered": false
}

Item type: number

Integer entry field, positive or negative

Ansewer format is an integer: 0

{
  "id": "question1",
  "label": "An integer question",
  "type": "number",
  "className": [],
  "answered": false
}

Item type: decimal

Decimal entry field, positive or negative

Ansewer format is decimal: -6.5

{
  "id": "question1",
  "label": "A decimal question",
  "type": "decimal",
  "className": [],
  "answered": false
}

Item type: boolean

A boolean flag question. Could be rendered as a checkbox. It should be made clear for user between non-answered and false states.

Answer format is boolean: true or false

A single-line integer entry

{
  "id": "question1",
  "label": "A boolean question",
  "type": "boolean",
  "className": [],
  "answered": false
}

Item type: date

Date entry field. Could be rendered as a date picker.

Answer format is YYYY-MM-DD "2016-12-25"

{
  "id": "question1",
  "label": "A date question",
  "type": "date",
  "className": [],
  "answered": false
}

Item type: time

Time entry field. Could be rendered as a time picker.

Answer format is HH:MM "11:34"

{
  "id": "question1",
  "label": "A time question",
  "type": "time",
  "className": [],
  "answered": false
}

Item type: array

Multi-choice field. User can select multiple options from a value set.

Answer format is an array of strings ["option1", "option2"]

{
  "id": "question1",
  "label": "A multi-choice",
  "type": "array",
  "className": [],
  "valueSetId": "question1_valueset1_valueSet",
  "answered": false
}

Item type: note

A read-only note field. Its label should be rendered as markdown text.

results matching ""

    No results matching ""