Skip to Content

Prerequisites

Make sure you have been to the previous blog of this blog series.

OVP list card introduction

OVP list card displays data in form of a list. OVP list card are of two types:

  1. extended – shows from 1 up to 4 attributes/values in up to 2 rows
  2. condensed – shows from 5 up to 6 attributes/values in up to 3 rows

List card can have a bar flavour in which data is represented as a bar chart in one row, supported in both extended and condensed list cards.

Standard List card – Standard flavour card present 3 fields, on the left side it shows the first 2 DataFields and on the right side it presents the first DataPoint if exist or the third DataField

Standard List card – Bar flavour card present 3 fields, on the top left side it shows the first data field and on the bottom, it presents the first DataPoint value in a bar and the second DataPoint on the right side of the bar if exist

Extended list card – Standard flavour card present up to 6 fields, on the left side it shows the first 3 DataFields and on the right side it presents the first 3 DataPoint. If No DataPoint exists or less then 3, the next data field will be used instead. For example, if only one DataPoint exist, the Forth and Fifth DataFields will be used to the right side, below the first DataPoint

Extended list card – Bar flavour card present 5 fields, on the top left side it shows the first 2 DataField and on the bottom, it presents the first DataPoint value in  a bar and the second and third DataPoint on the right side of the card if exist

OVP table card introduction

OVP table card represents the data in tabular format. OVP table card presents 3 fields, the data in the three columns are filled according to the importance and the order in which they are specified in the annotation file.

Commonly used OVP card annotations

As we now know that all the Fiori elements templates including OVP used OData annotations extensively. It’s very important to understand which annotations should be used for what purpose. Some of the commonly used annotations used by OVP cards are:

com.sap.vocabularies.UI.v1.Identification

The identification term is usually used to retrieve information about card actions, OVP cards  support the following actions:

com.sap.vocabularies.UI.v1.DataFieldForAction

this is mapped to action defined in OData model like function imports. I will discuss more of it when I’ll be explaining stack or Quickview card.

com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation

this is used for intent base navigation actions. In simple words, intent-based navigation between two Fiori application hosted within the same Fiori launch pad using semantic object and semantic action of the Fiori application. I will discuss more about intent based navigation when I discuss navigation in forthcoming blog.

com.sap.vocabularies.UI.v1.DataFieldWithUrl

This is used for URL based navigation to an external application. I will discuss more about intent based navigation when I discuss navigation in forthcoming blog.

com.sap.vocabularies.UI.v1.SelectionVariant

In simple words, SelectionVariant annotation is used to filter the data.

<Annotation Term="com.sap.vocabularies.UI.v1.SelectionVariant" Qualifier="SP2">
   <Annotation Term="com.sap.vocabularies.Common.v1.Label" String="Where Customer Name is Asia High tech" />
   <Record>
      <PropertyValue Property="SelectOptions">
         <Collection>
            <Record>
               <PropertyValue Property="PropertyName" PropertyPath="CustomerName" />
               <PropertyValue Property="Ranges">
                  <Collection>
                     <Record>
                        <PropertyValue Property="Sign" EnumMember="com.sap.vocabularies.UI.v1.SelectionRangeSignType/I" />
                        <PropertyValue Property="Option" EnumMember="com.sap.vocabularies.UI.v1.SelectionRangeOptionType/EQ" />
                        <PropertyValue Property="Low" String="SAP" />
                     </Record>
                  </Collection>
               </PropertyValue>
            </Record>
         </Collection>
      </PropertyValue>
   </Record>
</Annotation>

The above annotation block will result in following filter URL parameter in OData query:

?$filter=CustomerName eq ‘SAP’

Also used to support requests to a parameterized entity set with input parameters.These filters and parameters are also considered while retrieving the KPI value for the Header section. I’ll discuss more about KPI values when I’m discussion header card section in next blog.

com.sap.vocabularies.UI.v1.PresentationVariant

PresentationVariant provides information about the sorting criteria applied on the entity set.

<Annotation Term="UI.PresentationVariant" Qualifier="SP2">
   <Annotation Term="com.sap.vocabularies.Common.v1.Label" String="Customer Name in Descending Order" />
   <Record>
      <PropertyValue Property="SortOrder">
         <Collection>
            <Record>
               <PropertyValue Property="Property" PropertyPath="CustomerName" />
               <PropertyValue Property="Descending" Boolean="true" />
            </Record>
         </Collection>
      </PropertyValue>
   </Record>
</Annotation>

The above annotation block will result in following filter URL parameter in OData query:

?$orderby=CustomerName desc

com.sap.vocabularies.UI.v1.DataPoint

Used to provide the KPI title, formatting options including number formatting, criticality (colour) and the trend in the card header section. I’ll discuss more about KPI values when I’m discussion header card section in next blog.

Table and List card specific annotations

Table and list card use the com.sap.vocabularies.UI.v1.LineItem annotation, to display values. you can use different com.sap.vocabularies.UI.v1.LineItem annotation for different cards instances of the same entity type by using different qualifiers, and setting the annotationPath property with the qualifier in the card configuration. for example com.sap.vocabularies.UI.v1.LineItem#Qualifier1 and com.sap.vocabularies.UI.v1.LineItem#Qualifier2.

At run time, the line item records are sorted according to importance, set in the com.sap.vocabularies.UI.v1.ImportanceType annotation, and their order of entry, and each card uses different number of fields according this order.

The cards search for com.sap.vocabularies.UI.v1.DataFields and for com.sap.vocabularies.UI.v1.DataFieldForAnnotation that points to a com.sap.vocabularies.UI.v1.DataPoint.

DataPoints can be used in order to highlight specific value using the Criticality / CriticalityCalculation definition

Create your first OVP card

For this blog series, I won’t be using “add card” functionality of the OVP web IDE plugin because its difficult to take screenshots of every card configurations. rather you just need to copy the below code under “sap.ovp.cards” namespace in your manifest.json file:

"card01": {
				"model": "GWSAMPLE_BASIC", // model to which card should be bound
				"template": "sap.ovp.cards.list", // type of card i.e. list in this example.
				"settings": {
					"title": "{{card01_title}}", // card title
					"subTitle": "Standard List card - Standard flavour", // card subtitle
					"entitySet": "ProductSet", // entity to which card should be bound i.e. product in this example
					"listType": "condensed", // type of card i.e. condensed / extended
					"listFlavor": "standard", // card flovour i.e. standard or bar
					"sortBy": "Availability_Status", // Entity property by which data should be sorted
					"sortOrder": "Descending", // sorting order i.e. ascending or descending
					"annotationPath": "com.sap.vocabularies.UI.v1.LineItem", // path to com.sap.vocabularies.UI.v1.LineItem annotation
					"addODataSelect": true,
					"stopResizing": false,  // disable card resize on drag in resizable layout
					"defaultSpan": {
						"rows": 5, // number of rows visible
						"cols": 1, // number of columns, one column is around 320Px
						"showOnlyHeader": false // only card header will be visible
					}
				}
			}

Most of the card setting in the above code block is explained with comments. You can play with them and ask questions in the comment section in case you have any. But I cannot satisfy my conscience without about the below settings:

annotationPath: as explained above, list and table cards use LineItem annotation to display values, annotaionPath setting of the list of table card need the path to this annotation. In this case, LineItem annotation without any qualifier will be selected. You can also specify qualifier like LineItem#ReorderSoon, in this case, LineItem annotation with the qualifier ReorderSoon will be considered.

addODataSelect: We only need attributes which are specified in the LineItem annotation to display any card. But if this property is false and no SelectionVariant annotation is specified. Then no $select query will be added to the data call. Hence this setting is quite important from the performance perspective.

sortOrder and sortBy should be used in case of a simple sort condition. For complex sort scenarios, a PresentationVariant annotation can be used.

The above card will look for the following annotations from your annotation file:

<Annotation Term="com.sap.vocabularies.UI.v1.LineItem">
               <Collection>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Product ID" />
                     <PropertyValue Property="Value" Path="ProductID" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Product Name" />
                     <PropertyValue Property="Value" Path="Name" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Category" />
                     <PropertyValue Property="Value" Path="Category" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Supplier" />
                     <PropertyValue Property="Value" Path="SupplierName" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Unit Price" />
                     <PropertyValue Property="Value" Path="Price" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Weight" />
                     <PropertyValue Property="Value" Path="WeightMeasure" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Width" />
                     <PropertyValue Property="Value" Path="Width" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Depth" />
                     <PropertyValue Property="Value" Path="Depth" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataField">
                     <PropertyValue Property="Label" String="Height" />
                     <PropertyValue Property="Value" Path="Height" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataFieldForAnnotation" Qualifier="Price">
                     <PropertyValue Property="Label" String="Unit Price" />
                     <PropertyValue Property="Target" AnnotationPath="@com.sap.vocabularies.UI.v1.DataPoint#Price" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataFieldForAnnotation" Qualifier="WeightMeasure">
                     <PropertyValue Property="Label" String="Weight Measure" />
                     <PropertyValue Property="Target" AnnotationPath="@com.sap.vocabularies.UI.v1.DataPoint#WeightMeasure" />
                  </Record>
                  <Record Type="com.sap.vocabularies.UI.v1.DataFieldForAnnotation" Qualifier="Depth">
                     <PropertyValue Property="Label" String="Depth" />
                     <PropertyValue Property="Target" AnnotationPath="@com.sap.vocabularies.UI.v1.DataPoint#Depth" />
                  </Record>
               </Collection>
            </Annotation>
<Annotation Term="com.sap.vocabularies.UI.v1.DataPoint" Qualifier="Price">
               <Record Type="com.sap.vocabularies.UI.v1.DataPointType">
                  <PropertyValue Property="Title" String="Unit Price" />
                  <PropertyValue Property="Description" Path="Name" />
                  <PropertyValue Property="Value" Path="Price" />
                  <PropertyValue Property="ValueFormat">
                     <Record Type="com.sap.vocabularies.UI.v1.NumberFormat">
                        <!--<PropertyValue Property="ScaleFactor" Decimal="1000"/>-->
                        <PropertyValue Property="NumberOfFractionalDigits" Int="1" />
                     </Record>
                  </PropertyValue>
               </Record>
            </Annotation>
            <Annotation Term="com.sap.vocabularies.UI.v1.DataPoint" Qualifier="Stock_Availibility">
               <Record Type="com.sap.vocabularies.UI.v1.DataPointType">
                  <PropertyValue Property="Title" String="Stock Availibility" />
                  <PropertyValue Property="Description" Path="Name" />
                  <PropertyValue Property="Value" Path="Availability_Status" />
                  <PropertyValue Property="Criticality" Path="StatusCriticality" />
                  <!--<PropertyValue Property="ValueFormat">
                            <Record Type="com.sap.vocabularies.UI.v1.NumberFormat">
                                <PropertyValue Property="ScaleFactor" Decimal="1000"/>
                                <PropertyValue Property="NumberOfFractionalDigits" Int="1"/>
                            </Record>
                        </PropertyValue>-->
               </Record>
            </Annotation>
            <Annotation Term="com.sap.vocabularies.UI.v1.DataPoint" Qualifier="WeightMeasure">
               <Record Type="com.sap.vocabularies.UI.v1.DataPointType">
                  <PropertyValue Property="Title" String="Weight" />
                  <PropertyValue Property="Description" Path="Name" />
                  <PropertyValue Property="Value" Path="WeightMeasure" />
               </Record>
            </Annotation>
            <Annotation Term="com.sap.vocabularies.UI.v1.DataPoint" Qualifier="Depth">
               <Record Type="com.sap.vocabularies.UI.v1.DataPointType">
                  <PropertyValue Property="Title" String="Depth" />
                  <PropertyValue Property="Description" Path="Name" />
                  <PropertyValue Property="Value" Path="Depth" />
               </Record>
            </Annotation>

You can see that I have defined more than the required number of DataFields and DataPoints, but the condensed card created shows only 2 datafields and 1 datapoint. The order of this is default as the order in which they are defined in the annotations. But the default order can be altered using Importance annotation:

<Annotation Term="com.sap.vocabularies.UI.v1.Importance" EnumMember="com.sap.vocabularies.UI.v1.ImportanceType/Medium" />

Properties like the label inDataField and title in DataPoint is not valid for list card but in table car,d they will appear as the column header in list card.

I want you to create 3 more list cards just by changing listType and listTable and analyse which dataFileds and dataPoints are getting displayed in which type of list card. You should get the result like in the picture above with 4 list cards.

Creating a table card

The settings for the table card is almost the same as list card only the card template should be “table” instead of “list”.

"card05": {
				"model": "GWSAMPLE_BASIC",
				"template": "sap.ovp.cards.table",
				"settings": {
					"title": "{{card05_title}}",
					"subTitle": "{{card05_subTitle}}",
					"entitySet": "ProductSet",
					"addODataSelect": true,
					"defaultSpan": {
						"rows": 5,
						"cols": 1
					}
				}
			}

You might have noticed that I have not specified annotaionPath in card setting but its still rendering the values because it’s taking the value of default Identification annotation without any qualifier.

Conclusion

We have successfully understood the behaviour of list and table card, some general annotation used in OVP and annotations used by table and list cards. We have also created 4 list card each of different type and flavour and 1 table card.

Next is what?

In the next blog, I will discuss more card header like view switch, KPI etc, annotations used in card header. stay connected !!

Related Blogs

Overview Page (OVP) Card headers

Overview Page (OVP) Card navigation and authorization

 

To report this post you need to login first.

Be the first to leave a comment

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

Leave a Reply