Skip to Content

Having seen and understood the basics of List Reports and the main annotations, you are ready to explore other UI annotations.  You might want to start with some simple changes – sorting and grouping.  Certainly your users can sort and group a list report using the settings icon. However if you are creating a custom report you will probably want to default the sorting and grouping for them. In this blog you will see how to set the default sort order and grouping as a developer.

It’s worth remembering that, as well as guiding the design of the List Report through annotations, there are always some List Report behaviours end users can control for themselves.  Naturally, if there’s a common preference among many end users you will want to default those behaviours up front using annotations. It’s also necessary to set certain default behaviours – such as sorting and grouping – if you want to add more advanced aggregation features such as totals, subtotals, and other analytics.

As a developer you can also adjust the Sort Order and Grouping using the annotation UI.PresentationVariant. Using annotations to default the Sort Order is straightforward. Setting up a default Grouping, however, requires you to have a little more knowledge than just the annotations. You will need to understand the difference between the different table types supported by the Fiori element List Report, and how that impacts grouping and other table behaviours.

IMPORTANT: For simplicity in this blog you will see firstly how to default sorting and grouping using local annotations. However remember that if you are creating a specific custom CDS View to provide the data for your List Report you are recommended to build the annotations into the CDS View using a Metadata Extension.  You can find out more about Metadata Extensions in the ABAP Programming Model for SAP Fiori.

Below you see a simple Sales Order list report.  This is your starting point for the rest of the examples in this blog.

TIP: This report is based on a ABAP CDS View exposed as an OData Service, as recommended in the ABAP Programming Model for SAP Fiori.

Before you attempt to use the PresentationVariant, you need to understand a little about List Report table types. Because the SAP Cloud Platform Web IDE makes the annotations easy to understand, you will see how to sort and group using the Annotation Modeler first, and then you will see some alternative approaches using XML or a metadata extension of your CDS View.  So in this blog you will find:

  • A brief introduction to Table Types
  • A little revision on annotations basics to get you started
  • How to default the Sort Order
  • How to default Grouping
  • Using PresentationVariant in annotation XML files
  • Using PresentationVariant in the metadata extension of a CDS View

The examples in this blog are based on:

  • SAPUI5 1.50
  • SAP NetWeaver AS ABAP 7.52 (as part of a SAP S/4HANA 1709 solution)
  • SAP Cloud Platform Web IDE Full Stack version 180104
  • Ecliipse Oxygen

A brief introduction to Table Types

There are 3 main table types used:

  • Responsive
  • Grid
  • Tree

The Responsive type is a simple lean table. This table type is recommended for use on all types of devices including smartphones.

With a responsive table you can Sort and add a single level of Grouping as a business user, using the Settings icon. However you are not permitted to default this as a developer.

This example shows single level grouping on the Company Name.

 

The other table types are known collectively as Analytical table types. They are intended to handle larger amounts of data, and are therefore recommended for larger devices, e.g. desktop and tablet.

With analytical tables you can Sort and do multiple levels of Grouping, both as a business user and as a developer.

You’ll also find features you would expect in a desktop or tablet app, such as:

  • Reorder columns via drag and drop
  • Adjust column width using the cursor on the column border
  • Sort, filter, group or freeze columns using the column header
  • Automatic totalling and subtotalling for aggregated data

TIP: In the latest versions you even get a Show Details link for a totals dialog summarizing a column of amounts in multiple currencies into a consolidated total into a total per currency.

A Grid table is the default table type used when your OData Service includes aggregated data, i.e. attribute sap:semantics is set to “aggregate”.

TIP: You can see this setting on the Entity Type tag in the metadata of your OData Service, e.g.

<EntityType Name="ZC_SO_SalesOrderItemType" sap:semantics="aggregate" sap:label="Sales Order Items" sap:content-version="1">

Aggregated data can be shown with summary information such as totals.

If you are following the ABAP Programming Model for SAP Fiori, the easiest way to set sap:semantics to aggregate is to include the following annotation in your CDS View itself against any numeric field, such as amount or quantity:

@DefaultAggregation: #SUM

TIP: You cannot use DefaultAggregation annotations in metadata extensions. You can find out more about Default Aggregations in the ABAP Programming Model for SAP Fiori.

A Tree table is used to show lists with hierarchical tree structures.  When you add grouping properties to a Grid table, the Fiori elements automatically converts to a Tree table.  This has the added bonus that as you adjust the grouping, totals and subtotals can be shown as well.

TIP: If necessary you can can override the table type to some extent in the manifest.json by using the gridTable and treeTable settings within sap.ui.generic.app > pages (of the List Report Page) > component > settings.

A little revision on annotations basics to get you started 

Start by opening your Fiori elements list report project in the SAP Cloud Platform Web IDE.  If you don’t have one already you can find out how to do that in Fiori Elements – How to Develop a List Report – Basic Approach

You can use the Web IDE Annotation Modeler to assist you as you will find explained in Fiori Elements – How to Develop a List Report – using Local Annotations

TIP: You can also change the annotations.xml file directly.

When you view the annotations file using the Annotation Modeler you can see the being used by the List Report.  These annotations were assigned when you created the List Report using the List Report application wizard.  In the Annotation Modeler, you can see both the local annotations and the external annotations inherited from the OData Service.

TIP: When following the ABAP Programming Model for SAP Fiori, the annotations are created as a metadata extension to the CDS View. And the CDS View has been exposed as an OData Service.

You start the process by adding to the Local Annotations. The easiest way to do that is by using the Annotation Modeler and the + icon on the local annotations row.

TIP: If you need to change an external annotation, just select the matching redefine icon in the Actions column.

So now you are ready to add your annotations.

How to default the Sort Order 

The sort order is defaulted using the UI.PresentationVariant annotation properties:

  • sortOrder – this collects the sorting parameters
  • sortOrder.by – this nominates the property for sorting
  • sortOrder.direction – Ascending or Descending (the default is Ascending)

If you want to sort by more than one field, you simply use the sortOrder property to collect multiple sets of sortOrder.by and sortOrder.direction combinations.

You can add these using Local Annotations.  Start by adding the UI annotation PresentationVariant.

TIP: PresentationVariant has a number of subnodes that technically must exist even if they are not used. That’s all the red asterisk indicates in the Annotation Modeler.

Within the subnode SortOrder, for each property you want to include in your Sort Order, you add a SortOrderType annotation.  The sequence in which you have defined the SortOrderType properties determines the sort sequence.

Set the Property of the SortOrderType to the OData entity property you want to sort by.

By default Sort is ascending, if you need to you simply add the Descending subnode of SortOrderType. This is a Boolean value and all you need to do is set it to true.

In this example you can see the annotations that will sort the Sales Order list firstly by Company Name and within company by Sales Order ID descending.

Because PresentationVariant is used in many different scenarios – including Overview Page analytic cards – to complete your PresentationVariant annotation you also need to set:

  • the Visualization subnode to point to your @UI.LineItem annotation used by your List Report
  • the RequestAtLeast subnode to include your sort properties

IMPORTANT: If you forget to do this in local annotations your app may hang!

In this example you can see the Visualization and RequestAtLeast subnodes of the Sales Order List Report.

Once you have saved the annotations and restarted your app, your Sales Order list looks like this:

You can find more information on defaulting the Sort Order in the SAPUI5 SDK > Developing Apps with Fiori elements > How to use List Report and Object Page Templates > Preparing UI Annotations > Annotations relevant for List Reports and Object Pages > Tables > Default Sort Order.

How to default Grouping 

You can default the grouping by setting the GroupBy subnode of the UI.PresentationVariant.

TIP: If you want to group by more than one property, just use the + icon in the Annotation Modeler.

VERY IMPORTANT: Remember however that how the grouping is applied depends on the table type. So if you try to apply grouping to a responsive table, the app is will ignore your settings!

Provided you make sure you are using an analytical table, then your grouping will work, and your grid table will convert to a tree table.

So then your Sales Order List Report will look like this.

Notice the differences to a responsive report:

  • the sort indicators in the column headers show that you have sorted the report by Company Name ascending and Sales Order ID descending
  • instead of just clicking on a row to see the details, we now have a final column with a > icon to reach the related Object Page to see the details of the row

NOTE: You do not need to sort before grouping – grouping will still work. However like me you will probably find that most business users are likely to expect that the data is sorted within your grouping.

Using PresentationVariant in annotation XML files

If you prefer to code this directly in the annotation XML editor – rather than using the annotation modeler – this is what it should look like.

Using PresentationVariant in the metadata extension of a CDS View

Of course, if you have created a CDS View specifically for this list report, you might prefer to follow recommended best practice and include your annotations as part of your CDS View.

The correct way to do this is to add your PresentationVariant and other UI annotations in a metadata extension of your CDS View. Metadata extensions enable you to layer annotations on top of existing CDS Views.

For the Sales Order list example, your Presentation Variant is formatted like this:

@UI.presentationVariant: [{

    sortOrder: [

       { by: 'CompanyName' },

       { by: 'SalesOrder', direction: #DESC } ],

     groupBy: [ 'CompanyName', 'SalesOrder' ],

     visualizations: [{ type: #AS_LINEITEM }],

     requestAtLeast: [ 'CompanyName', 'SalesOrder' ]

     }]

As the PresentationVariant applies to the whole report, you add your annotation above the “annotate view” statement as in this example.

Find out more about MetaData Extensions and UI Annotations in the ABAP Programming Model for SAP Fiori

Taking your Fiori elements app to the Next Level

If you are interested in Fiori elements you might also like to look at these videos on Youtube:

And you can find more information on Developing apps with SAP Fiori elements in the SAPUI5 SDK

Lastly you will find a collection of blogs, videos and other material in the Fiori elements wiki.

And if you are creating custom Fiori apps for SAP S/4HANA, you will find many resources to help you in the Expert Deep Dive section of the SAP Fiori for SAP S/4HANA wiki

Brought to you by the S/4HANA RIG

To report this post you need to login first.

42 Comments

You must be Logged on to comment or reply to a post.

  1. Joseph BERTHE

    Hello Jocelyn,

    Thanks for this precious information. It will be nice to have the same for the ObjectPage.

    Is the ObjectPage react the same as the ListReport (in the case where we have sections with table) ?

    Regards,

    Joseph

    (0) 
    1. Jocelyn Dart Post author

      Hi Joseph,

      Yes much the same although if you have more than one @UI.Identification or @UI.Lineitem annotation in your report it is always best to use a Qualifier to distinguish between them so that the template always knows which annotation you mean.

      Rgds

      Jocelyn

      (0) 
    1. Jocelyn Dart Post author

      Yes that’s right.  Remember that there may be 2 variants – one for the filter and one for the table – or a single combined variant depending on how the list report has been written.

      (0) 
    1. Jocelyn Dart Post author

      Hi Pedro

      Try annotation UI.multiLineText  as mentioned in per https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/7.51.1/en-US/62c32d02c4ee4b1b84dd3347e01a2075.html 

      Rgds,

      Jocelyn

      (0) 
  2. Former Member

    Hi Jocelyn ,

    Thanks for nice blog .We are trying to add filter on column header same as sort and group  but cannot find it in the UI annotation. Can you help here.

    Thanks,

    Monica

    (0) 
    1. Jocelyn Dart Post author

      Hi Monica,

      I am not quite sure what you mean? Do you mean you want to adjust which columns are displayed in the list? That is controlled by the @UI.LineItem annotation.

      Rgds,

      Jocelyn

      (0) 
  3. Former Member

    Hi Jocelyn,

    I am getting sort ,freeze in column header but i am not getting  filter in column header of table .Could you please help.

    Thanks,

    Monica

    (0) 
    1. Jocelyn Dart Post author

      Please ask questions as a separate post in answers.sap.com not in blog comments.

      As per the SAP Community Rules of Engagement.

      (0) 
  4. Akshaya Parthasarathy

    Hi Jocelyn,

    I’m using a list report smart template application. On scroll the the UI is sending batch requests again and again to the backend and say if i have 300 records, those 300 records are bound infinite times.

    This happens on scroll

    Can you please help with a solution for this?

    (0) 
    1. Jocelyn Dart Post author

      HI Akshaya, please raise questions as separate posts in answers.sap.com not as blog comments.

      At a guess it sounds like your OData Service isn’t supporting top/skip/filter options correctly.

      If you want more please raise a question in answers.sap.com

      Rgds

      Jocelyn

      (0) 
  5. Akshaya Parthasarathy

    Hi Jocelyn,

    I have set gridTable:true in my manifest for list report table. But for Navigation to object page, it shows a “Show Details” button instead of Carousel. Can you please help me get a carousel for GridTable ?

    (0) 
    1. Jocelyn Dart Post author

      Hi Akshaya,

      I think perhaps you mean the > icon rather than a Carousel?  The Show Details link shows depending on how your actions are defined. If you have more than one inline action you automatically get Show Details instead of the > icon.

      Rgds

      Jocelyn

      (0) 
    1. Jocelyn Dart Post author

      Hi Akshaya

      I’m not sure what you mean? The filter, group and sort settings are automatic in all List Reports – just look for the settings icon on the top RH of the Smart Table. Any defaults you set via annotations will show in the settings as well.

      Rgds,

      Jocelyn

      (0) 
  6. Florian Henninger

    Hi Jocelyn Dart ,

    nice blog, helped me a lot to get a view behind the scenes.

    is it possible to skip the navigation on the list. So I just need a list to show a specific status and do not need to navigate. Did not find anything at the annotations which sounded like that.

    Alternative I will create an second odata, which will show the details, but this would be just for workaraound, because noone need it.

    ~Florian

     

    (1) 
  7. Timothy Hughes

    Jocelyn,

    I have a gridTable report, where I really need totals calculated.  This report also has an Association to _line data.

    I have found that if I add @DefaultAggregation: #SUM to the _parent CDS view, it changes the KEY of that view to GENERATED_ID, which breaks the navigation to _line (due to key mismatch).

    Do you know of a way to not have the Generated_ID become the key?
    
    If not, is there a BADI (or other method) where I can interpret the GENERATED_ID in the _line Select Statment? 
    
    Thanks!
    
    -Tim

     

    (0) 
    1. Jocelyn Dart Post author

      Hi Tim,

      Interesting…  usually we opt for GUIDs as the technical id and then relate that back to a semantic key. You could perhaps use a table function for that? Or else just adjust the on condition of the $projection relationship between the parent and line views.

      Rgds

      Jocelyn

      (0) 
  8. Timothy Hughes

    Two problems:

    1. The generated_id, is generated at runtime, and cannot be specified at design time (for whatever reason, I cant post an image of that in this reply).
    2. Fiori Elements does not support CDS views with Parameters (I have a separate post on that), and thus no Table Functions can be used in Fiori Elements…. not that it would help anyway, due to #1.

    So, as it stands, it is impossible to get totals, unless you use an analytical view, and you can’t navigate with an Analytical view….

    Is there any other way to get calculated totals on Responsive, or gridTable?  I tried local annotations, and it did NOT work.

    Thanks,

    Tim

     

     

     

    (0) 
    1. Jocelyn Dart Post author

      Hi Tim,

      Local annotations only adjust the UI – they can’t make your OData Service provide new functionality.  Since the aggregation itself (i.e. the totalling of values) needs to be part of the OData Service it needs to be part of the CDS View itself.

      This is one of the reasons why it helps to use Metadata extensions rather than put all of your UI annotations inline in your CDS View.  Using Metadata extensions helps you clarify, for both your developers and your support people, which annotations are directly influencing the UI, versus which annotations are influencing the capabilities of the OData Service itself.

      Rgds

      Jocelyn

      (0) 
  9. Timothy Hughes

    And for what it is worth, this did not work either: @AbapCatalog.preserveKey: true, but it did change SQL view key back to semantic key.

    Take a look at any SQL View with “Default Aggregation”  (using SE11) — you see that all fields are key, but the “Generated_ID” will not be listed.

     

    (0) 
    1. Jocelyn Dart Post author

      Hi Tim, what I would advise is looking at how this problem is solved in delivered Fiori apps in S/4HANA – if you don’t have one perhaps grab a CAL Fully Activated Appliance to understand what is happening under the covers in a more advanced scenario than can be explained in a blog.

      https://blogs.sap.com/2017/12/14/sap-s4hana-1709-fully-activated-appliance-create-your-sap-s4hana-1709-system-in-a-fraction-of-the-usual-setup-time/

      My suspicion is that your approach may not be providing what you need because too much is being attempted in the one CDS view.  Typically CDS Views are layered into a Virtual Data Model approach.  Using those layers gives you the flexibility to combine transactional and analytical approaches.

      In any case, at this point your questions are too specific to be handled as blog comments.  So I recommend  creating a separate post with the details of your issue including the backend system release and SAPUI5 release in answers.sap.com.  That would also give the opportunity for some of our analytics experts to weigh in, rather than rely on a single blog author.

      Rgds

      Jocelyn

      (0) 
  10. Timothy Hughes

    I debugged it, and found enough to search OSS.   Unfortunately, I am on 7.50 not 7.52, but looks like this is fixed in 7.52 SP 1.

    I will request a downport… who knows.

    Tim

     

    (0) 
  11. Timothy Hughes

    EUREKA (sort of)

    After a ton of debugging, 30 seconds at a time, I have figured out that navigation works, IF all fields in ASSOCIATION condition are displayed in the List (not hidden) – in my case two of the fields are mandatory selection fields (so I didn’t display them)

    I guess it makes sense, as the association were passed as “$projection”.

    on   $projection.gjahr = _line.gjahr
    and $projection.monat = _line.monat
    and $projection.kostl = _line.kostl
    and $projection.hkont = _line.hkont

    As association fields (gjahr and monat), were not “projected” (the hidden key fields), the generated_id did not include those fields, and not retrieved by:

    if_sadl_gw_dpc_util~get_dpc)->get_keys_from_analytical_id(
               EXPORTING io_tech_request_context io_tech_request_context
               IMPORTING et_keys DATA(lt_keys).

    Sorry for adding so many comments to your blog…I need to look at alternative methods of association.

    -Tim

     

    (0) 
  12. Timothy Hughes

    Last comment.  Problem solved.

    Make sure all fields in the “on condition” ($projection or not) of an ASSOCIATION are specified (using Local Annotations) in:

    Local Annotations->UI.PresentationVariant->RequestAtLeast

    Thank you for all of your great posts.

    -Tim

    (0) 
    1. Jocelyn Dart Post author

      Glad you sorted it Tim!  And thanks for posting the solution… it’s always the non-obvious ones that are the most frustrating. But as you say it does make sense… with the benefit of hindsight!

      (0) 
  13. Gregor Wolf

    Hi Jocelyn Dart,

    I’ve added an Entity Set to our OData Service that return a hierarchy with annotations based on the section 2. Hierarchy using annotations of the blog post: TreeTable Odata binding. I want to consume that EntitySet on the ObjectPage of a Fiori Elements List Report Application. For that I’ve followed the example provided in Setting the Table Type. My sap.ui.generic.app section looks like this:

    "sap.ui.generic.app": {
    	"_version": "1.3.0",
    	"pages": {
    		"ListReport|ObdlvryhdrSet": {
    			"entitySet": "ObdlvryhdrSet",
    			"component": {
    				"name": "sap.suite.ui.generic.template.ListReport",
    				"list": true
    			},
    			"pages": [
    				{
    					"entitySet": "ObdlvryhdrSet",
    					"component": {
    						"name": "sap.suite.ui.generic.template.ObjectPage",
                            "settings": {
                                "sections": {
                                    "ToSalesdocFlow::com.sap.vocabularies.UI.v1.LineItem": {
                                        "navigationProperty": "ToSalesdocFlow",
                                        "entitySet": "SalesdocumentFlowSet",
                                        "tableType": "TreeTable"
                                    }
                                }
                            }							
    					},
    					"pages": {
    						"ObjectPage|ToObdlvryitm": {
    							"navigationProperty": "ToObdlvryitm",
    							"entitySet": "ObdlvryitmSet",
    							"component": {
    								"name": "sap.suite.ui.generic.template.ObjectPage"
    							}
    						}
    					}
    				}
    			]
    		}
    	}
    },

    The SalesdocumentFlowSet content is displayed, but only in a normal Responsive Table and not in a TreeTable. Do you have any hint for me? Is there anywhere a full documentation of sap.ui.generic.app?

    Best regards
    Gregor

    (0) 
    1. Jocelyn Dart Post author

      Hi Gregor

      Ok so your manifest.json looks fine. However if the Fiori element is not happy with the hierarchy annotations it will default to a responsive table.   Similarly if you render the table on a phone treetable setting will be ignored.

      Those references are rather old.. you might want to cross check against the latest annotations reference for hierarchy annotations https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/1709%20002/en-US/23473e6a8b1c4da2b0ba5be4f319a16c.html

      This one on how the OData aggregation is interpreted also explains more about the grouping and filtering behaviour that is also related to hierarchy usage.

      https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/1709%20002/en-US/f352ab0a8fda4e3b8262927074f0b0c1.html

      No we do not provide public documentation for sap.ui.generic.app itself nor are their any plans to do so. The template itself is updated very frequently.  We do provide documentation for using the annotations.

      I agree there’s not much publically on the hierarchy annotations themselves. If I find a hint I’ll add some more.

      Rgds

      Jocelyn

      (0) 
      1. Jocelyn Dart Post author

        Hi Gregor,

        Ok so with the latest versions the manifest.json has changed a little and you can try this approach instead:

                                    "name""sap.suite.ui.generic.template.ObjectPage"
                                    "settings": {
                                        "sections": {
                                            "to_ProductText::com.sap.vocabularies.UI.v1.LineItem": {
                                                "navigationProperty""to_ProductText",
                                                "entitySet""STTA_C_MP_ProductText",
                                                "treeTable"true
        Also there are some mandatory annotation properties that are required to support tree hierarchy.. so your annotations file should be describing these something like this example:
        <Property Name="HIERARCHY_NODE" Type="Edm.String" Nullable="false" MaxLength="32" sap:hierarchy-node-for="HIERARCHY_NODE"/> // Odata annotation: sap:hierarchy-node-for
        <Property Name="LEVEL" Type="Edm.Int32" sap:hierarchy-level-for="HIERARCHY_NODE"/>                                          //Odata annotation: sap:hierarchy-level-for
        <Property Name="PARENT_NODE" Type="Edm.String" MaxLength="32" sap:hierarchy-parent-node-for="HIERARCHY_NODE"/>              // Odata annotation: sap:hierarchy-parent-node-for
        <Property Name="DRILLDOWN_STATE" Type="Edm.String" MaxLength="16" sap:hierarchy-drill-state-for="HIERARCHY_NODE"/>          // Odata annotation: sap:hierarchy-drill-state-for
        Let me know how you go… could be a great blog to write yourself  😉
        Rgds
        Jocelyn

         

        (0) 
  14. Monika Juyal

    Hi Jocelyn,

    I am using a list report with responsive table. Is there any way to merge duplicate via annotations in CDS, If not how to achieve this functionality?

    Thanks in advance.

    Regards,

    Monika

    (0) 
  15. August Engkilde

    Hello Jocelyn,

    Thank you for this informative blog post.
    I have a Question concerning I have made a List inside a fiori elements object page using Local annotation in the Web IDE.  ( I has to be local because we ae merging data from SRM and ECC in the samme service )
    By default the list has a Navigation arrow at the end of each line item.

    How do I remove this?

    Normally in Ui5 I can set list item type to “Inactive ” and the will solve it.
    but how is this done using Annotation ?

    Best

    August

    (0) 

Leave a Reply