Add Dynamic Lists to Forms

The Dynamic List form element runs a script to retrieve items from an external source to populate a drop-down form list at request time. The scripts, which can be written in the language of your choice, can use values of other form elements to build dynamic lists of values with relevant content. Using variables, the scripts can access additional information such as the requester's user name or email address. Dynamic List form elements can be added to the service-level form of a new service request (see Create New Service Requests), to the component-level form when you add components to a service catalog entry (see Catalog), or to change requests (see Create Change Requests).

Dynamic lists allow you to maintain real-time values for any frequently changing form options. Using an external system’s API, dynamic lists can retrieve lists such as:

  • Available organizations to join.
  • Cost centers that are accessible to a user.
  • Database types and the appropriate versions for each database type.
  • All subnets in the destination selected on the form.

Use variables in dynamic list scripts

Some Commander variables can reference other form elements and some Commander variables can reference other information. See Script examples of dynamic list usage.

The maximum length of variable values is 1000 character, and dynamic list variables can't have costs associated with them.

  • In any text field that supports variables, you can click to open the script editor and select variables for the current context.
  • The script won't execute until all variables have a value. If the form contains a blank list, one or more variables may have trouble resolving. To fix this issue, check the Commander log file for the following message: Dynamic list [name] can't resolve variables: [variable names]; then provide access to the missing variables.

Access:

Configuration > Self-Service > Forms

Available to:

Commander Roles of Superuser and Enterprise Admin

To configure a script for the Dynamic List form element:

  1. In the Toolbox section on the right, click Dynamic List.
  2. In the Dynamic List form element, click the Configure link to edit and test the script before publishing it.
  3. In the Edit Script dialog, enter any arguments that you want to pass to the script executable in the Script Arguments field.

    The maximum length is 2048 characters.

  4. In the Script field, enter the script to be run.

    The result must be a JSON string array.

  5. In the Executable field, enter the executable that will run the script.

    If your system environment doesn't have the script executable on its path, you must provide the fully qualified path to it (for example, C:\python37\python.exe). To use PowerShell, you only need to enter powershell.exe.

    Some scripting executables require files with a specific file extensions. Commander already has mappings for the following common executables: powershell.exe=.ps1, python.exe=.py, cmd.exe=.bat. However, if you are using other executable that require specific file extensions, you must map the executable and file extension in the advanced system property embotics.workflow.embedded.script.extensions. For more information, see Set system properties in Commander for details on how to modify system properties through Commander.

  6. Optional: In the optional Credentials field, select or add guest OS credentials that are required to run the script. See Manage Credentials.

    The credential contents are populated into environment variables that the script can access.

  7. Optional: In the Timeout field, adjust the amount of time that you want the script to complete by before it will time out and fail. The maximum value is 99 seconds.
  8. Optional: In the Fallback Value field, enter a value that will be used if the script fails.
  9. Optional: Test your script. See Test dynamic list scripts.

    The script output has a maximum limit as defined in the advanced system property embotics.execute.command.task.capture.length, which is 512 KB by default.

  10. Click OK.
  • If some lists contain content that's dependent on the selections made in other form elements, arrange the lists in the form in the order of their dependence, top to bottom. When requesters work top down on the form, their choices may affect the contents of subsequent lists. If requesters go back and make changes, they may lose some of their selections.
  • You can't create two lists that reference each other.

Test dynamic list scripts

Use the Test tab of the Edit Script dialog to see the output of your script. If your script contains Commander variables, you can specify the values of each variable in the script and view the results. If there are no variables in your script, the Variable/Value section won't appear in the Test tab of the Edit Script dialog. See Script examples of dynamic list usage.

Script status is recorded in the Commander log file. A successful script exit code is 0. Any other exit code means that the script has failed. Details of script failures are displayed in the Test tab result field.

If the script fails during deployment, users will see a generic failure alert, but details of the failure won't be exposed to users. Users will be directed to contact their administrator.

Script examples of dynamic list usage

Below are two examples that show how to use dynamic lists.

Example 1: List that depends on another list

The following script retrieves a list of Canadian provinces. The results will be used in the second list. Both dynamic list elements are added in sequence to the form.

$headers = @{Accept = "application/json" }
$Data = Invoke-RestMethod -Method Get -Uri "http://geogratis.gc.ca/services/geoname/en/codes/province" -Headers $headers
ConvertTo-Json @(($Data.definitions)|Select -ExpandProperty description)

Dynamic List Edit Script to display provinces

Running this script in the Test tab shows the list of provinces that will be visible to users.

Dynamic List Test Script to display provinces

The script below retrieves the selected province from the list above and inserts it into the variable target.settings.dynamicList['Province']. This script is added to a new Dynamic List form element. From this information, the script produces a list of cities relevant to that province.

$headers = @{Accept = "application/json" }	
$Data = Invoke-RestMethod -Method Get -Uri "http://geogratis.gc.ca/services/geoname/en/codes/province" -Headers $headers
$Provinceid = $Data.definitions | Where-Object {$_.description -eq "#{target.settings.dynamicList['Province']}"} | Select-object code -ExpandProperty code
$CityData = Invoke-RestMethod -Method Get -Uri "http://geogratis.gc.ca/services/geoname/en/geonames?province=$Provinceid&concise=CITY" -Headers $headers

$result = @()

if ($CityData.items.Length > 1) {
   $result += $CityData.items |Select -ExpandProperty name 
} else {
   $result = $CityData.items |Select -ExpandProperty name
}

ConvertTo-Json @($result)

Dynamic List Edit Script to display cities

Running this script in the Test tab shows the list of cities that will be visible to users when they select the province Ontario. Using this Test tab, you can change the value of the variables in the script, run the script, and see the appropriate output.

Dynamic List Test Script to display cities

In the Service Catalog, the two lists will be available for selection: a list of provinces and a list of cities for the province that was selected in the first list.

Example 2: List that includes credentials to an API request

This is an example of how a script that can be used for a dynamic list form element can retrieve the username and password from the credentials. The credentials selected in the Edit Script dialog are injected into the script's environment variables. This sample script accesses Commander metadata to get a list of services.

$user = (Get-Item Env:SELECTED_CREDENTIALS_USERNAME).value;
$pass= (Get-Item Env:SELECTED_CREDENTIALS_PASSWORD).value;
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($user, $secpasswd)
$headers = @{Accept = "application/json" }
$Data = Invoke-RestMethod -Method Get -cred $cred -Uri "https://#{system.address}:#{system.port}/rest/v3/services" -Headers $headers
ConvertTo-Json @($Data.items |Select -ExpandProperty name)