SAP Fiori Overview Page – Global Filter
There are a number of blog that cover different aspect of Overview Page creation, for example, Overview Page Web IDE plugin, Analytical Cards, List Cards, Table Cards, Navigation Concepts, Stack Cards, Quick View Cards and KPI Header. Global Filter creation deserves a separate blog. In my blog I explain Global Filter creation from start to end.
Below is a Global Filter for Flight Overview Page in action:
As you can see Region, Airline and Plane Type are multi-value fixed-value filters. All filters support search to restrict filter value list (see picture above). Besides of, Region and Airline filters display value descriptions, but apply value keys to restrict Overview Page data.
I created a separate OData Service for Global Filter. As long as Global Filter Entity Type Properties have the same names as Properties of OData Service that feeds Overview Page it works just fine.
Below is implementation of ZFLIGHT_FILTER_1_SRV OData Service that feeds Global Filter.
Note: FILTER Entity Type has Filterable attribute set for all 3 properties: CARRID, CARRID__CONTINENT and PLANETYPE.
Note: CONTINENT Entity Type has CONTINENTNAME property that is a text for CARRID_CONTINENT property (assigned later in annotations)
Note: CARRIER Entity Type has CARRRNAME property that is a text for CARRID property (assigned later in annotations)
Note: PLANE Entity Type has the only property e.g. PLANETYPE (no text for plane type key)
Below is ZFLIGHT_FILTER_1_SRV OData Service Data Provider Class implementation:
CLASS zcl_zflight_filter_1_dpc_ext DEFINITION
PUBLIC
INHERITING FROM zcl_zflight_filter_1_dpc
CREATE PUBLIC .
PUBLIC SECTION.
PROTECTED SECTION.
METHODS carriers_get_entityset
REDEFINITION .
METHODS continents_get_entityset
REDEFINITION .
METHODS planes_get_entityset
REDEFINITION .
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_ZFLIGHT_FILTER_1_DPC_EXT IMPLEMENTATION.
METHOD carriers_get_entityset.
SELECT carrid carrname
INTO TABLE et_entityset
FROM scarr.
ENDMETHOD.
METHOD continents_get_entityset.
SELECT /bic/continent AS carrid__continent txtsh AS CONTINENTNAME
INTO TABLE et_entityset
FROM /bic/tcontinent.
ENDMETHOD.
METHOD planes_get_entityset.
SELECT planetype
INTO TABLE et_entityset
FROM saplane.
ENDMETHOD.
ENDCLASS.
Note: GetEntitySet operation is implemented for 3 Entity Sets: CARRIERS, CONTINENTS and PLANES to populate Global Filter value lists.
Below is ZFLIGHT_FILTER_1_SRV OData Service Model Provider Class implementation:
CLASS zcl_zflight_filter_1_mpc_ext DEFINITION
PUBLIC
INHERITING FROM zcl_zflight_filter_1_mpc
CREATE PUBLIC .
PUBLIC SECTION.
METHODS define
REDEFINITION .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS ZCL_ZFLIGHT_FILTER_1_MPC_EXT IMPLEMENTATION.
METHOD define.
* see /iwbep/if_ana_odata_types=>gcs_ana_odata_annotation_value
super->define( ).
DATA(entity_type) = model->get_entity_type( 'FILTER' ).
DATA(property) = entity_type->get_property( 'CARRID' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'filter-restriction'
iv_value = 'multi-value' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'value-list'
iv_value = 'fixed-values' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'label'
iv_value = 'Airline' ).
DATA(entity_type2) = model->get_entity_type( 'CARRIER' ).
property = entity_type2->get_property( 'CARRID' ).
property->set_reference_annotation(
iv_annotation_key = /iwbep/if_ana_odata_types=>gcs_ana_odata_annotation_key-text
iv_property = 'CARRNAME' ).
property = entity_type->get_property( 'CARRID__CONTINENT' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'filter-restriction'
iv_value = 'multi-value' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'value-list'
iv_value = 'fixed-values' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'label'
iv_value = 'Region' ).
entity_type2 = model->get_entity_type( 'CONTINENT' ).
property = entity_type2->get_property( 'CARRID__CONTINENT' ).
property->set_reference_annotation(
iv_annotation_key = /iwbep/if_ana_odata_types=>gcs_ana_odata_annotation_key-text
iv_property = 'CONTINENTNAME' ).
property = entity_type->get_property( 'PLANETYPE' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'filter-restriction'
iv_value = 'multi-value' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'value-list'
iv_value = 'fixed-values' ).
property->/iwbep/if_mgw_odata_annotatabl~create_annotation( 'sap' )->add(
EXPORTING
iv_key = 'label'
iv_value = 'Plane Type' ).
DATA(ann_target) = vocab_anno_model->create_annotations_target( 'ZFLIGHT_FILTER_1_SRV.FILTER/CARRID' ).
DATA(annotation) = ann_target->create_annotation( iv_term = 'com.sap.vocabularies.Common.v1.ValueList' ).
DATA(record) = annotation->create_record( ).
DATA(property2) = record->create_property( 'CollectionPath' ).
property2->create_simple_value( )->set_string( 'CARRIERS' ).
DATA(collection) = record->create_property( 'Parameters' )->create_collection( ).
record = collection->create_record( 'com.sap.vocabularies.Common.v1.ValueListParameterInOut' ).
property2 = record->create_property( 'LocalDataProperty' ).
property2->create_simple_value( )->set_property_path( CONV #( 'CARRID' ) ).
property2 = record->create_property( 'ValueListProperty' ).
property2->create_simple_value( )->set_string( CONV #( 'CARRID' ) ).
record = collection->create_record( 'com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly' ).
property2 = record->create_property( 'ValueListProperty' ).
property2->create_simple_value( )->set_property_path( CONV #( 'CARRNAME' ) ).
ann_target = vocab_anno_model->create_annotations_target( 'ZFLIGHT_FILTER_1_SRV.FILTER/CARRID__CONTINENT' ).
annotation = ann_target->create_annotation( iv_term = 'com.sap.vocabularies.Common.v1.ValueList' ).
record = annotation->create_record( ).
property2 = record->create_property( 'CollectionPath' ).
property2->create_simple_value( )->set_string( 'CONTINENTS' ).
collection = record->create_property( 'Parameters' )->create_collection( ).
record = collection->create_record( 'com.sap.vocabularies.Common.v1.ValueListParameterInOut' ).
property2 = record->create_property( 'LocalDataProperty' ).
property2->create_simple_value( )->set_property_path( CONV #( 'CARRID__CONTINENT' ) ).
property2 = record->create_property( 'ValueListProperty' ).
property2->create_simple_value( )->set_string( CONV #( 'CARRID__CONTINENT' ) ).
record = collection->create_record( 'com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly' ).
property2 = record->create_property( 'ValueListProperty' ).
property2->create_simple_value( )->set_property_path( CONV #( 'CONTINENTNAME' ) ).
ann_target = vocab_anno_model->create_annotations_target( 'ZFLIGHT_FILTER_1_SRV.FILTER/PLANETYPE' ).
annotation = ann_target->create_annotation( iv_term = 'com.sap.vocabularies.Common.v1.ValueList' ).
record = annotation->create_record( ).
property2 = record->create_property( 'CollectionPath' ).
property2->create_simple_value( )->set_string( 'PLANES' ).
collection = record->create_property( 'Parameters' )->create_collection( ).
record = collection->create_record( 'com.sap.vocabularies.Common.v1.ValueListParameterInOut' ).
property2 = record->create_property( 'LocalDataProperty' ).
property2->create_simple_value( )->set_property_path( CONV #( 'PLANETYPE' ) ).
property2 = record->create_property( 'ValueListProperty' ).
property2->create_simple_value( )->set_string( CONV #( 'PLANETYPE' ) ).
ENDMETHOD.
ENDCLASS.
Note that abode code generates annotations which:
- Limit Region, Airline and Plane Type Global Filter selections to multi-value and fixed value
- Assign Region, Airline and Plane Type labels to CARRID, CARRID__CONTINENT and PLANETYPE Global Filter drop downs respectively;
- Assign CONTINENTNAME property as text for CARRID__CONTINENT property of CONTINENT Entity Type
- Assign CARRNAME property as text for CARRID property of PLANE Entity Type;
- Assign CARRIERS Entity Set to be a value list for CARRID property of FILTER Entity Type
- Assign CONTINENTS Entity Set to be a value list for CARRID__CONTINENT property of FILTER Entity Type;
- Assign PLANES Entity Set to be a value list for PLANETYPE property of FILTER Entity Type
This is how ZFLIGHT_FILTER_1_SRV OData Service metadata looks like:
<edmx:Edmx xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:sap="http://www.sap.com/Protocols/SAPData" Version="1.0">
<edmx:DataServices m:DataServiceVersion="2.0">
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" Namespace="ZFLIGHT_FILTER_1_SRV" xml:lang="en" sap:schema-version="1">
<EntityType Name="FILTER" sap:content-version="1">
<Key>
<PropertyRef Name="CARRID"/>
<PropertyRef Name="CARRID__CONTINENT"/>
<PropertyRef Name="PLANETYPE"/>
</Key>
<Property Name="CARRID" Type="Edm.String" Nullable="false" sap:filter-restriction="multi-value" sap:label="Airline" sap:unicode="false" sap:value-list="fixed-values" sap:creatable="false" sap:updatable="false" sap:sortable="false"/>
<Property Name="CARRID__CONTINENT" Type="Edm.String" Nullable="false" sap:filter-restriction="multi-value" sap:label="Region" sap:unicode="false" sap:value-list="fixed-values" sap:creatable="false" sap:updatable="false" sap:sortable="false"/>
<Property Name="PLANETYPE" Type="Edm.String" Nullable="false" sap:filter-restriction="multi-value" sap:label="Plane Type" sap:unicode="false" sap:value-list="fixed-values" sap:creatable="false" sap:updatable="false" sap:sortable="false"/>
</EntityType>
<EntityType Name="CARRIER" sap:content-version="1">
<Key>
<PropertyRef Name="CARRID"/>
</Key>
<Property Name="CARRID" Type="Edm.String" Nullable="false" sap:text="CARRNAME" sap:unicode="false" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="CARRNAME" Type="Edm.String" Nullable="false" sap:unicode="false" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
</EntityType>
<EntityType Name="CONTINENT" sap:content-version="1">
<Key>
<PropertyRef Name="CARRID__CONTINENT"/>
</Key>
<Property Name="CARRID__CONTINENT" Type="Edm.String" Nullable="false" sap:text="CONTINENTNAME" sap:unicode="false" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
<Property Name="CONTINENTNAME" Type="Edm.String" Nullable="false" sap:unicode="false" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
</EntityType>
<EntityType Name="PLANE" sap:content-version="1">
<Key>
<PropertyRef Name="PLANETYPE"/>
</Key>
<Property Name="PLANETYPE" Type="Edm.String" Nullable="false" sap:unicode="false" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
</EntityType>
<EntityContainer Name="ZFLIGHT_FILTER_1_SRV_Entities" m:IsDefaultEntityContainer="true" sap:supported-formats="atom json xlsx">
<EntitySet Name="FILTERS" EntityType="ZFLIGHT_FILTER_1_SRV.FILTER" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:addressable="false" sap:content-version="1"/>
<EntitySet Name="CARRIERS" EntityType="ZFLIGHT_FILTER_1_SRV.CARRIER" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:addressable="false" sap:content-version="1"/>
<EntitySet Name="CONTINENTS" EntityType="ZFLIGHT_FILTER_1_SRV.CONTINENT" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:addressable="false" sap:content-version="1"/>
<EntitySet Name="PLANES" EntityType="ZFLIGHT_FILTER_1_SRV.PLANE" sap:creatable="false" sap:updatable="false" sap:deletable="false" sap:pageable="false" sap:addressable="false" sap:content-version="1"/>
</EntityContainer>
<Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="ZFLIGHT_FILTER_1_SRV.FILTER/CARRID">
<Annotation Term="com.sap.vocabularies.Common.v1.ValueList">
<Record>
<PropertyValue Property="CollectionPath" String="CARRIERS"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="CARRID"/>
<PropertyValue Property="ValueListProperty" String="CARRID"/>
</Record>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly">
<PropertyValue Property="ValueListProperty" PropertyPath="CARRNAME"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
<Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="ZFLIGHT_FILTER_1_SRV.FILTER/CARRID__CONTINENT">
<Annotation Term="com.sap.vocabularies.Common.v1.ValueList">
<Record>
<PropertyValue Property="CollectionPath" String="CONTINENTS"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="CARRID__CONTINENT"/>
<PropertyValue Property="ValueListProperty" String="CARRID__CONTINENT"/>
</Record>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterDisplayOnly">
<PropertyValue Property="ValueListProperty" PropertyPath="CONTINENTNAME"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
<Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="ZFLIGHT_FILTER_1_SRV.FILTER/PLANETYPE">
<Annotation Term="com.sap.vocabularies.Common.v1.ValueList">
<Record>
<PropertyValue Property="CollectionPath" String="PLANES"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="com.sap.vocabularies.Common.v1.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="PLANETYPE"/>
<PropertyValue Property="ValueListProperty" String="PLANETYPE"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="self" href="https://pcibd100.pcisap.lan:8001/sap/opu/odata/sap/ZFLIGHT_FILTER_1_SRV/$metadata"/>
<atom:link xmlns:atom="http://www.w3.org/2005/Atom" rel="latest-version" href="https://pcibd100.pcisap.lan:8001/sap/opu/odata/sap/ZFLIGHT_FILTER_1_SRV/$metadata"/>
</Schema>
</edmx:DataServices>
</edmx:Edmx>
Now Global Filter ZFLIGHT_FILTER_1_SRV OData Service is ready to be used Overview Page. First of all, OData Service needs to be added to a project, then assigned as Global Filter Model and Entity Type
And finally what is needed is be done is to list all FILTER Entity Type Properties that will be a part of Global Filter
Hello Uladzislau,
thank you for sharing your knowledge in this blog post.
I recognized that you have absolute values in your donut chart instead of percentage values. Could you share the annotation please?
Best regards
Dieter
Hi Dieter,
see annotation file below:
Regards, Uladzislau
Hi Uladzislau,
Thank you for writing this blog. We have a similar requirement and your blog helped me a lot.
I have one question. Is it possible to pass $filter for the CollectionPath referenced inside v1.ValueList annotation?
Regards,
Himanshu
Hi Himanshu,
my recommendation is to stay standard. There is always a risk that custom changes may not survive the upgrade. If you still want to make custom changes you can check Krishna Kishor Kammaje blogs.
Regards, Uladzislau
Hi, Uladzislau
Thank u for the blog. When I configuring the global filter, I noticed that it only works for those Entity Set with same properties. Is there any way to filter properties before aggregation? For example, I want to calculate total cost for each company, so I need to group data by org_unit and use sum() to gain the result. Cost have many types, now I want to calculate transportation costs only. I think it's not possible to join cost_type with the data after aggregation, so is it possible to filter cost_type with global filter?
Regards, Raven
Hi Raven,
it should work for analytical cards.
Regards, Uladzislau
Hi Uladzislau,
So it does not work for overview page, right?
Regards, Raven
Hi Raven,
it should work for Analytical cards, but not for Table and List cards.
Regards, Uladzislau
Hi Uladzislau Pralat,
Thanks
Will this global filter work for custom cards?
Thanks
Hi Akash,
if custom card implemented right then it should.
Regards, Uladzislau