9

This issue came forth from drilling down the original question: How to set filter in table dropdown based on table row data

Background

I want to use a filter on a SAPUI5 dropdown control, where I set the filter value based on a model property (data binding)

The issue

If I use a filter where the filter value value1 is specified by data binding:

new sap.ui.model.Filter({
    path     : "division", 
    operator : sap.ui.model.FilterOperator.EQ, 
    value1   : "{/someProperty}"
})

then the dropdown does not render any items

However, if I hardcode a value at property value1:

new sap.ui.model.Filter({
    path     : "division", 
    operator : sap.ui.model.FilterOperator.EQ, 
    value1   : "Test"
})

Then the filter works as expected.

The Question

Is it true we can't use data binding for specifying a filter value? Or should I implement it in another way?

A small part of me can actually understand that setting a filter on a control's model using a value from that same model could induce some referential issues, but this behavior also occurs when using two distinct named models (one for the dropdown, and one for the filter value)

Any help is greatly appreciated!

Community
  • 1
  • 1
Qualiture
  • 4,900
  • 7
  • 27
  • 38
  • I know its been long. How did you workaround this issue? I need to set default filter by Date in my application for a List. Do we have to use bindAggregation with a template in the JS ? or is there a better way? – c_y Feb 16 '15 at 17:07
  • 1
    I think I went ahead using the EventBus, and set the filter in the controller instead – Qualiture Feb 18 '15 at 09:08
  • Not sure if I'm missing something here, but can't you just do ´value1: this.getView().getModel().getProperty("/someProperty")´ (assuming ´this´ relates to the controller)? – emrass Mar 03 '15 at 19:12
  • Normally it would, but in this case the filter is part of an aggregation template (see referred link in question on top) so each filter should have been set using a value from the current row's binding context – Qualiture Mar 03 '15 at 19:41
  • Related GitHub issue: https://github.com/SAP/openui5/issues/130 – Boghyon Hoffmann Jul 05 '18 at 11:33

2 Answers2

8

I just went through the code of ClientListBinding, unfortunately the property binding for Filter value is not supported. Please check the source code here.

See function getFilterFunction, the filter value is get from your Filter definition oValue1 and oValue2, it does not parse any DataBinding path to get value from DataModel.

/**
 * Provides a JS filter function for the given filter
 * @name sap.ui.model.ClientListBinding#getFilterFunction
 * @function
 */
ClientListBinding.prototype.getFilterFunction = function(oFilter){
    if (oFilter.fnTest) {
        return oFilter.fnTest;
    }
    var oValue1 = this.normalizeFilterValue(oFilter.oValue1),
        oValue2 = this.normalizeFilterValue(oFilter.oValue2);

    switch (oFilter.sOperator) {
        case "EQ":
            oFilter.fnTest = function(value) { return value == oValue1; }; break;
        case "NE":
            oFilter.fnTest = function(value) { return value != oValue1; }; break;
        case "LT":
            oFilter.fnTest = function(value) { return value < oValue1; }; break;
        case "LE":
            oFilter.fnTest = function(value) { return value <= oValue1; }; break;
        case "GT":
            oFilter.fnTest = function(value) { return value > oValue1; }; break;
        case "GE":
            oFilter.fnTest = function(value) { return value >= oValue1; }; break;
        case "BT":
            oFilter.fnTest = function(value) { return (value >= oValue1) && (value <= oValue2); }; break;
        case "Contains":
            oFilter.fnTest = function(value) {
                if (typeof value != "string") {
                    throw new Error("Only \"String\" values are supported for the FilterOperator: \"Contains\".");
                }
                return value.indexOf(oValue1) != -1; 
            }; 
            break;
        case "StartsWith":
            oFilter.fnTest = function(value) { 
                if (typeof value != "string") {
                    throw new Error("Only \"String\" values are supported for the FilterOperator: \"StartsWith\".");
                }
                return value.indexOf(oValue1) == 0; 
            }; 
            break;
        case "EndsWith":
            oFilter.fnTest = function(value) { 
                if (typeof value != "string") {
                    throw new Error("Only \"String\" values are supported for the FilterOperator: \"EndsWith\".");
                }
                var iPos = value.lastIndexOf(oValue1);
                if (iPos == -1){
                    return false;                   
                }
                return iPos == value.length - new String(oFilter.oValue1).length; 
            }; 
            break;
        default:
            oFilter.fnTest = function(value) { return true; };
    }
    return oFilter.fnTest;
};

I guess you have to go workaround here to use event handler.

Haojie
  • 5,665
  • 1
  • 15
  • 14
0

No, it is not currently possible to set Filter value using data binding. However, there is an approved enhancement issue in the OpenUI5 repository labeled "contribution welcome". This means that it is planned to add this functionality, and once added it will be possible to set the Filter value using data binding.

rikusv
  • 646
  • 5
  • 10