cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

MultiComboBox for table filtering in Fiori Elements for OData v4

purplepinguin86
Explorer
0 Likes
2,470

I'm using Fiori Elements Templates for OData v4 where I can easily add custom combobox filters for my table using the following example:

https://ui5.sap.com/#/topic/5fb9f57fcf12401bbe39a635e9a32a4e

Now I want to use not a normal `ComboBox` but a `MultiComboBox`, so the `selectedKey` in the example can be changed to `selectedKeys` quite easily. Like so:

<MultiComboBox items="{/Quarters}" selectedKeys="{path: 'filterValues>', type: 'sap.fe.macros.filter.type.Value', formatOptions: { operator: 'com.xxx.ext.controller.CustomFilter.quarterViewFilter' }}">
    <core:Item key="{ID}" text="{ID}" />
</MultiComboBox>

It kinda works in the background, but if I select multiple the value becomes a string separated by commas: "value1,value2", so the `MultiComboBox` doesn't show anything then (as it is an invalid item key).

Also it seems I cannot use `setFilterValues` as shown in the example, with the MultiComboBox's `selectionFinish="handler.setQuartersFilter"` event, as I want to use a more complex `sap.ui.model.Filter` filter .

Does anyone have a solution for this?

Accepted Solutions (1)

Accepted Solutions (1)

purplepinguin86
Explorer

So I found a solution for this!

First we need to register the custom Value Operator (as also shown in the example).

What I didn't know is that you can pass this to the control:FormElementWrapper XML element values as well, in order to register it through the XML template (you can use any arbitrary xml attribute name, I used `filter`)

<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:l="sap.ui.layout" xmlns:control="sap.fe.core.controls" xmlns:filter="sap.fe.macros.filter.type">
	<control:FormElementWrapper filter="{type: 'sap.fe.macros.filter.type.Value', formatOptions: { operator: 'com.xxx.ext.controller.CustomFilter.quarterViewFilter' }}">
		<HBox alignItems="Center" width="100%" core:require="{handler: 'com/xxx/ext/controller/CustomFilter'}">
			<MultiComboBox items="{/Quarters}" selectionFinish="handler.setQuartersFilter">
				<core:Item key="{ID}" text="{ID}" />
			</MultiComboBox>
		</HBox>
	</control:FormElementWrapper>
</core:FragmentDefinition><br>

Then you you can use this for the js part:

// eslint-disable-next-line no-undef
sap.ui.define(['sap/ui/model/Filter', 'sap/ui/model/FilterOperator'], function (Filter, FilterOperator) {
    'use strict';

    return {
        quarterViewFilter: function (value) {
            value = value.substring(1); // Apperantly it starts with an equal sign which we want to remove
            if (!value) return new Filter({ path: 'quarter', operator: FilterOperator.LE, value1: 'xxx' }); // just return a fake filter. 


            const values = value.substring(1).split(','); // Apparently it starts with an equal sign which we want to remove
            console.log('debug custom MultiComboBox filter!', values);
            return new Filter({
                filters: values.map(
                    (value) =>
                        new Filter({
                            filters: [
                                new Filter({ path: 'quarterStart', operator: FilterOperator.LE, value1: value }), // So the version quarter needs to be less or equal to the value
                                new Filter({
                                    path: 'quarterEnd',
                                    operator: FilterOperator.GE,
                                    value1: value
                                }) // So the version quarter end needs to be greater or equal to the value
                            ],
                            and: true
                        })
                ),
                and: false
            });
        },

        setQuartersFilter: function (event) {
            const selectedQuarters = event.getParameter('selectedItems').map((item) => item?.getText());
            this.setFilterValues(
                'QuarterView', // Corresponds to the filter key name defined in manifest.json
                'com.xxx.ext.controller.CustomFilter.quarterViewFilter',
                selectedQuarters.join(',') // Only a normal string can be passed to the filter function
            );
        }
    };
});

It seems that filters only works with normal string values, that is why I used a join and split. If anyone can think of a more cleaner solution, just let me know!

Answers (1)

Answers (1)

Dong_Chen1
Product and Topic Expert
Product and Topic Expert

"sap.fe.macros.filter.type.Value" is only for single value. Since MultiComboBox supports multi values, you cannot use that. Instead, try "sap.fe.macros.filter.type.MultiValue".

<MultiComboBox width="100%" selectedKeys="{path: 'filterValues>', type: 'sap.fe.macros.filter.type.MultiValue'}">
			<layoutData>
				<FlexItemData growFactor="1" />
			</layoutData>
			<items>
				<core:Item key="1" text="1" />
				<core:Item key="2" text="2" />
				<core:Item key="3" text="3" />
				<core:Item key="4" text="4" />
				<core:Item key="5" text="5" />
			</items>
		</MultiComboBox>

Another type supported here is "sap.fe.macros.filter.type.Range". See the examples at https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/filterBar/filt....