Skip to main content

Setup Assistant

The setup assistant is a form you can build and use in XM Solutions to collect user input and customize a Solution accordingly.

If you would like to join the early access program for XM Solution Plugins, then please let us know by taking this survey.

Not generally available

This feature is in Early Access and is not yet generally available. Functionality, APIs, and documentation may change before general availability.

For example, maybe you want to let users of your Solution to choose whether they want to use a particular question or question block in the survey. A Setup Assistant can ask them that question, then your solution can remove that question or not depending on how the user answers the question.

Prerequisites​

Before starting, you should have some basic familiarity with XM Solutions by completing these pre-requisites:

How to access the Setup Assistant Creator​

Setup Assistant forms are made by using the Setup Assistant Creator.

To launch the Creator using the CLI, use this command:

solution editor --setupAssistant

Once you've launched the editor, you'll be asked to start from scratch or choose a file as your starting point. If you already have a setup assistant form, or you've started from a template that has one, you should upload your existing file. Otherwise, start from scratch.

The editor does not save your data.

You need to download your file when you're done working on it.

Using the Setup Assistant Creator​

To use the creator, you drag the things you'd like to use from the list on the left onto the canvas in the center. Once something has been added to the canvas, you can click the edit button to customize it.

Elements vs Questions vs Widgets​

The sidebar on the left has three types of things that you can drag onto the canvas. They are:

  1. Widgets
  2. Elements
  3. Questions

Widgets are information blocks that can be placed in the sidebar to the right of the canvas. Elements and Questions can be placed in the main canvas area. Elements are purely informational, and questions collect input from the end user.

Target variables and scope​

When you edit questions, you will be asked to provide the target variable and scope for that question. The target variable defines the variable name you will use to access the question answers later. The scope determines where the answer will be available to you. The scope options are:

  • Exported: The variable will be available on the Solution context. You can use it in any of the script elements in your XM Solution.
  • Form: The variable will be available to use in the display logic for all questions in the Setup Assistant.
  • Page: This option is the same as "Form", except the variable will only be available to questions on the same page.

If you've selected the "Exported" scope, you can access the variable in JavaScript by using

context.setup.answers.variableName

Display Logic​

Display logic can be added to questions, so they will only appear to the end user if the display logic conditions are met. This is useful for asking follow-up questions. For example, you could have a question asking if the user would like to include demographics questions in their survey. If they say yes, you could include more questions to see which demographics questions they would like to ask.

Repeating Groups​

Repeating group is a question unlike all the other questions. It will repeat a group of questions to the user. You can drag questions straight into the repeating group question on the canvas of the page. Repeating groups are useful if you want to ask the same questions about a series of items. For example, if you were running a product study. You could allow users to test as many products as they want by using a repeating group.

Including Setup Assistant in a Solution​

Once you're done editing your Setup Assistant form, you need to download it, put it in your plugin's src folder and put the file path in the Solution Execution file. The setup step is required for the Solution Execution file. It will look something like this:

{
"setup": {
"formFilePath": "path/to/your/file"
},
"steps": {
...
}
}

Types of Questions​

Here are some of the different types of questions that can be included in your solution. The different types will require different configuration options, so make sure you understand what type of question you require.

Text questions​

Text questions are questions where element.configuration.type is Text. Text questions prompt the user for typed input which can be configured to accept either alphabetic or numeric answers.

If element.configuration.options.numeric is false, the answer must be a string.

If element.configuration.options.maxLength is defined, the answer must have a character count of maxLength or less (even if element.configuration.options.numeric is true).

If element.configuration.options.numeric is true, the answer must be an int or a float.

If element.configuration.options.max and/or element.configuration.options.min is defined, the answer must be numeric and less than or equal to max and/or greater than or equal to min.

For example, consider the following Setup Assistant numeric text question:

{
"elementId": "textVariable",
"type": "question",
"configuration": {
"prompt": "Enter your answer",
"required": true,
"options": {
"numeric": true,
"multiline": false,
"placeholder": "",
"min": 100,
"max": 500,
"maxLength": 5
},
"type": "Text"
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"textVariable": 150
}
}
}

Similarly, consider the following Setup Assistant string text question. Note that the answer will require a string as its answer because element.configuration.options.numeric is false:

{
"elementId": "textVariable",
"type": "question",
"configuration": {
"type": "Text",
"prompt": "Enter your answer",
"required": true,
"options": {
"numeric": false,
"multiline": false,
"placeholder": "",
"maxLength": 15
}
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"textVariable": "Test Answer"
}
}
}

Checkbox questions​

Checkbox questions are questions where element.configuration.type is Checkbox. Checkbox questions prompt the user to check or uncheck a checkbox and must be a boolean value. If element.configuration.required is true, the answer must be true.

For example, consider the following Setup Assistant checkbox question:

{
"elementId": "checkVariable",
"type": "question",
"configuration": {
"prompt": "Check this",
"description": "",
"required": true,
"defaultValue": true,
"type": "Checkbox"
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"checkVariable": true
}
}
}

Multiple choice questions​

Multiple choice questions are questions where element.configuration.type is MultipleChoice. Multiple choice questions present the user with a question and some answers, and users can select some number of them depending on the configuration. An answer to a multiple choice question is an object where each key is a choiceId for an answer (found in element.configuration.options.choices) and the corresponding value is the boolean value that describes whether the answer has been selected.

If element.configuration.options.single is true, the answer can only have one choice marked as true.

If element.configuration.options.single is false, the answer can have multiple choices marked as true.

If element.configuration.options.max and/or element.configuration.options.min is defined, the number of choiceIds marked true must be less than or equal to max and/or greater than or equal to min.

For example, consider the following Setup Assistant single multiple choice question:

{
"elementId": "multiVariable",
"type": "question",
"configuration": {
"prompt": "Choose one of the following options",
"description": "Description",
"defaultValue": {
"option1": false,
"option2": false
},
"required": true,
"options": {
"single": true,
"choices": [
{
"choiceId": "option1",
"text": "Option 1"
},
{
"choiceId": "option2",
"text": "Option 2"
}
]
},
"type": "MultipleChoice"
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"multiVariable": {
"option1": true,
"option2": false
}
}
}
}

Similarly, consider the following Setup Assistant multi-select multiple choice question. Note that multiple true answers are allowed because element.configuration.options.single is false:

{
"elementId": "multiVariable",
"type": "question",
"configuration": {
"prompt": "Choose one of the following options",
"description": "Description",
"defaultValue": {
"option1": false,
"option2": false,
"option3": false
},
"required": true,
"options": {
"single": false,
"choices": [
{
"choiceId": "option1",
"text": "Option 1"
},
{
"choiceId": "option2",
"text": "Option 2"
},
{
"choiceId": "option3",
"text": "Option 3"
}
],
"min": 1,
"max": 2
},
"type": "MultipleChoice"
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"multiVariable": {
"option1": true,
"option2": false,
"option3": true
}
}
}
}

File upload questions​

File upload questions are questions where element.configuration.type is FileUpload. File upload questions ask the user to upload a file. The answer to a file upload question is metadata about the uploaded file including the filename, the uploadedId, the type, and the size in bytes.

The type of the answer should be a subtype of one of the types of element.configuration.options.accept. For example, image/png is a valid type if the question accepts image/*.

The uploadedId is a string id that should be of the form IM_ABCDEF123456789 for images or F_ABCDEF123456789 otherwise.

For example, consider the following Setup Assistant file upload question:

{
"elementId": "uploadVariable",
"type": "question",
"configuration": {
"required": true,
"prompt": "Upload a file",
"description": "Description",
"options": {
"accept": [
"audio/*",
"video/*",
"image/*"
]
},
"type": "FileUpload"
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"uploadVariable": {
"filename": "upload.png",
"uploadedId": "IM_ABCDEF123456789",
"type": "image/png",
"size": 228548
}
}
}
}

Constant sum questions​

Constant sum questions are questions where element.configuration.type is ConstantSum. Constant Sum questions prompt the user to enter values that must sum to a pre-configured value. An answer to a constant sum question is an object where the keys are TargetSum, ActualSum, and Items where Items is an object where the keys are the ids of items and the values are the values to be summed.

In the answer, the Items array must have at least two entries.

The sum of the values in the Items array must equal TargetSum.

The sum of the values in the Items array must equal ActualSum.

For example, consider the following Setup Assistant constant sum question:

{
"elementId": "sumVariable",
"type": "question",
"configuration": {
"type": "ConstantSum",
"prompt": "Enter your answer",
"description": "",
"required": true,
"options": {
"targetSum": 100,
"items": [
{
"itemId": "item1",
"text": "How much Item 1?"
},
{
"itemId": "item2",
"text": "How much Item 2?"
},
{
"itemId": "item3",
"text": "How much Item 3?"
}
]
}
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"sumVariable": {
"targetSum": 100,
"actualSum": 100,
"items": {
"item1": 20,
"item2": 35,
"item3": 45
}
}
}
}
}

Repeating group questions​

Repeating group questions are questions where element.configuration.type is RepeatingGroup. They contain a configured block of questions that can be repeated. Repeating group questions contain a child element called element.configuration.options.child which often contains a StaticGroup sub-question.

The static group question contains a repeated set of questions in element.configuration.options.child.configuration.options.children which is an array of questions of other types.

The answer to a repeating group question with a static group is an array of answers to questions in the static group where each answer is a key/value pair where the key is the elementId of a question in the static group and the value is a valid answer to that question.

For example, consider the following Setup Assistant repeating group question:

{
"elementId": "groupVariable",
"type": "question",
"configuration": {
"type": "RepeatingGroup",
"required": true,
"prompt": "What types of customer segments do you have?",
"description": "Describe each of the segments according to dimensions X,Y,Z.",
"defaultValue": [
{
"adName": "",
"adMessage": ""
}
],
"options": {
"child": {
"elementId": "SAC_C3iqHPVFI8NJL3",
"type": "question",
"configuration": {
"type": "StaticGroup",
"required": true,
"prompt": "",
"options": {
"children": [
{
"elementId": "adName",
"type": "question",
"configuration": {
"type": "Text",
"required": true,
"prompt": "Ad name",
"description": "",
"options": {
"numeric": false,
"multiline": false
}
}
},
{
"elementId": "adCheck",
"type": "question",
"configuration": {
"prompt": "Check this",
"description": "",
"required": false,
"defaultValue": true,
"type": "Checkbox"
}
}
]
}
}
}
}
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"groupVariable": [{
"adName": "Ad Name",
"adCheck": false
}]
}
}
}

Note that repeating text questions are actually special repeating group questions under the hood. These special repeating groups do not contain a static group. Instead, element.configuration.options.child.configuration.type specifies a question type.

For repeating text questions, this type is Text. The answer to this type of repeating group question is an array of valid answers that are not paired with elementIds as keys.

For example, consider the following repeating text question:

{
"elementId": "groupVariable",
"type": "question",
"configuration": {
"type": "RepeatingGroup",
"required": true,
"prompt": "What types of customer segments do you have?",
"description": "Describe each of the segments according to dimensions X,Y,Z.",
"defaultValue": [
"segment one is ...",
"segment 2 is ..."
],
"options": {
"child": {
"elementId": "SAC_MmxoSLIV7z_Phu",
"type": "question",
"configuration": {
"type": "Text",
"required": true
}
}
}
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"groupVariable": [
"text 1",
"text 2",
"text 3"
]
}
}
}

Resource selection questions​

Resource selection questions are questions where element.configuration.type is ResourceSelection. Resource selection questions ask the user to select a resource of a pre-configured type. The pre-configured type is defined by element.configuration.options.resourceType, and it can have any of the following values:

  • credentials
  • directorysegments
  • folder
  • messagelibrary
  • program
  • survey
  • surveyquestions
  • workspace
  • xmdcontactlist
  • xmdirectory
  • zone

Some resource types, need to have a parent resource defined in element.configuration.options.resourceFilterData. The parent resource must be in an array field with an arbitrary name (we will use filterName) with the parent resource's answer ID in it. Said parent resource is used as a filter.

For example:

  • For surveyquestions, there must exist a survey resource selection question before it, and the survey resource selection question should be referenced in the resourceFilterData object of the surveyquestions question (as shown in the example below). This parent-child relationship ensures that the survey questions displayed in the selector will come from the survey selected in the previous question.

  • The same applies to directorysegments with xmdcontactlist because, as the name suggests, we're essentially grabbing a segment from the directory selected in the xmdcontactlist question.

A setup file in which the surveyquestions resource type is used in a resource selection question could look like the following:

{
"elements": [
{
"elementId": "selectedResourceeNDUGxy",
"type": "question",
"configuration": {
"prompt": "Select a survey",
"description": "",
"required": false,
"options": {
"resourceType": "survey"
},
"type": "ResourceSelection"
}
},
{
"elementId": "selectedResource",
"type": "question",
"configuration": {
"prompt": "Select a survey question",
"description": "",
"required": false,
"options": {
"resourceType": "surveyquestions",
"resourceFilterData": {
"filterName": [
"answers.selectedResourceeNDUGxy.primaryId"
]
}
},
"type": "ResourceSelection"
}
}
]
}

Some other resource types can use filters, defined exactly how parent resources are defined except, of course, the filterName is different.

The survey resource type can use the url.programId filter name to filter surveys by program. When the filter is applied, the selector displays all the surveys that are in the given program and all of the surveys that are not in any program. To use this filter properly you have to set the filter program ID as a query parameter programId=YOUR_PROGRAM_ID in your Setup Assistant session URL.

Not all resource types support filtering

The surveyquestions and directorysegments resource types require a parent resource to be defined in their setup file and are therefore automatically filtered by it.

For now, only the survey resource type can use the optional url.programId filter.

The answer to a resource selection question is an object containing displayText of the choice the user made and at least the primaryId of the answer, but can include a secondaryId and/or tertiaryId as well.

In the case when the resource type survey uses url.programId as filter, secondaryId is set to the program ID used as filter and tertiaryId can either be inProgram or an empty string "" depending on whether the selected survey is in the filter program or not.

For example, consider the following Setup Assistant resource selection question:

{
{
"elementId": "selectedResource",
"type": "question",
"configuration": {
"prompt": "Select a survey",
"description": "",
"required": true,
"options": {
"resourceType": "survey",
"resourceFilterData": {
"filterName": [
"url.programId"
]
}
},
"type": "ResourceSelection"
}
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"selectedResource": {
"displayText": "My Survey",
"primaryId": "SV_1234",
"secondaryId": "PROG_5678",
"tertiaryId": ""
}
}
}
}
warning
Testing a resource selection question of resource type survey and filter url.programId

When running solution generate-test -r to retrieve your test file, make sure to add the secondaryId and tertiaryId fields to the resource selection question's answer in your test file with the values

you want to test.

When running solution generate-test make sure to include the programId=YOUR_PROGRAM_ID query parameter in the Setup Assistant session URL that was created for you to input the answers.

If however, we had a resource selection question of resource type survey that didn't use url.programId as filter, the answer object would only have "displayText" and primaryId as fields. This is true for almost any other resource type.

{
"setup": {
"answers": {
"selectedResource": {
"displayText": "My Survey",
"primaryId": "SV_1234"
}
}
}
}

Topic selection questions​

Topic selection questions are questions where element.configuration.type is TopicSelection. Topic selection questions prompt the user to choose topics and items from within topics.An answer to a topic selection question is an object containing objects for each topic.

Each topic contains a boolean selected field which describes whether that topic has been selected and an items object which contains key/value pairs where each key is an itemId and each value is a boolean values that describe whether the item is selected.

If element.configuration.options.maxTopics and/or element.configuration.options.minTopics is defined, the number of topics where selected is true must be less than or equal to maxTopics and/or greater than or equal to minTopics.

If a topic's selected field in its answer is false, none of its items can be true.

If an item's alwaysSelected field in its question is true, that same item must be true in the answer.

If a topic's selected field in its answer is true and that topic's maxItems/minItems are defined in the question, the number of true items beneath that topic in the answer must be less than or equal to maxItems and/or greater than or equal to minItems.

For example, consider the following Setup Assistant topic selection question:

{
"elementId": "selectedTopics",
"type": "question",
"configuration": {
"required": true,
"prompt": "Choose which topics and questions you would like to include",
"description": "All questions have been written by experts and are multiple choice.",
"options": {
"topics": [
{
"_uid": "SAC_X4R7u0z3P_hxlr",
"id": "authorityEmpowerment",
"title": "Authority and Empowerment",
"description": "This topic aims to gauge to what degree employees feel authority and empowerment to do their jobs.",
"items": []
},
{
"_uid": "SAC_EeYijOWB5cG2Ea",
"id": "collaboration",
"title": "Collaboration",
"description": "This topic aims to gauge to what degree employees feel collaboration plays a role in their jobs.",
"minItems": 1,
"maxItems": 2,
"items": [
{
"_uid": "SAC_6mgie01MZZuNKt",
"id": "coworkers",
"title": "Collaboration with Coworkers",
"description": "These questions aim to measure collaboration between employees and their coworkers",
"alwaysSelected": true
},
{
"_uid": "SAC_Uo54qqF6B8OtN6",
"id": "vendors",
"title": "Collaboration with Vendors",
"description": "These questions aim to measure collaboration between employees and vendors"
}
]
}
],
"minTopics": 1,
"maxTopics": 2
},
"defaultValue": {
"authorityEmpowerment": {
"selected": false,
"items": {}
},
"collaboration": {
"selected": true,
"items": {
"coworkers": true,
"vendors": false
}
}
},
"type": "TopicSelection"
}
}

The following would be a valid answer:

{
"setup": {
"answers": {
"selectedTopics": {
"authorityEmpowerment": {
"selected": false,
"items": {}
},
"collaboration": {
"selected": true,
"items": {
"coworkers": true,
"vendors": false,
"management": true
}
}
}
}
}
}

It is required to reach 100% branch coverage with your test files for validation. That means every step in your Solution Execution file must be included in validation at least once. You may need several test files that provide different Setup Assistant answers in order to get this coverage.

It's easy to rename your test file and make a new one using the solution generate-test command again. If different user inputs drastically change how resources are built, then you should make multiple test files even if it is not a separate branch in your Solution Execution file.

This assures that every major branch of your Solution has some amount of test coverage, but it does NOT guarantee that your Solution is free of errors.

Understanding Setup Assistant forms​

Your test Setup Assistant answers should go in setup.answers in your test file. The answers object contains key/value pairs where each key is the elementId of a question in your Setup Assistant file and the value is a valid answer to that question:

{
"setup": {
"answers": {
"elementId1": "answer1",
"elementId2": {
"someAnswerField": "answer2"
},
"elementId3": [
"answer3a",
"answer3b",
"answer3c"
],
"etc": "etc..."
}
}
}

Each question type's answer has a specific shape and sometimes multiple shapes depending on the question's configuration, so consult the list below to build a valid answer for each question. In the following sections, element will refer to one of the question objects in the elements array which will be in the pages array of your Setup Assistant file.

If element.configuration.required is true, then answers must have a valid answer for that question.