Dependent Selector Configurations
Last updated
Last updated
The last article explained how to make a dynamic configuration, a setting where the options are fetched from an API or database so they change from tenant to tenant
This article will explain how to make a dependent selector configuration, a setting where the options are fetched from an API or data base and vary based on the user's selection of an earlier config (which can also be dynamic)
A tenant settings page that allows the the user select their favorite food.
The options for the favorite food will be fetched from an API or database, so they will be different from tenant to tenant.
There will also be a food type configuration.
The user's selection for food type will also affect what options are presented to the user when they are selecting their favorite food.
The food type config is also dynamic, so the food type options will vary from tenant to tenant.
Tenant A: food type options will be Sweet and Savory.
If the user chooses food type Sweet then the favorite food options will be: Chocolate, Caramel, Jello
If the user chooses food type Savory then the favorite food options will be: Chips, Pizza, Bread
Tenant B: food type options will be Fruits and Veggies.
If the user chooses food type Fruits then the favorite food options will be: Strawberry, Banana, Kiwi
If the user chooses food type Veggies then the favorite food options will be: Carrot, Broccoli, Pepper
Create the parent selector: This is the dynamic configuration whose selected value determines the options available for the dependent selector.
In this example the parent selector is the food_type
.
Here is a quick review on how to set up a dynamic configuration:
Like other dynamic configurations, the schema
property for this must have a reference to a list of options in the schema
's definitions
.
In this example the food_type
schema property must have a reference to food_type_options
.
Like other dynamic configurations, the schema needs to have a definitions section with an entry that has the options for the parent selector.
In this example the schema
definitions
must include a list of food_type_options
.
Like a normal configuration, the uischema
elements
section must have an entry for the parent selector.
In this example there must be a uischema element with type: control
and scope: '#/properties/food_type'
Like other dynamic configurations, the integration's code must have an init sync which fetches the tenant specific options for the parent selector and prints them to the standard out.
Its value must be an array of objects, each of which has a const
and title
property. The const
will be the ID of that option, and the title
will be the name of the option.
In this example the standard out of an init sync must include food_type_options
It could look like this: food_type_options = [
{'const': 1, 'title': 'Fruits'},
{'const': 2, 'title': 'Veggies'},
]
It could look like this: food_type_options = [
{'const': 3, 'title': 'Sweet'},
{'const': 4, 'title': 'Savory'},
]
Create a dependent selector: This is the configuration whose options will depend on the parent selector and the values fetched from a database/API.
In this example the dependent selector is favorite_food
.
Here is how a dependent selector is set up:
Like a normal configuration, the schema
property for this must have a type
. The type
for a dependent selector should be string
.
Like other dynamic configurations, the schema
needs to have a definitions
section with an entry that has the options for the dependent selector. It's type should be object
.
In this example the schema
definitions
must include a list of food_options
.
Like a normal configuration, the uischema
elements
section must have an entry for the dependent selector. However a dependent selector's uischema
element has some additional requirements:
Its type
must be DependentSelectControl
.
It must have an options
property which includes:
dependentMappingsScope
: This must reference the schema definition that has the options for the dependent selector.
In this example it will be '#/definitions/food_options'
.
parentScope
: This must reference the schema property for the parent selector which controls the options that will be present.
In this example it will be '#/properties/food_type'
Like other dynamic configurations, the integration's code must have an init sync which fetches the tenant specific options for the dependent selector and prints them to the standard out.
It's value must be a map of the option type IDs (from the parent selector) to a list of the options for that type.
All the options for every list must be either entirely string
or entirely oneOf
(an objects with a title
and const
)
In this example each option for every list will be a string
.
In this example the standard out of an init sync must include food_options
It could look like this food_options = {
1: ['Strawberry', 'Banana', 'Kiwi'],
2: ['Carrot', 'Broccoli', 'Pepper']
}
It could look like this food_options = {
3: ['Chocolate', 'Caramel', 'Jello'],
4: ['Chips', 'Pizza', 'Bread'],
}
The configs section of the PANDIUM.yaml would include this:
A TypeScript implementation of the init sync of the integration in could look like this:
This example has a static parent selector and the options for the dependent selector will be oneOf
rather than string
.
The configs section of the PANDIUM.yaml would include this:
A TypeScript implementation of the init sync of this integration in could look like this: