Skip to Content
Technical Articles

Fiori Elements – How to Develop a List Report – Using Local Annotations

Latest Update November 2020: 

It’s hard to believe that 4 years have passed since I first started blogging on SAP Fiori elements.

Since then it has grown from strength to strength. SAP Fiori elements apps are now the:

  • Preferred choice for SAP Fiori apps delivered for SAP S/4HANA
    • As at November 2020 nearly 900 of the more than 2K apps available are SAP Fiori elements app
  • Preferred and recommended choice for efficient development of your own custom-built apps
  • Preferred build approach for many of our customers… see the SAP TechEd 2020 session: Yorkshire Water uses SAP Fiori Elements to build Fiori apps quickly

The tooling has also changed from SAP Web IDE on SAP Cloud Platform Neo, to the next generation tooling SAP Fiori Tools.  SAP Fiori Tools are an extension of SAP Business Application Studio on SAP Cloud Platform Cloud Foundry that guide you through creating your own SAP Fiori elements apps – and they can be run offline on VSCode too.

So it’s time for this blog post to step gracefully aside and instead refer you to the current best resources for Fiori elements, including:

One last big hint: One of the most beneficial additions to the official documentation is the SAP Fiori elements feature map which explains what is available per floorplan for your SAPUI5 version – definitely worth a read!

But hey, all knowledge has value so if you want to read how this used to work in the SAP Web IDE… read on!


In Fiori Elements – Develop a List Report Basic Approach we looked at the simplest way to create a List Report using an OData service based on a purpose built CDS view with all of the annotations pre-set.  In this blog we look at alternate approach when you have an OData service without any pre-set annotations.  You can also use this approach to override or supplement pre-set annotations.

Find other Fiori Elements blogs on the Fiori Elements wiki

What are annotations?

In my first blog I described them as … “comments on the OData service that provides the data”.

The official OData site gives them a formal definition as:

Metadata annotations can be used to define additional characteristics or capabilities of a metadata element, such as a service, entity type, property, function, action or parameter.”

I find it more helpful to think of them as adding formalised semantic meaning to OData entities. In other words the annotations describe the purpose and intent of the OData entity and its attributes in a way that can be used directly by programs (and, happily, humans).

As mentioned in previous blogs, annotations are an optional part of OData.  The available annotations are described using an OData vocabulary.  For example, SAP has a vocabulary of all annotations that can be used in ABAP CDS views.  Some of these annotations are UI annotations that we can use to build our List Report.  Other annotations have other purposes such as @OData.Publish:true which exposes a CDS view as an OData Service. When it comes to UI Annotations, there are quite a lot of them… so we’ll start with a focus on the essentials for List Reports.

Creating a Fiori Element List Report with Annotations XML

Before we start, it’s worth noting that while its UI annotations let us control most of the List Report, not everything can be controlled by UI annotations. Certain features depend on what the OData Service itself provides, e.g. we can only provide a keyword search in the List Report Filter bar if the OData Service EntitySet contains the semantic marker sap:searchable=”true”. Features such as create, update, delete are provided in a similar way.

So how does using an annotations XML file change our process for creating a List Report which in Fiori  Elements – How to develop a List Report – Basic Approach as:

  1. Prepare the OData service
  2. Prepare the UI Annotations
  3. Create the Fiori App using the Fiori Elements List Report template

The pre-requisites are still the same, and the process itself is essentially the same, it’s just a slight change in the order of the steps:

  1. Prepare the OData service
  2. Create the Fiori App using the Fiori Elements List Report template
  3. Prepare the UI Annotations

So to show how this works, we’ll start with an OData Service without any UI annotations.  To demonstrate that this is really the only difference we will again use an OData Service based on a CDS view, although as mentioned in my previous blog, CDS views are not a pre-requisites – just very easy to use.

This time our OData Service is similar to our previous example but without any UI annotations and looks like this:

Creating the Fiori App in the HCP Web IDE using the Fiori Elements List Report wizard works exactly the same way. The only difference is which service and entity we select for the report. Now if you are using a SAP system that supports annotations it will still show you an annotation file, it’s just that the file will be generated with a  very basic XML structure.

Because there are no annotations yet, if you run the Component.js file of your app it will look something like this:

Working with the Annotations XML file

To work with our local annotations file we first need to check we have one. If you have used the wizard then it should exist already, but not everyone has access to HCP Web IDE or Personal Web IDE, so let’s review again where this lives in the recommended SAPUI5 app structure.

In our app we should see a folder called “annotations”. This should be a sub-folder of “webapp”.  If not we can always create one, e.g. using the context menu of folder “webapp” and selecting New > Folder.

Next we check there is a file called annotations.xml in our project’s annotations folder. If not we can create one using the context menu of folder “annotations” and selecting New > Annotation File.

Tip: It’s important to use the New > Annotation file wizard, and not just create the file using New > File.  The Annotation file wizard will not only create an annotations xml file, it will fill it with the basic edmx tags needed to start annotating. This is an example of an annotations.xml file generated this way:

The annotation file wizard will also update the manifest.json file to make sure our app:

  1. Knows where the annotation file sits in the project hierarchy and exactly what the file is called
  2. Knows where to find text resources ( related to your annotations file
  3. Links the OData Service to the related annotation xml file

As a reminder, we looked at the manifest.json file and its contents in the Fiori  Elements – How to develop a List Report – Basic Approach blog.

Tip: The annotations file doesn’t need to be called annotations.xml – although it does need to be a XML file.  If we use a different file name then we need to adjust the manifest.json file to match.

We can edit the annotations file directly using the Code Editor or, in the HCP Web IDE, we can use the Annotation Modeler tool. The Annotation Modeler uses a HCP Web IDE plugin so it is only available in the HCP Web IDE, so it’s always worth knowing the XML format itself.  In this blog for simplicity we will show the annotation modeler and related XML snippets.

You’ll find XML snippets for the different annotations in the SAPUI5 SDK in the section Developing Apps with SAP Fiori Elements > Annotations Relevant for List Reports and Object Pages, and Annotations Relevant for List Reports.

Annotations of the Fiori Element List Report

We can see in the SAPUI5 SDK that there are several UI annotations relevant to the List Report, but fortunately there are only 3 we need to create a basic List Report and these are:

  • UI.HeaderInfo – for the list table header
  • UI.LineItem – for the list table contents
  • UI.SelectionFields – for the filter bar fields

They relate to the List Report as follows:

Before we add any annotations our annotations.xml file looks like this in the annotation modeler.

In the Code Editor, if we’ve used the Fiori Elements List Report wizard, the relationship to our OData Service will already be added to the  tag of our annotations.xml file and will look like this:

All of our following annotations will need to be placed within a <Schema> tag for our OData Entity Set within the <edmx:DataServices> tag like this:

We use the + icon in the action columns to add extra annotations.

Adjusting the UI.HeaderInfo Annotations

The easiest annotation to add is the UI.HeaderInfo that adds the description and count to the table header of our List Report.  All we need to do is to enter the mandatory fields TypeName and TypeName Plural.  We can see in the Key Information column that these are immediately added to i18n property files.

It’s also mandatory to enter a value for the Title annotation which is a child of UI.HeaderInfo. This annotation will actually be used for the related Object Page which will we cover in a future blog.

In the code editor these annotations will look like this:

Adjusting the UI.LineItem Annotations

The UI.LineItem annotations denote which fields should be columns in our list report table.  There are different types of columns we can use – text, numbers, date/time, amount with currency, quantity with unit, urls, buttons, rating stars, progress bars, etc.  Once again we start with the simplest approach which is to use simple typed data fields, such as text and number fields.  For this we select the + action next in the UI.LineItem and choose the child annotation DataField.

In the DataField annotation we use the Value dropdown select the matching entity attribute and add a Label for the column header. The annotation modeler automatically adds the Labels to the @i18n properties file, or we can select an existing text from the file for our Label. We repeat this for as many columns as we want to add.

In the code editor these annotations will look like this:

Adjusting the UI.SelectionFields Annotations

We add the fields we want in our filter bar in the UI.SelectionFields annotations.  We use the SelectionFields dropdown to select attributes of our EntitySet. We use the Add Path option to add more filter fields.

In the code editor these annotations will look like this:

Running the app

Having saved all the UI annotations we have added, we can now run our App from the Component.js file. It should look like this:

Once again it’s a fully functioning production quality List Report app, complete with personalization settings (check out the gear wheel icon at the top right of the table) so users can adjust the filters, sort order, and groupings.

Basic vs. Alternate Approach

So which approach is preferred – basic approach or local annotations? Certainly if you have an environment capable of producing annotated CDS views and you are creating views explicitly for a given list report it makes sense to keep the annotations aligned against the CDS view. Otherwise local annotations work just fine.

In the next blog we’ll look at how we can make the list report even more useful.  We can control features such as the table type, single or multi-selection of rows, filter variant management, and default sort order.

We can also add some graphical visualizations to make the information in our report easier to understand such as thumbnail images, status icons, rating stars and progress bars.   These are techniques we’ll be able to reuse when we look at the Object Page in a future blog.

You must be Logged on to comment or reply to a post.
    • Yes! That's Object Page... only holding off a little as that gets us into deeper architecture discussions which will make more sense once we've discussed codeless navigation options

  • Really a great tutorial. Thank you for that. I already waited for something like this.

    When I implemented an application with my own OData service everything worked fine except displaying the texts from ResourceModel ( The texts are simply not available even though ResourceModel is defined in manifest.json, texts are available in and annotation definition looks ok (see here for screenshots).
    Any ideas?

    Thanks Helmut

    • Hi Helmut
      ok so I'm guessing you created you project structure & manifest.json by hand? Brave!
      When we generate using the wizard the i18n model itself is referenced with thd model name @i18n in the manifest.json as well.  Do that & your references to @i18n properties should come through
      Let us know how you go

      • Hi Jocelyn,
        I also used the wizard to create the app.
        It created the i18n model like this (without the @):

        "i18n": {
        "type": "sap.ui.model.resource.ResourceModel",
        "uri": "i18n/"

        When I changed the model name to "@i18n" the texts were displayed. Already wondered about the strange i18n model name :-D.

        Thanks a lot

          • Thanks for the information.

            I added the model @i18n to the manifest.json file and it worked correctly.

            "models": {
            "i18n": {
            "type": "sap.ui.model.resource.ResourceModel",
            "uri": "i18n/"
            "@i18n": {
            "type": "sap.ui.model.resource.ResourceModel",
            "uri": "i18n/"


            Best Regards,


  • Hi Jocelyn,

    This is an awesome post and really helpful.

    I want to ask is there something different to be done when creating the application using a local mock service(Mock service created using edmx file).

    I created the List Report application using template and my mock service. I then tried to create the local annotation by following your blog but was unable to do so using the Annotation Modeller wizard as it was not detecting my local service.I then manually added the schema of the service in code editor of the Annotation modeler and was able to create annotations.

    The manifest.json  file was also updated accordingly to pick the annotation file.

    But when I test the application using Mock data the annotation file is not picked up. I had to manually add the column in the application.

    Can you please suggest if there is something different to be done when creating application using local Mock service?

    This would be really helpful as many folks are working on Demo apps,using the local mock service,to approach the respective clients.


  • Excellent article Jocelyn.
    It was very useful for me to decide which approach to take between "Local UI Annotations" and "Service UI Annotations".

    Best Regards,


  • Thank you for the great intro Jocelyn,

    i am currently working on some CDS on S/4HANA 1610 SP0 and run into issues with aggreations and the List Report Viewer.

    After some investigation the List Report Template seems to always use an OData merge select of the used columns and also the columns defined as UI.LineItem.

    If i later change visible columns to aggregate only on one column and get the @Agregation SUM for netvalue, i will get a lot of rows, because the odata request selects always all ListItem columns even if they are not shown on UI Table?!?

    Is this by design or mayber a bug?

    My current solution is skip using ListItems and later on add them manually, but from my point of view this is a bug and should be handled in the fiori list report viewer app, because you will get the wrong results using default ListItem.

    For me the ListItem should only define the initial set of shown columns, but when i change them and store the new set as variant in the LREP, i would expect the correct results.

    Maybe you are also familar with this topic and knows if this is a bug or behaves by design (for a reason that i do not know 😉

    Regards Holger

    • Hi Holger,

      Hmmm... I am not sure if I have understood you?

      Can you give some code examples or screenshots?

      Have you tried setting the annotations in the CDS view or metadata extension of a CDS view to see if that resolves  your concern?



  • Thanks for the post Jocelvn.

    I am trying to implement UI annotation for smart table - the requirement is to restrict the columns appearing in the table personalization button. This I am trying to do by setting sap:visible to true. But where I need to do this is not clear.

    In backend oData entity I could not find any property like sap:visible (unlike for updatable, creatable, etc.). Also in UI annotations, I could not find any option like visible (unlike headerInfo, LineItem, etc.).

    Could you please help me in the same please.




    • Hmmm... ok Bhoomika.

      I would suggest that most CDS experts would say the best way to do that would be NOT to include it in your ABAP CDS Consumption View in the first place.  After all that is kind of why we have the layers of Dictionary table refined by Interface view refined by Consumption view.

      However if you really need it in your Consumption View for technical reasons you could try @UI.Hidden as per Field Hiding

    • Hi Neil,

      That is something I am currently working on.  As a hint… table types are handled in a few ways:

      1. In the CDS view the view may be marked as an aggregation – this flips the table type to “grid”
      2. You can override the table type in the manifest.json file… with restrictions
      3. Tree hierarchy tables are a special kind of grid table when you set a GroupBy presentationvariant. This lets you display totals and subtotals for instance

      More info in the SAPUI5 SDK



    • Hi Lars,

      There actually is - you can specify that the data is loaded immediately on entry to the transaction rather than pressing go.

      You can do this by using the UI Adaptation editor in the Web IDE as I explain in Fiori elements - export to MS Excel via the UI Adaptation Editor and using it to select the smart table and change Enable Auto Binding to true.

      HOWEVER be careful before setting this that you have considered the performance implications as the size of your data grows.  If the user may need to filter the data anyway you could have them waiting a while for nothing.




  • Hi Jocelyn,


    I have applied Intent based navigation to open another Fiori App to one of my fields in the CDS view . But I need to open the new app with multiple selection already applied . Eg: The new app is opened by clicking on document number but the document which should open in FB03 should be selected by doc no + fiscal Year + company code and then open up . Can you provide an update how this can be achieved as i am not able to provide more than 1 key during navigation from cds view.




  • Hi Jocelyn,

    Thank you very much for the detailed and nice description.

    In one of my project I am using the List Report template where I do need to format the time in Hour:Minute:Second format. Say for example we are getting data from odata only in minutes. So how to and where to plugin the formatter function for this.

    Thank you in advance.

  • Hi Jocelyn,

    I am trying to build a navigation from List report line item document number to some other app - i.e have document number as link

    Snippet from local annotations  in UI.LineItem-

    <Annotation Term="UI.LineItem">
         <Record Type="UI.DataField">
    <Record Type="UI.DataFieldForIntentBasedNavigation">
         <PropertyValue Property="SemanticObject" String="MySalesOrder"/>
         <PropertyValue Property="Inline" Bool="true"/>
         <PropertyValue Property="Label" String="Manage"/>
         <PropertyValue Property="Action"  String="display"/>

    Doesn't work. ofcourse I am missing something, but didn't find any blog/reference/KBA  - Can you please help ?

    I am using all local annotations in annotation modeler with xsodata, No ABAP CDS.



    • Hi Tanveer

      One for another day...  short version... all of the properties of that row are passed as parameters, plus the header content and some other stuff.

      In the Launchpad Designer, you configure a tile catalog with a tile to your app, and a target mapping to the app *and* to the intent you used for your inline button.  When you configure the target mapping to the inline button, the parameter names are whatever the target app uses, and the parameter values reference the properties of your list.

      Try comparing it to some of the delivered tile catalogs - any of the Manage apps should do - and you'll get the idea

      Good luck!



        HI Jocelyn,

        Thanks for reply –  I understand the part of launchpad designer but I think I am missing something from List Report annotations side.

        I used UI.DataFieldForIntentBasedNavigation under UI.LineItem, is that correct ? any other annotations I need to add ? Can this be done without extension ? What All configs will be required in maifest.json ? Also, how to make document number field the 'hyperlink'  type look ?

        Thanks for your help !




        • Hi Tanveer,

          You can use DataFieldForIntentBasedNavigation or DataFieldWithIntentBasedNavigation - "for" shows it as a button, the "with" variation turns the field into a hyperlink.

          No you do not need extensions.

          Use the outbounds section within in the manifest.json to define your navigation parameters for the Semantic Object.  Find out more here Configuring Navigation

          I'll try and get a blog out explaining more soon.



          • Hi Jocelyn ,

            I'll try and get a blog out explaining more soon.

            I am desperatly looking for a blog or a tutorial to show how to achieve intent based navigation from one custom Fiori Elements app (list/object) to another custom Fiori Elements app (preferarbly to the object page) without resorting to extension programming.

            Did you already wrote such an blog and I just did not find it?

            Are you aware of such an example/blog/tutorial?




    Hi Jocelyn,

    Great Blog, Thank you so much for sharing the knowledge, I have created a report with the list report template and i have a requirement to display a text message on the report , and keep it forever on the report just like a note or something like that, Is there any way to do so?




    • Hi Pradeep, That sounds like you need to write some data back to the database so it is kept? Then you want to look at changing your read only List Report to a read/write transactional app using BOPF as per the ABAP Programming model for SAP Fiori. Take a look at the tutorial Developing New Transactional Apps 

      Good luck!


      • Just another thought - technically you could also use an inline action in the table and a breakout extension to do that.   However that requires more knowledge and skill to pass the field to an OData Service function to store it.

      • HI Jocelyn,

        Thank you for the reply and i do not have to write back to the database, i just want display a  message on top of the report, i mean a text on UI from the controller like "The date expires on this month end" something like that on somewhere on the report, since it is a smart list report template i have extended the controller to write custom functions, so i am fetching validity from the odata service and i just want to put the validity date somewhere on the report.


        Thanks in advance,


        • Hi Pradeep

          Definitely need to look at an extension breakout then.  Perhaps this one about Adding Custom Messages?

          If you get it working, please blog it!




            Hi Jocelyn,


            Extending a controller and Action to a list report is worked for me, I have done changes as follows:

            		"extends": {
            			"extensions": {
            				"sap.ui.controllerExtensions": {
            					"sap.suite.ui.generic.template.ListReport.view.ListReport": {
            						"controllerName": "MyReport.ext.controller.ListReportExt",
            						"": {
            							"EntitySetName": {
            								"EntitySet": "EntitySetName",
            								"Actions": {
            									"ReportDate": {
            										"id": "ReportDate",
            										"text": "",
            										"press": "onPressReportDate"
            									"ActionEntitySetName1": {
            										"id": "Actionbutton",
            										"text": "{@i18n>Action1}",
            										"press": "onDownload",
            										"requiresSelection": false
            In controller extension onInint method:
            this.getView().byId("ReportDate").setText("My Text");


            I am just adding a text to action button ReportDate which will display on the table and on press i am routing to corresponding App.


            Thanks for the help Jocelyn ?


            Best Regards,


          • Great - please write a blog on what you did !  And let me know ... I'll add it into our Fiori elements wiki so you will be recognized there as well!

    • Hi Akshaya

      Thanks for the encouragement!

      How to configure navigation is explained in the SAPUI5 SDK documentation below.

      Good luck!


      • Hi Jocelyn


        I read the document. I have added another pages array in manifest and the navigation carousel appears but in the next navigated page, though I have configured to display a table, nothing comes up. Do you have any examples to help?

  • Hi Jocelyn,

    I have created a list report and bound to an oData entity set. But in my table the data group is repeating on scroll. The batch is called again on scroll. Can you help?

    • Hi Akshaya

      Please use blog comments only for comments on the blog itself. If you have related issues raise them in with the appropriate tags such as Fiori or SAP Fiori for SAP S/4HANA.

      And always give us the context of your query - such as what SAPUI5 version are you on, what release system is your OData Service running on, is it a SAP or non-SAP OData Service,  if it's a SAP OData Service did you create it in transaction SEGW or using a CDS View.

      One big tip - always test your OData Service independently of your UI - if the OData Service does not behave correctly, then of course the Fiori app that is running on top of that won't work correctly either.  So test and fix the OData Service first.

      Hope that helps


  • HI Jocelyn  Nice post, could you help me with this doubt  ( How to navigate to a list report calling a Saved User Variant ? )


  • Hi Jocelyn,


    Thank you for the information, It was really helpful.


    I am facing one issue with selection fields description,  In my case the selection field name is "BELNR" (The same name is coming from odata service) But I wanted to add a field description for BELNR. I have tried with Label

    The generated code is :

    <Annotation Term="UI.SelectionFields">
    <PropertyPath>BELNR<Annotation Term="Common.Label" String="{@i18n&gt;ACCOUNTING_DOCUMENT_NUMBER}"/>


    But it is not working, I am unable to see the selection field on the screen after adding the label. Could you please help me in this?




    • Hi Srilaxmi, Please post your question to and include your SAPUI5 version and S/4HANA version with tag SAP Fiori for SAP S/4HANA

      It is very difficult to answer questions like this directly in blog comments.



  • Hello,

    I am not able to get Compact Filter F4 help List in Analytical List Pages, it showing as only Define Condition not as a Select from list.

    But it should come like below,

    <Annotation Term="UI.SelectionFields">


    <Annotation Term="Common.ValueList" Qualifier="CF">
    <Record Type="Common.ValueListType">
    <PropertyValue Property="CollectionPath" String="ZC_BU_POITEMKPI_C002"/>
    <PropertyValue Property="PresentationVariantQualifier" String="FilterByPurchasingOrganization"/>
    <PropertyValue Property="Parameters">
    <Collection >
    <Record Type="Common.ValueListParameterInOut">
    <PropertyValue Property="LocalDataProperty" PropertyPath="PurchasingOrganization"/>
    <PropertyValue Property="ValueListProperty" String="PurchasingOrganization"/>
    <Record Type="Common.ValueListParameterOut">
    <PropertyValue Property="LocalDataProperty" PropertyPath="PurchasingOrganization"/>
    <PropertyValue Property="ValueListProperty" String="PurchasingOrganization"/>
    <Record Type="Common.ValueListParameterIn">
    <PropertyValue Property="LocalDataProperty" PropertyPath="PurchasingOrganization"/>
    <PropertyValue Property="ValueListProperty" String="PurchasingOrganization"/>
    <PropertyValue Property="Label" String="Filter By Purch. Organization"/>
    <PropertyValue Property="SearchSupported" Bool="true"/>
    <PropertyValue Property="CollectionRoot" Path="PurchasingOrganization"/>


    Please suggest how I will achieve this.



  • Great blog. All works fine when test run from SAP CLoud Web IDE. However when we deploy to Gateway system on-prem annotation file doesn’t load. Below is a screen shot.

    Have used option from menu to add annotation and not manually

    Cloud Web IDE test run


    From Fiori Launchpad


    • Hi Kevin,

      Please post your question to and include your SAPUI5 version that you are using and details of your Gateway system version. Remember your Gateway system needs to be on at least 7.51 SP01.

      It's possible the problem is in deploying the app to the SAPUI5 repository - you might want to check if you can see the file in the matching BSP application in transaction SE80.

      It is very difficult to answer specific issues like this directly in blog comments and I unfortunately I just don't have time to check on blog comments every day.  Generally on there are more people with more experiences to help you.



  • Hi Jocelyn,

    I have been through a few of your blogs and they are of great information. But one thing I am struggling to find is the system compatibility of Fiori Elements and local Annotations with the Backend ECC System. For example if I build a Fiori Elements App in Web IDE with the Local Annotations as you have highlighted in this blog and Deploy to ECC System 7.4 will it work? OR is there a Minimum Version of SAP that is needed for all the Local Web IDE Annotations to function?

  • Hi Jocelyn,

    is the building of sums or sub totals althought possible without CDS views. I managed to get the filter, the grouping and sorting to work with fiori elements list report, on an ERP System EHP8 but i am not able to somehow do a sumation.

    Any suggestions or experience with it?