Configure Dynamic Selective Lists
This article shows how to apply Dynamic Selective Lists (DynSL) in UBIK®.
The goal is to provide a property on the mobile client, for which the user can select a value from a dynamic list: a list where the available items depend on another property value.
Throughout this tutorial, you will learn how to set up
- a new Dynamic Selective List (DynSL)
- selective items for the DynSL
- a target property using the DynSL
- a dependency property ultimately deciding the items of the DynSL for a specific target
- a criterion for choosing the items depending on a dependency property value
Getting these configurations to the mobile client is a critical part as well.
Also, the technical background is explained, so you can understand what's going on in case of unexpected behavior.
Preconditions: We assume you're familiar with MetaClasses, Classifications, and Abstract Content Management (ACM). In other words, you should be capable of creating a small mobile app with UBIK® before you start with this tutorial. Also, please read the Offline Query article, since this technique is used for Dynamic Selective Lists. |
Contents
- 1 Goal 1: Create a new Dynamic Selective List
- 2 Goal 2: Create items for the Dynamic Selective List
- 3 Goal 3: Use the Dynamic Selective List on a target Meta Property
- 4 Goal 4: Define a dependency property
- 5 Goal 5: Add a criterion to connect the dots
- 6 Releasing the ACM meta definitions
- 7 Test
- 8 Bonus: Multi-value criterion
- 9 More possibilities
- 10 Known issue workaround: Not ignoring NULL criteria doesn't work
- 11 See also
Goal 1: Create a new Dynamic Selective List
Basic definition
First, we'll define the dynamic selective list without specifying any details.
- Create a new MetaClass deriving from the Query meta class. We'll call this new meta class "MC_DYN_SL".
- Assign the Dynamic Selective List Classification to it.
- Create a new instance of this new meta class. In this tutorial, we shall be referring to it by the name of "DynSL".
There will be more to do so the DynSL actually works later, but we'll come to that when it is time.
Getting it to the mobile client
Next, we want to make sure the mobile client receives your DynSL.
- Create a new query scope instance for the DynSL. Let's call it "QCS_DYN_SL" for example.
- Assign the DynSL instance to the new query scope by dragging the DynSL instance onto the "QUERY" field of the scope instance.
- Add the Offline Query Classification to the scope.
- Add the Dynamic Selective List Classification to your scope as well.
- Add the "QCS_DYN_SL" to the scope list of your ACM context.
- Add the "DynSL" instance to the infrastructure list of your ACM context.
Goal 2: Create items for the Dynamic Selective List
Basic definition
For our DynSL, we also need items that can be selected on the target property. We'll define them now, without specifying details yet.
- Create a meta class "MC_DYN_SL_ITEM", deriving from "NAMEDBASECLASS", so it has meta properties for name and description.
- For all possible values your dynamic selective list should provide, create an instance. For example, we could name them "Hugo", "Denise", and "Bob".
We'll have to add more data to our items, but we'll do that later.
Getting them to the mobile client
Now, let's ship the items to the mobile client.
- Create a meta class scope "MCS_DYN_SL_ITEM" for the item meta class ("MC_DYN_SL_ITEM").
- Add the scope to the list of all scopes of your ACM context.
- Also, add all items ("Denise", "Bob", and "Hugo") to the infrastructure list of your ACM context. You may use a query for that, of course.
Goal 3: Use the Dynamic Selective List on a target Meta Property
Basic definition
Again, the first step will be to define the model and data.
- Create a meta class "MC_WITH_DYN_SL" containing a meta property "LNK_WITH_DYN_SL".
- Make sure the meta property has the property type "Guid", meaning it can link to another object (i.e., a dynamic selective item).
- Create an instance of "MC_WITH_DYN_SL". It shall be called "InstanceWithDynSL".
Getting it to the mobile client
This is the part where we tell the client that the DynSL should be used for our link property.
- First, we need a scope for our target object. Create a meta class scope "MCS_WITH_DYN_SL".
- Add the scope to the list of all scopes of your ACM context.
- Also add the "LNK_WITH_DYN_SL" meta property to the scope.
- Make that scoped meta property editable (lock status "writable" and visibility "visible").
- Now we assign the DynSL: Set the "FilterQuery" property of the scoped meta property to "QCS_DYN_SL", which is the query scope we created earlier for our DynSL.
- The instance ("InstanceWithDynSL") must also be available on the client, somewhere in the content hierarchy. We'll deal with that later.
Goal 4: Define a dependency property
If we want a dynamic set of options to select from, we also need a dependency telling us which options should be available. In our example, "Bob", "Denise", and "Hugo" are all options. But let's say, as an arbitrary example, for our target object "InstanceWithDynSL", only "Denise" and "Bob" should be selectable values of the property "LNK_WITH_DYN_SL".
In any case, we require somebody to blame for this decision. After all, "Hugo" could feel left out and send a complaint to management, so we better have a scapegoat. The goal of this section is to create something so we can justify why "Denise" and "Bob" can be possible values, but "Hugo" isn't. Also, for the DynSL to work, the mobile client requires this information as well.
Our line of argumentation will be: the department has a specific requirement for items to be selectable, so the department rules are the reason only "Denise" and "Bob" are qualified.
Basic definition
- First, we need a new meta class "MC_DEPARTMENT".
- Add a meta property "MP_REQUIREMENT" to the scapegoat class.
- You can use any property type for that, but we'll just stick to "String" for this example.
- Now let's create a specific department with concrete qualification requirements: Create an instance "Department Alpha", because that sounds cool and important.
- "Department Alpha" has the highest standards for its items, so please enter the value "A" for the property "MP_REQUIREMENT" of "Department Alpha". We'll imagine "A" stands for "Security clearance level 'Angel'". But this is top secret.
Now we have to assign a security clearance level to our items. We want "Denise" and "Bob" to have security clearance "A", but "Hugo" should just have clearance "B".
- This means we require a new meta property "MP_SECURITY_CLEARANCE" on our item meta class! Add such a meta property to "MC_DYN_SL_ITEM".
- After you've added the new meta property, we can open the items in a bulk editor and enter the value "A" for "Bob" and "Denise", and "B" for "Hugo".
Getting it to the mobile client
- Since our items have gained a security clearance now, we also have to send it to the client. Add the new meta property to the scope "MCS_DYN_SL_ITEM".
- Of course, we also want to have our department on the client. Also, the department should be a root object, and our test object "InstanceWithDynSL" should be below that department in the content hierarchy on the client. We trust you know how to achieve this!
- The department scope "MCS_DEPARTMENT" should also have the new meta property "MP_REQUIREMENT" as a scoped meta property.
So now, we've created a dependency property telling us why some of our items can be selected and some of them can't. But something's still missing. We'll get to that in a moment.
The dependency object specifying the value influencing the selectable items must be either the target object (the one with the DynSL property), or anywhere above it in the hierarchy. |
Goal 5: Add a criterion to connect the dots
We know why "Denise" and "Bob" can be selected for "InstanceWithDynSL". They have the right security clearance after all, which is required by the department "Department Alpha", which is the department above "InstanceWithDynSL". But we haven't documented that yet! And if it's illegible, it doesn't exist. Quick, let's define this rule before "Hugo" gets to file a complaint. In order for the DynSL to be evaluated correctly on the client, we need to make this logical connection processible anyway.
Basic definition
What we need, is a so-called Dynamic Selective List Criterion. It links the department's requirement to the security clearance of our items, in a way the mobile client understands it.
- Create a new meta class "MC_DYN_SL_CRITERION".
- Add the Dynamic Selective List Criterion Classification to it and implement all the meta properties it requires.
- Now create an instance of the criterion meta class. We'll call it "SecurityClearanceCriterion".
- Now open the bulk editor for our new meta class so we can configure the details of our criterion:
- Set the DYNAMIC_SELECTIVE_LIST property to our "DynSL".
- Set the IS_MULTI_VALUE_STRING to False for now.
- The DEPENDENCY_CLASS should be our "MC_DEPARTMENT".
- The DEPENDENCY_PROPERTY_NAME is "MP_REQUIREMENT".
- QUERY_CRITERION_NAME should be set to "MP_SECURITY_CLEARANCE".
- IGNORE_NULL can be set to False for now.
Getting it to the mobile client
Now that we have documented our security clearance criterion, we just have to tell the client.
- For this purpose, create a meta class scope "MCS_DYN_SL_CRITERION" for the meta class "MC_DYN_SL_CRITERION".
- Add the Dynamic Selective List Criterion Classification to the scope.
- All the meta properties described above should also be added to the scope.
- Add the scope to the list of all scopes of your ACM context.
- Add the criterion instance ("SecurityClearanceCriterion") to the list of infrastructure objects.
- Add the meta property "MP_SECURITY_CLEARANCE" to the DynSL scope "QCS_DYN_SL". The reason for this is, that the DynSL is an offline query and requires a property to contain the criterion value. This value is resolved using the DynSL criterion.
A criterion property (like "MP_SECURITY_CLEARANCE" in our example) on the Dynamic Selective Items also has to appear on the Dynamic Selective List scope, because technically, an offline query is used in the background. It's recommended to read the details about Offline Queries to understand this. |
Releasing the ACM meta definitions
Now that we have configured everything, the ACM meta definitions can be released and the web service can be restarted.
Test
Connect the mobile client to the web service you're using and log in. We want to see a root object "Department Alpha" and below it, the "InstanceWithDynSL". On the latter, you should be able to edit the property "LNK_WITH_DYN_SL". A selection dialog should appear, suggesting "Denise" and "Bob", but not "Hugo".
Bonus: Multi-value criterion
In our example, it turns out "Hugo" has connections to the top level management. He talks them into lowering the security clearance of "Department Alpha" to "B", hence allowing him to be on the team. But since "A" is higher than "B", "Denise" and "Bob" should also be cleared for access. How do we include both of them?
This can be done in two steps:
- Change the security clearance requirement ("MP_REQUIREMENT") of "Department Alpha" to "A;B".
- Change the IS_MULTI_VALUE_STRING property of the "SecurityClearanceCriterion" to True.
Now, after releasing the ACM meta definitions and restarting the web service, all items with security clearance levels "A" and "B" are possible choices and all of them should appear when editing "InstanceWithDynSL"'s property "LNK_WITH_DYN_SL".
More possibilities
You can configure Dynamic Selective Lists to allow much more complex scenarios. For example, you can remove the restriction for the dependency class on the criterion. You can define the target object as the dependency object, too, so it depends on a different property of itself. You can even specify multiple criteria, potentially with different dependency objects. It is also possible to define multiple properties with dynamic selective lists depending on each other successively.
Known issue workaround: Not ignoring NULL criteria doesn't work
One of the features of DynSL is to specify a criterion with the dependency value NULL that should only yield items with the criterion property value NULL (instead of just yielding every result). This can be achieved by setting the criterion's "IGNORE_NULL" property to False and the dependency property value to NULL.
Or rather, it should be achieved that way; there is a bug on the WinX client in version 4, which basically always ignores null values no matter the criterion configuration. Fortunately, there's a workaround:
If you override the dependency property in customizing programmatically, so it always returns any value definitely never occurring "in the wild" instead of NULL, and do the same for the item's criterion property, you achieve the desired result. We're working on fixing the bug, but in the meantime this should help you work around it.
var val = base.MY_PROPERTY;
return val ?? "NULL"; // this is the same as as saying, 'If the value is not null, use it. Else, use whatever I wrote after the "??" operator'
Why does this work? Currently, the client handles NULL values differently than regular values (ignoring them, basically). However, with the above code you're changing a NULL into a regular value, so there's no extra behavior.