Useful ABAP CDS Annotations
This is the collection of Framework-specific ABAP CDS annotations used often during application implementation. Framework specific annotations are interpreted by variety of SAP software components like OData, UI and Analytics operating with ABAP CDS as data model. Annotations can be added within CDS views, entities, table functions and metadata extensions to elements, parameters, at the header level before the define
statement. These annotations control the consumer framework behaviour.
For detailed explanation and syntax read List of all ABAP CDS framework annotations.
UI
The official definition is:
Represent semantic views on business data through the use of specific patterns that are independent of UI technologies.
Okay, but how much other Front-end frameworks like UI5 / Fiori is actually understands it ?…
From application development perspective simply use them to control the Fiori Element templates to render the required layout.
This section contains common and tricky annotations. The whole list of UI annotations for oData v4 with illustration can be found here.
Hiding UI Elements
@UI.hidden: true Parentkey;
Actions on tables with batch control
This comes very handy when you have a table in a Fiori Elements List report, and enabled selection of multiple lines in manifest.json
. Such way You can execute an Action in one shot for more items in the table.
However by default the actions are processed separately for each line. To group them via OData batch changeset processing, use the invocationGrouping
property. As result the RAP behavior implementation method of the action is called at once with all the keys, not separately for those items.
You can place the action within the metadata extension before the first element.
Works also for tables on the object page.
@UI.lineItem: [ { type: #FOR_ACTION, label: 'Confirm', dataAction: 'confirm', invocationGrouping: #CHANGE_SET } ]
Adding a column to a table
Whenever You need to add a field to the list report or to a table on the object page, do it with lineitem annotation.
@UI: { lineItem: [{ position: 10 }] } ProductId;
Object Page
Action on Object Page
You can place – a RAP action called post
, which is defined in the behavior for example – on the Object Page Header. Place this annotation in front of the first element within the metadata extension.
@UI.identification: [ { type: #FOR_ACTION, label: 'Post Document, dataAction: 'post' } ]
Generic rule that fields cannot be simply assigned to an object page via annotations. They are embedded by using facets, which refer to a container holding the fields.
Adding a Status Field to the Header
First define a facet before the first element as reference to a data point
@UI.facet: [ { purpose: #HEADER, type: #DATAPOINT_REFERENCE, id: 'idStatus', targetQualifier: 'hdrStatus' } ]
Then add the field to the facet
@UI.dataPoint: { qualifier: 'hdrStatus', title: 'Status', criticality: 'StatusCriticallity' } @UI.textArrangement: #TEXT_ONLY Status;
Tip: do not forget to calculate the criticality as integer. We used StatusCriticality
to hold that.
Adding fields to the header
You can add fields without any decoration to the header like this, grouping them together at the same time.
First define the field group placed at the header.
@UI.facet: [ { purpose: #HEADER, type: #FIELDGROUP_REFERENCE, position: 10, targetQualifier: 'Dates' } ]
Add fields to the group
@UI.fieldGroup: [{ position: 10, qualifier: 'Dates' }] ManufacturedOn; @UI.fieldGroup: [{ position: 20, qualifier: 'Dates' }] ShelfLifeExpiry;
Adding fields to identification (form part)
To simply add fields to a the predefined formular of Fiori Elements utilize the identification annotation. The identification form is placed after the header without grouping.
@UI: { identification: [{ position: 10 }]} ProductId;
Tip: use named field groups and collections to group fields together.
Adding table to object page
Define a facet mentioning the association to the child entity to be displayed in a table (on the Object Page).
@UI.facet: [ { id: 'Quantities', purpose: #STANDARD, type: #LINEITEM_REFERENCE, label: 'Quantities', position: 20, targetElement: '_Quantity' } ]
Consumption
Interpretation of the CDS Content by domain specific frameworks.
Value Help
Two things are here two emphasize. First is the additionalBinding
which makes possible to define context dependent value helps. Second is the usage
, which tells whether the other fields in the same entity serve as input/output as well for the value help.
Tip: @Consumption.valueHelpDefinition.useForValidation
can be used to validate user input against the list of values the help is providing. Note: use it in combination with few entries which are preloaded on page load by Fiori Elements and rendered as combobox. You can do this by adding annotation @ObjectModel.resultSet.sizeCategory: #XS
to the CDS entity on header level.
define view entity C_MyEntity as projection on I_MyEntity { key entityKey, ParentKey, RootKey, ValidityStart, Order, @Consumption.valueHelpDefinition: [{ entity:{name: 'I_OrderItem_VH', element: 'ItemNr' }, additionalBinding: [{ localElement: 'Order', element: 'DocumentNr', usage: #FILTER_AND_RESULT }] }] Item, ...
ObjectModel
As ABAP Programming Model for Fiori with BOPF is getting obsolete with new releases, so it is mainly used nowadays only for defining text elements for code values.
Tell which CDS element holds the text of the given code/id element.
@ObjectModel.text.element: [ 'CodeFieldText' ] @UI.textArrangement: #TEXT_FIRST CodeField, _Char.Descr as CodeFieldText,
Semantics
These annotations are telling the consumer framework the purpose of the annotated element. These annotations are consumed by core frameworks like Analytics or RAP runtime engine. Some annotations are also translated via SADL to OData annotations.
Administrative Data
Telling frameworks like RAP to maintain administrative data for the given fields automatically. The timestamps technical type must be like domain tzntstmpl
.
@Semantics.user.createdBy: true created_by as CreatedBy, @Semantics.systemDateTime.createdAt: true created_at as CreatedAt, @Semantics.user.lastChangedBy: true last_changed_by as LastChangedBy, @Semantics.systemDateTime.lastChangedAt: true last_changed_at as LastChangedAt, @Semantics.systemDateTime.localInstanceLastChangedAt: true local_last_changed_at as LocalLastChangedAt,
Consider field as boolean
You can tell about a character field with length 1 – knowing it contains top most an ‘X’ 🙂 – that it should be considered as a flag. As result Fiori Elements will display for example (based on the translated OData annotation) Yes / No on the UI.
@Semantics.booleanIndicator: true
Orphan annotations
Static Text / Description
Labels and tooltips example.
@EndUserText.label: 'Yummy' @EndUserText.quickInfo: 'Not for Cats' DogFood;
Share this content: