Work-around for “ALL” Conflict of Multi-select List Box in SAP Design Studio
In a dashboard on an iPad, it is common requirement to have of a multi-select List box that has an “ALL” option included as part of the values. However, in a dashboard on an iPad, when we click on “ALL” and then click other options (or vice versa), we experience a “CONFLICT”. That has been explained in detail as “NATIVE FUNCTIONALITY” below.
In this document, I will explain the possible workaround to achieve a solution for this conflicting scenario with the help of ‘FILTER’ functionality.
Scenario:
We use a List Box with list of States and using the List Box selections, the Cities in the selected States are filtered and displayed on a Crosstab. The List Box is Multi-Selection enabled and it also has “ALL” selection in its list.
Native Functionality:
- When “ALL” is selected first and then another State is selected – ‘FILTER’ is applied for “ALL” (showing ALL the Cities in Crosstab), but in the List Box both “ALL” and the selected State remain selected.
- When multiple States are selected and then “ALL” is selected – ‘FILTER’ is applied for “ALL” (showing ALL the Cities in Crosstab), but in the List Box both “ALL” and the selected States remain selected.
Note that for both a) and b), the outcome is the same after the selections are made.
Native Functionality of List Box with Multiple Selection
Expected Functionality after the workaround:
- When “ALL” is selected first and then another State is selected – “ALL” will be deselected and only the selected State will be retained. Now, the Filter for the Selected State is applied on the Target Datasource, showing only the Cities of the selected State in the Crosstab.
- When multiple States are selected and then “ALL” is selected – previously selected States will be deselected and only the “ALL” selection is retained. Now, the Filter for the State is cleared, showing all the Cities in the Crosstab.
Steps for Workaround:
Step 1: Create a Global Variable of type String – Previous_Selection to store the Internal key of the previously selected member of the List Box. Also, assign it’s Default Value as “(ALL_MEMBERS)”, since for the first selection, the previous selection is assumed to be “ALL”.
Step 2: In the “On Startup” event, get all the members of the State dimension and load it to the List Box along with “ALL” option enabled as shown below.
Step 3: In the “On Select” event of the List Box, type the following code:
var Current_Selection = LISTBOX_STATE.getSelectedValue();
if (Current_Selection == “(ALL_MEMBERS)” && Current_Selection == Previous_Selection && LISTBOX_STATE.getSelectedValues().length != 1) {
var Multi_Selections = LISTBOX_STATE.getSelectedValues();
var Selection_Without_ALL = “”;
Multi_Selections.forEach(function(element, index) {
if (element != “(ALL_MEMBERS)” ) {
Selection_Without_ALL = element ;
}
});
LISTBOX_STATE.setSelectedValue(Selection_Without_ALL);
DS_1.setFilter(“ZR_STOKY__ZR_STKEY”, Selection_Without_ALL);
Previous_Selection = Selection_Without_ALL;
}
else if ( (Current_Selection == “(ALL_MEMBERS)” && Current_Selection!=Previous_Selection) || Current_Selection== “” ) {
LISTBOX_STATE.setSelectedValue(“(ALL_MEMBERS)”);
DS_1.setFilter(“ZR_STOKY__ZR_STKEY”, “(ALL_MEMBERS)”);
if (Current_Selection == “”) {
Previous_Selection == “(ALL_MEMBERS)”;
}
else {
Previous_Selection = Current_Selection ;
}
}
else {
DS_1.setFilter(“ZR_STOKY__ZR_STKEY”, LISTBOX_STATE.getSelectedValues());
Previous_Selection = Current_Selection ;
}
Explanation for the Code above:
When Multiple Selection of the List Box is enabled and multiple selections are selected, LISTBOX.getSelectedValue gives the Key of the Top most selected member in the List Box’s listing arrangement, irrespective of when it was selected. So, when “ALL” option is selected at any time – whether in the beginning or after many selections are made, LISTBOX.getSelectedValue will only give “(ALL_MEMBERS)” because of the reason that “ALL” is always the Top most option in the List Box’s listing arrangement.
So, after every selection is made on the List Box, the Top most selected member’s Key is stored in a local variable – Current_Selection.
Similarly, in the previous set of selected members, the key of the Top most selected member is assigned to the global variable – Previous_Selection. Initially, the Previous_Selection is assumed to be “ALL”.
Now, using the Previous_Selection and Current_Selection, three condition are specified, they are:
Condition 1: When Current_Selection and the Previous_Selection are “ALL” and if more than one selections have been made.
If Condition 1 is true, then it means that “ALL” is selected at first and then the other selections are made.
Execution for ‘Condition 1 is true’: Deselect “ALL” and select the other previous selected members, and then apply filter for State with the selected members, other than “ALL”.
Condition 2: When Current_Selection and the Previous_Selection are not the same, if Current_Selection is either “ALL” or “”. ( “” means there are no members selected. This is returned when only one value is first selected and then deselected in the followed selection )
If Condition 2 is true, then it means that “ALL” is selected after a number of selections are made or after all members are deselected.
Execution for ‘Condition 2 is true’: Select “ALL” and deselect the other previous selected members, and then clear the filter for State as “ALL” is selected.
Condition 3: If the above two conditions are not satisfied.
If Condition 3 is true, then it means that “ALL” has not been selected at all (in the current selection as well as in the previous selection made).
Execution for ‘Condition 3 is true’: Retain the selection of the selected members and then apply the filter for State with the selected members.
Note: When “(ALL_MEMBERS)” is passed as the Set Filter Value for the State, it is equal to clearing the filter for State.
I had framed this workaround using LISTBOX.getSelectedValue for multiple selection of members. This will be very efficient when the functionality is implemented on an iPad compatible dashboard. More workarounds for the same “CONFLICT” can be developed and there is no guarantee that my workaround is the most efficient of all. But one good thing about this is that, this is so easy to incorporate with any data on any dashboard without making lot of changes to the actual code.
Your solution helped me in confirming that there is no standard way to unselect a selected item in the listbox. I have a similar requirement and had a similar solution in my mind as a workaround. Thanks for your blog.
Aneeque
Hi Experts,
I came across this blog which I found helpul. This is exactly what I was looking for and it answered all my quest regards listbox multiple selection.
I applied it to my dashboard where I am using 3 listboxes. However, it is working and also gives an error with API setSelectedValue is not working.
Does this work around with binding filter properties? I tried to implement it with binding properties on listbox without set items on startup. Because I added ALL on the properties panel.
Please correct me where I’m going wrong. Can I use this with binding properties on listbox?
Thanks,