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.
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.
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.
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:
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.
No comments:
Post a Comment