cancel
Showing results for 
Search instead for 
Did you mean: 

Fiori List Report: Multi-value filter displayed as colour-coded checkboxes?

PetraMi
Explorer
0 Kudos
180

Hello fellow Fiori developers,

My List Report app has a filter bar with a multi-value field for status, with 3 possible values. By default it comes up as a multi-value dropdown box. I would like to have it rendered as 3 colour-coded checkboxes, like in this standard app:

PetraMi_0-1733740282898.png

 

PetraMi_1-1733740304589.png

Thanks for your valuable input!

 

View Entire Topic
PetraMi
Explorer

 

 

 

 

 

 

After some browser debugging of the original application I found the way. I used Guided development / Add a custom filter to the filter bar and adjusted the code snippets. (Sidenote: if the project already contains extensions, I would advise against letting Guided Development updating the controllers or manifest.json. It can overwrite stuff, place updates in wrong places and cause syntax errors. I copied bits of proposed snippets and adjusted the files manually)

1. The elements for the checkboxes: one sap.m.FlexBox with 3 sap.m.CheckBox. For each CheckBox use property valueState to set the desired colour:

 

 

 

        <FlexBox id="_IDFlexBox1">
            <CheckBox id="Red" valueState="Error"/>
            <CheckBox id="Yellow" valueState="Warning"/>
            <CheckBox id="Green" valueState="Success"/>
        </FlexBox>

 

 

 

2. These should be placed in a new fragment file, representing the custom control on the smart filter bar. Full fragment code:

 

 

 

<core:FragmentDefinition xmlns="sap.m" xmlns:smartfilterbar="sap.ui.comp.smartfilterbar" xmlns:core="sap.ui.core">
<smartfilterbar:ControlConfiguration id="_IDGenControlConfiguration" groupId="_BASIC" 
    key="_keyStatusCB"
    label="Status"
    visibleInAdvancedArea="true">
    <smartfilterbar:customControl>
        <FlexBox id="_IDFlexBox1">
            <CheckBox id="Red" valueState="Error"/>
            <CheckBox id="Yellow" valueState="Warning"/>
            <CheckBox id="Green" valueState="Success"/>
        </FlexBox>
    </smartfilterbar:customControl>
</smartfilterbar:ControlConfiguration>
</core:FragmentDefinition>

 

 

 

The fragment file should be placed in the 'webapp/ext'/fragments' folder and have extension .fragment.xml. In my example, I let the Guided development create the file and place it appropriately, then I modified the customControl, from using the proposed ComboBox to my FlexBox. Result:

PetraMi_0-1733918120398.png

3. The fragment should be added to smart filter bar provided by the List Report floorplan, by adding this bit to the manifest (replace yourEntitySet with the name of the main entity set on the List Report page, and yourproject with the name of your project in SAP BAS):

 

 

 

....
                    "sap.suite.ui.generic.template.ListReport.view.ListReport": {
                        "SmartFilterBarControlConfigurationExtension|yourEntitySet": {
                            "className": "sap.ui.core.Fragment",
                            "fragmentName": "yourproject.ext.fragments.StatusCB",
                            "type": "XML"
                        }
                    }

 

 

 

At this point the checkboxes should be visible on the filterbar and you should be able to check and uncheck them. But there will be no effect on the filtering yet, since they are not linked to any of the oData entity properties.

4. Link the checkbox elements with the property of the entity set to which the filtering should apply. In my case, the property is 'Criticality', and it may have values 1, 2, or 3, representing statuses 'Overdue', 'In progress' and 'Completed' respectively. The expected filtering is: show overdue items only if red box is checked, completed items only if green is checked etc.

I let the Guided Dev generate the file and then replaced the proposed logic for ComboBox in event onBeforeRebindTableExtension with logic appropriate for FlexBox and Checkbox. There are still multiple references to ComboBox but it now works for me:

 

 

 

sap.ui.define([
    "sap/m/MessageToast",
    "sap/ui/model/Filter",
    "sap/ui/comp/smartfilterbar/SmartFilterBar",
    "sap/m/ComboBox"
], function(MessageToast,Filter, SmartFilterBar, ComboBox) {
    'use strict';

    return {

        getCustomAppStateDataExtension: function (oCustomData) {
            //the content of the custom field will be stored in the app state, so that it can be restored later, for example after a back navigation.
            //The developer has to ensure that the content of the field is stored in the object that is passed to this method.
            if (oCustomData) {
                var oCustomField1 = this.oView.byId("CBOverdue");
                if (oCustomField1) {
                    oCustomData.Criticality = oCustomField1.getSelectedKey();
                }
            }
        },
        restoreCustomAppStateDataExtension: function (oCustomData) {
            //in order to restore the content of the custom field in the filter bar, for example after a back navigation,
            //an object with the content is handed over to this method. Now the developer has to ensure that the content of the custom filter is set to the control
            if (oCustomData) {
                if (oCustomData.Criticality) {
                    var oComboBox = this.oView.byId("CBOverdue");
                    oComboBox.setSelectedKey(
                        oCustomData.Criticality
                    );
                }
            }
        },
        onBeforeRebindTableExtension: function(oEvent) {
            var oBindingParams = oEvent.getParameter("bindingParams");
            oBindingParams.parameters = oBindingParams.parameters || {};

            var oSmartTable = oEvent.getSource();
            var oSmartFilterBar = this.byId(oSmartTable.getSmartFilterId());
            if (oSmartFilterBar instanceof SmartFilterBar) {
                var oCustomControl = oSmartFilterBar.getControlByKey("_keyStatusCB");

                    var oItems = oCustomControl.getItems();
                    var oCB = oItems[0];
                    if ( oItems[0].getSelected( )) {oBindingParams.filters.push(new Filter("Criticality", "EQ", "1"))}; 
                    if ( oItems[1].getSelected( )) {oBindingParams.filters.push(new Filter("Criticality", "EQ", "2"))};                    
                    if ( oItems[2].getSelected( )) {oBindingParams.filters.push(new Filter("Criticality", "EQ", "3"))};

                
                              
            }
        }
    };
});

 

 

 

5. finally the controller is added to the List Report controllers in the manifest.json:

 

 

 

                   "sap.suite.ui.generic.template.ListReport.view.ListReport": {
                        "controllerName": "yourproject.ext.controller.ListReportExt",