I was a bit surprised to find that dropdowns and listboxs do not work with Universe Data Sources the same way they do with BW Data Sources.
While there are solutions out there to implement cascades with your selections, they either involve creating your own with the SDK or using a trick with multiple data sources. The multiple data source solution works just fine, but it adds more data sources when most of us are trying to reduce the number of data calls we have.
I created a lightweight solution that uses a single global script to parse out an array of concatenated cascade values to listboxes. The script is called on start and on change events and it allows for multiple selections from any list. It requires you have access to your universe and can create a dimension.
For this writeup, I am using a 3 tiered cascade of Region -> Country -> City.
@Select(Office\Region) || '|' || @Select(Office\Country) || '|' || @Select(Office\City)
This should output a string of Region|Country|City separated by a pipe character.
//Assign concatenated list to array variable
var arraymembers = DS_1.getMembers("<city_hier_concat>", 250);
//Initialize string variables to hold each member once concatenated list is parsed out
var LB1_ELEMENT = "";
var LB2_ELEMENT = "";
var LB3_ELEMENT = "";
//Depending on entry point, clear and set default to *All text (null value) for lists
if (pLB == 0) {
LB1.removeAllItems();
LB2.removeAllItems();
LB3.removeAllItems();
LB1.addItem("", "*All");
LB2.addItem("", "*All");
LB3.addItem("", "*All");
LB1.setSelectedValue("");
LB2.setSelectedValue("");
LB3.setSelectedValue("");
}
else if (pLB == 1) {
LB2.removeAllItems();
LB3.removeAllItems();
LB2.addItem("", "*All");
LB3.addItem("", "*All");
LB2.setSelectedValue("");
LB3.setSelectedValue("");
}
else if (pLB == 2) {
LB3.removeAllItems();
LB3.addItem("", "*All");
LB3.setSelectedValue("");
}
//Get selected values from lists and assign to variables
var LB1SELECT = LB1.getSelectedValues();
var LB2SELECT = LB2.getSelectedValues();
var LB3SELECT = LB3.getSelectedValues();
//Loop through concatenated list, split out members and assign to element variables
arraymembers.forEach(function (a , index) {
var elementsplit = a.text.split("|");
var x = 0;
elementsplit.forEach(function (b , index) {
if (x == 0) {
LB1_ELEMENT = b;
x = x + 1;
}
else if (x == 1) {
LB2_ELEMENT = b;
x = x + 1;
}
else if (x == 2) {
LB3_ELEMENT = b;
x = 0;
}
});
//Depending on entry point, check to see if elements match selection or if *All is selected (null value)
//if matched, assign child members to appropriate listbox
if (pLB == 0) {
LB1.addItem(LB1_ELEMENT, LB1_ELEMENT);
LB2.addItem(LB2_ELEMENT, LB2_ELEMENT);
LB3.addItem(LB3_ELEMENT, LB3_ELEMENT);
}
else if (pLB == 1) {
LB1SELECT.forEach(function (c , index) {
if (LB1_ELEMENT == c || c == "") {
LB2.addItem(LB2_ELEMENT, LB2_ELEMENT);
LB3.addItem(LB3_ELEMENT, LB3_ELEMENT);
}
});
}
else if (pLB == 2) {
LB2SELECT.forEach(function (d , index) {
if (LB2_ELEMENT == d) {
LB3.addItem(LB3_ELEMENT, LB3_ELEMENT);
}
if (d == "") {
LB1SELECT.forEach(function (c , index) {
if (LB1_ELEMENT == c || c == "") {
LB2.addItem(LB2_ELEMENT, LB2_ELEMENT);
LB3.addItem(LB3_ELEMENT, LB3_ELEMENT);
}
});
}
});
}
});
//Sort Results
LB1.sort();
LB2.sort();
LB3.sort();
//Set appropriate filters to selected elements.
//Since *All texts are set to null values, selecting *All will essentially clear that filter.
DS_1.setFilter("<region>", LB1SELECT);
DS_1.setFilter("<country>", LB2SELECT);
DS_1.setFilter("<city>", LB3SELECT);
That's it!
I am sure the script can be improved upon. I may add input field searches to the lists as well.
There are some caveats and notes:
Good luck and Happy Cascading! Feedback, suggestions, improvements are always welcome, and I will update accordingly.
Chad
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
11 | |
10 | |
7 | |
6 | |
4 | |
4 | |
3 | |
3 | |
3 | |
3 |