Correct usage for filters when binding items via XMLView

Marinho Brandão picture Marinho Brandão · Apr 22, 2016 · Viewed 51.9k times · Source

Using sap.m.Select, I have a similar code as this below:

<m:Select
    selectedKey='{state}'
    items="{
        path: 'states>/content',
        sorter: {
            path: 'name'
        }
    }">
    <core:Item key="{states>id}" text="{states>name}" />
</m:Select>

As want to be able to filter states by country when it is selected in another input, so, I'm trying using filters, which is defined in documentation in:

The problem is that I couldn't find anywhere (docs, google, SO, source code, examples, tests) showing how to correctly use it. I tried these 2 ways with no success:

<m:Select
    selectedKey='{state}'
    items="{
        path: 'states>/content',
        sorter: {
            path: 'name'
        },
        filters: [{
            path: 'countryId',
            operator: 'EQ',
            value1: '10' // just example
        ]}
    }">
    <core:Item key="{states>id}" text="{states>name}" />
</m:Select>

and

# View
<m:Select
    selectedKey='{state}'
    items="{
        path: 'states>/content',
        sorter: {
            path: 'name'
        },
        filters: ['.filterByCountry'}
    }">
    <core:Item key="{states>id}" text="{states>name}" />
</m:Select>

# Controller
...
filterByCountry: new sap.ui.model.Filter({
    path: 'countryId',
    operator: 'EQ',
    value1: '10'
}),
...

Anybody knows the proper way to use it?

Answer

Nabi picture Nabi · Apr 24, 2016

Here is how filters work in XML Views - see the 2 examples below I coded for you (use the jsbin links if they don't run here on stackoverflow). They both use the Northwind OData service. As you will see it's pretty much straight forward:

<Select
    items="{
        path : '/Orders',
        sorter: {
            path: 'OrderDate',
            descending: true
        },
        filters : [
            { path : 'ShipCountry', operator : 'EQ', value1 : 'Brazil'}
        ]
    }">

Of course, you can add multiple filters as well (see the second example below).

However, keep in mind that the filters are declared in the XMLView. Unfortunately, UI5 is currently not so dynamic to allow changing such filters defined in an XMLView dynamically by only using the binding syntax in the XMLView. Instead you would need some piece of JavaScript code. In your case you could listen for the change event of the other field. In the event handler you would then simply create a new Filter and apply it:

var oSelect, oBinding, aFilters, sShipCountry;

sFilterValue = ...; // I assume you can get the filter value from somewhere...
oSelect = this.getView().byId(...); //get the reference to your Select control
oBinding = oSelect.getBinding("items");
aFilters = [];

if (sFilterValue){
    aFilters.push( new Filter("ShipCountry", FilterOperator.Contains, sFilterValue) );
}
oBinding.filter(aFilters, FilterType.Application);  //apply the filter

That should be all you need to do. The examples below do not use any JavaScript code for the filter, but I guess you get the idea.

1. Example - Select box:

Run the code: https://jsbin.com/wamugexeda/edit?html,output

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>SAPUI5 single file template | nabisoft</title>
        <script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
            id="sap-ui-bootstrap"
            data-sap-ui-theme="sap_bluecrystal"
            data-sap-ui-libs="sap.m"
            data-sap-ui-bindingSyntax="complex"
            data-sap-ui-compatVersion="edge"
            data-sap-ui-preload="async"></script>
            <!-- use "sync" or change the code below if you have issues -->
 
        <!-- XMLView -->
        <script id="myXmlView" type="ui5/xmlview">
            <mvc:View
                controllerName="MyController"
                xmlns="sap.m"
                xmlns:core="sap.ui.core"
                xmlns:mvc="sap.ui.core.mvc">
 
                <Select
                    items="{
                        path : '/Orders',
                        sorter: {
                            path: 'OrderDate',
                            descending: true
                        },
                        filters : [
                            { path : 'ShipCountry', operator : 'EQ', value1 : 'Brazil'}
                        ]					
                    }">
                    <core:Item key="{OrderID}" text="{OrderID} - {ShipName}" />
                </Select>
 
            </mvc:View>
        </script>
 
        <script>
            sap.ui.getCore().attachInit(function () {
                "use strict";
 
                //### Controller ###
                sap.ui.define([
                    "sap/ui/core/mvc/Controller",
                    "sap/ui/model/odata/v2/ODataModel"
                ], function (Controller, ODataModel) {
                    "use strict";
 
                    return Controller.extend("MyController", {
                        onInit : function () {
                            this.getView().setModel(
                                new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
                                    json : true,
                                    useBatch : false
                                })
                            );
                        }
                    });
                });
 
                //### THE APP: place the XMLView somewhere into DOM ###
                sap.ui.xmlview({
                    viewContent : jQuery("#myXmlView").html()
                }).placeAt("content");
 
            });
        </script>
 
    </head>
 
    <body class="sapUiBody">
        <div id="content"></div>
    </body>
</html>

2. Example - Table:

Run the code: https://jsbin.com/yugefovuyi/edit?html,output

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>SAPUI5 single file template | nabisoft</title>
        <script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
            id="sap-ui-bootstrap"
            data-sap-ui-theme="sap_bluecrystal"
            data-sap-ui-libs="sap.m"
            data-sap-ui-bindingSyntax="complex"
            data-sap-ui-compatVersion="edge"
            data-sap-ui-preload="async"></script>
            <!-- use "sync" or change the code below if you have issues -->
 
        <!-- XMLView -->
        <script id="myXmlView" type="ui5/xmlview">
            <mvc:View
                controllerName="MyController"
                xmlns="sap.m"
                xmlns:core="sap.ui.core"
                xmlns:mvc="sap.ui.core.mvc">
 
                <Table
                    id="myTable"
                    growing="true"
                    growingThreshold="10"
                    growingScrollToLoad="true"
                    busyIndicatorDelay="0"
                    items="{
                        path : '/Orders',
                        sorter: {
                            path: 'OrderDate',
                            descending: true
                        },
                        filters : [
                            { path : 'ShipCity', operator : 'Contains', value1 : 'rio'},
                            { path : 'ShipName', operator : 'EQ', value1 : 'Hanari Carnes'}
                        ]					
                    }">
                    <headerToolbar>
                        <Toolbar>
                            <Title text="Orders of ALFKI"/>
                            <ToolbarSpacer/>
                        </Toolbar>
                    </headerToolbar>
                    <columns>
                        <Column>
                            <Text text="OrderID"/>
                        </Column>
                        <Column>
                            <Text text="Order Date"/>
                        </Column>
                        <Column>
                            <Text text="To Name"/>
                        </Column>
                        <Column>
                            <Text text="Ship City"/>
                        </Column>
                    </columns>
                    <items>
                        <ColumnListItem type="Active">
                            <cells>
                                <ObjectIdentifier title="{OrderID}"/>

                                <Text
                                    text="{
                                        path:'OrderDate',
                                        type:'sap.ui.model.type.Date',
                                        formatOptions: { style: 'medium', strictParsing: true}
                                    }"/>

                                <Text text="{ShipName}"/>

                                <Text text="{ShipCity}"/>

                            </cells>
                        </ColumnListItem>
                    </items>
                </Table>
 
            </mvc:View>
        </script>
 
        <script>
            sap.ui.getCore().attachInit(function () {
                "use strict";
 
                //### Controller ###
                sap.ui.define([
                    "sap/ui/core/mvc/Controller",
                    "sap/ui/model/odata/v2/ODataModel"
                ], function (Controller, ODataModel) {
                    "use strict";
 
                    return Controller.extend("MyController", {
                        onInit : function () {
                            this.getView().setModel(
                                new ODataModel("https://cors-anywhere.herokuapp.com/services.odata.org/V2/Northwind/Northwind.svc/", {
                                    json : true,
                                    useBatch : false
                                })
                            );
                        }
                    });
                });
 
                //### THE APP: place the XMLView somewhere into DOM ###
                sap.ui.xmlview({
                    viewContent : jQuery("#myXmlView").html()
                }).placeAt("content");
 
            });
        </script>
 
    </head>
 
    <body class="sapUiBody">
        <div id="content"></div>
    </body>
</html>