Skip to content

Feature Showcase App Guide

Jes Sie Cheah edited this page Dec 14, 2022 · 6 revisions

Tips on how to use this Guide:

When you see a feature that you would like to implement, copy or take note of the search term (e.g., #SearchTermExample) and perform a search here. You will be presented with

  • a short description of the feature,
  • code snippets and where to find them in the source code,
  • and in some cases, a link to the official RAP documentation for more information.

Alternatively, you can search for an annotation here, get the search term, and use it to locate the UI feature in the app. If the annotation cannot be found, it could simply mean that it is not showcased in the current release.

Content

List Report - Header Area

Define Filters

Default Values

Search term: #FilterDefault

With the annotation @Consumption.filter.defaultValue default values can be defined. This Annotation does not allow complex values and when switching variants, the annotation is no longer considered. For complex values the @UI.selectionVariant annotation is a better solution.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@Consumption.filter.defaultValue: '3' // Search term #FilterDefault
CriticalityCode;

More information: ABAP RESTful Application Programming Model - Consumption Annotations

🔼 Back to Content


Hide Filters

Search term: #HideFilter

To reduce the amount of available filters in a List Report, properties can be annotated with @Consumption.filter.hidden: true to hide them.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

//Search Term: #HideFilter
@Consumption.filter.hidden: true
AreachartTolUpperboundValue;
  
@Consumption.filter.hidden: true
AreachartTolLowerboundValue;
  
@Consumption.filter.hidden: true
AreachartDevUpperboundValue;

@Consumption.filter.hidden: true
AreachartDevLowerboundValue;

🔼 Back to Content


Filter Facets

Search term: #FilterGrouping

Another nice feature is filter facet, which allows one to structure the available properties of the entity into groups, so that filter adaptation is easier.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [
  // Search term #FilterGrouping
  {
    purpose: #FILTER,
    type: #FIELDGROUP_REFERENCE,
    targetQualifier: 'chartData',
    label: 'Chart Data (#FilterGrouping)'
  },
  // Search term #FilterGrouping, #Location
  {
    purpose: #FILTER,
    type: #FIELDGROUP_REFERENCE,
    targetQualifier: 'location',
    label: 'Location (#FilterGrouping)'
  }
]

@UI.fieldGroup: [{ qualifier: 'chartData' }] // Search term #FilterGrouping
IntegerValue;

@UI.fieldGroup: [{ qualifier: 'chartData' }] // Search term #FilterGrouping
ForecastValue;

@UI.fieldGroup: [{ qualifier: 'chartData' }] // Search term #FilterGrouping
TargetValue;

@UI.fieldGroup: [{ qualifier: 'chartData' }] // Search term #FilterGrouping
Dimensions;

🔼 Back to Content


Selection Fields

Search term: #VisibleFilters

@UI.selectionField is the annotation which allows one to specify an array of fields, which should by default be shown in the List Report filter bar as a filter, so that the user does not need to adapt the filters.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.selectionField: [{ position: 10 }] // Search term #VisibleFilters
StringProperty;

@UI.selectionField: [{ position: 20 }] // Search term #VisibleFilters
FieldWithPrice;

@UI.selectionField: [{ position: 30 }] // Search term #VisibleFilters
IsoCurrency;

@UI.selectionField: [{ position: 40 }] // Search term #VisibleFilters
CriticalityCode;

More information: ABAP RESTful Application Programming Model - Adding Selection Fields

🔼 Back to Content


Value Help

Search term: #ValueHelps, #DependentFilter

The implementation of a value help in CDS enables the end user to choose values from a predefined list for input fields on a user interface.

The additional binding defines a second condition for the value help on the same target value help provider entity for filtering the value help result list and/or returning values from the selected value help record. The additional binding can be defined for an additional element or parameter. Depending on the value provided in usage, the additional binding works as a filter, result or filter and result condition

Usage: #Result: The referenced element or parameter in localElement or localParameter is filled with the value provided by the value help. When creating an instance, you can fill various fields with this option.

ℹ️ Source: CDS View /DMO/FSA_R_RootTP

// Search Term #ValueHelps
@Consumption.valueHelpDefinition: [
  { entity: { name: '/DMO/FSA_I_Criticality', element: 'Code' },
    additionalBinding: [{ element: 'Name', 
                          localElement: 'FieldWithCriticality', 
                          usage: #RESULT }] }]
CriticalityCode,

Usage: #Filter : The value of the referenced element or parameter in localElement or localParameter is used as a filter for the value help. The value help only displays filtered results.

// Search Term #DependentFilter
@Consumption.valueHelpDefinition: [{ 
   entity: { name: '/DMO/FSA_I_Contact', element: 'ID' },
             label: 'Contacts',
             additionalBinding: [{ element: 'Country',
                                   localElement: 'Country',
                                   usage: #FILTER }] }]
ContactID,

You can influence what is shown in the value help using @Consumption.valueHelpDefault.display. In the example below, everything except for ID (Name), phone, country, street, city and postcode would be hidden in the value help.

ℹ️ Source: CDS View /DMO/FSA_I_Contact

define view entity /DMO/FSA_I_Contact
...
{
      @ObjectModel.text.element: ['Name'] // Search Term #DisplayTextAndID
      @UI.textArrangement: #TEXT_ONLY
      @EndUserText.label: 'Contact'
  key id            as ID,

      @Consumption.valueHelpDefault.display:false 
      name          as Name,

      @Consumption.valueHelpDefault.display:true 
      phone         as Phone,

      @Consumption.valueHelpDefault.display:false 
      building      as Building,

      @Consumption.valueHelpDefault.display:true 
      country       as Country,

      @Consumption.valueHelpDefault.display:true 
      street        as Street,

      @Consumption.valueHelpDefault.display:true 
      city          as City,

      @Consumption.valueHelpDefault.display:true 
      postcode      as Postcode,

      @Consumption.valueHelpDefault.display:false 
      address_label as AddressLabel,

      @Consumption.valueHelpDefault.display:false 
      photo_url     as PhotoUrl,
      ...
}

For smaller collections of possible values in the value help, it might be a good idea to have a dropdown instead of a dialog to choose the value. This can be achieved with the @ObjectModel : { resultSet.sizeCategory: #XS }

ℹ️ Source: CDS View /DMO/FSA_I_Criticality

@ObjectModel : { resultSet.sizeCategory: #XS }

define view entity /DMO/FSA_I_Criticality
...

More Information: ABAP RESTful Application Programming Model - Providing Value Help


List Report - Content Area

Configuring Tables

Actions - List

Search term: #ActionInLineItem

With this @UI.lineItem annotation, the action is displayed above the table on the right, with other possible actions.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #ActionInLineItem
@UI.lineItem: [{
  type:#FOR_ACTION,
  label: 'Change Criticality (#ActionInLineItem)',
  dataAction: 'changeCriticality',
  position: 10
}]
LastChangedAt;

ℹ️ Source: Behaviour Definition /DMO/FSA_R_RootTP

action changeCriticality parameter /DMO/FSA_D_ChangeCriticalityP result [1] $self;

A regular action requires a line item to be selected before the button is activated but a static action is always active.

More information: ABAP RESTful Application Programming Model - Actions

🔼 Back to Content


Value Help for action parameter

Search term: #ValueHelpParameter

Often properties of an entity have value helps, so that creating a new entity is easier and wrong inputs are reduced. Value helps for action parameters are also possible.

ℹ️ Source: CDS Abstract Entity /DMO/FSA_D_ChangeCriticalityP

// Search Term #ValueHelpParameter
@Consumption.valueHelpDefinition: [{ entity: { name: '/DMO/FSA_I_Criticality',  element: 'Code' }}]
criticality_code : abap.int4;

This can be achieved, by just annotating the parameter with @Consumption.valueHelpDefinition.

🔼 Back to Content


Default Value for action parameter

Search term: #ParameterDefaultValue

With the annotation @UI.defaultValue a default value for the parameter is set. A fixed string value can be given or a property from the entity can be reference using syntax #( 'ELEMENT_OF_REFERENCED_ENTITY: <field_name>' ).

ℹ️ Source: CDS Abstract Entity /DMO/FSA_D_ChangeCriticalityP

// Search Term #ParameterDefaultValue
@UI.defaultValue : #( 'ELEMENT_OF_REFERENCED_ENTITY: CriticalityCode')
criticality_code : abap.int4;

🔼 Back to Content


Navigation Button

Search term: #Navigation-IBN

An action navigating to a published app of an associated entity can be added, through Intent Based Navigation using @UI.lineItem. When the navigation is setup properly, a button will be rendered at the table toolbar. Since this feature requires Fiori Launchpad and a destination app that has been published, the following is just an example of how it can be coded, as this navigation does not work in a FE App Preview.

Here "FeatureShowcaseNavigation" is the semantic object to be referenced.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Tern #Navigation-IBN
@Consumption.semanticObject: 'FeatureShowcaseNavigation'
@UI.lineItem: [{
  label: 'IntentBased Navigation (#NavAction-IBN)',
  type: #FOR_INTENT_BASED_NAVIGATION,
  semanticObjectAction: 'manage',
  requiresContext: true
}]
NavigationID;

More information: ABAP RESTful Application Programming Model - Based on Intent

🔼 Back to Content


Presentation Variant - List Report

Search term: #PresentationVariant

A presentation variant defines how the result of a queried collection of entities is shaped and how this result is displayed, for example as a list report or a chart (@UI.presentationVariant.visualizations), the sorting order (@UI.presentationVariant.sortOrder), or the number of items (@UI.presentationVariant.maxItems) to display per segment.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #PresentationVariant
@UI.presentationVariant: [
  {
    qualifier: 'pvariant',
    maxItems: 5,
    // Search Term #DefaultSort
    sortOrder: [
      {
        by: 'StringProperty',
        direction: #ASC
      }
    ],
    visualizations: [{type: #AS_LINEITEM}]
  }
]

🔼 Back to Content


Selection Variant - List Report

Search term: #SelectionVariant

With a selection variant, you can define how the properties of an entity set should be filtered. The attribute text of the annotation is the title of the view and the attribute filter contains all filter parameters.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #SelectionVariant
@UI.selectionVariant: [
  {
    qualifier: 'svariant',
    text: 'Selection (Criticality between 0 and 2)',
    filter: 'CriticalityCode GE 0 and CriticalityCode LE 2'
  }
]

🔼 Back to Content


Selection Presentation Variant - List Report

Search term: #SelectionPresentationVariant

A SelectionPresentationVariant bundles a Selection Variant and a Presentation Variant.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.presentationVariant: [
  {
    qualifier: 'pvariant',
    maxItems: 5,
    // Search Term #DefaultSort
    sortOrder: [
      {
        by: 'StringProperty',
        direction: #ASC
      }
    ],
    visualizations: [{type: #AS_LINEITEM}]
  }
]

@UI.selectionVariant: [
  {
    qualifier: 'svariant',
    text: 'Selection (Criticality between 0 and 2)',
    filter: 'CriticalityCode GE 0 and CriticalityCode LE 2'
  }
]

// Search Term #SelectionPresentationVariant
@UI.selectionPresentationVariant: [
  {
    text: 'SPresVariant (Criticality between 0 and 2)',
    presentationVariantQualifier: 'pvariant',
    selectionVariantQualifier: 'svariant'
  }
]

🔼 Back to Content


Defining the Default Sort Order

Search term: #DefaultSort

Use the @UI.presentationVariant annotation to define a default sort order. The attribute by defines, on which property the sort order should be applied.

Without a sort order defined with direction, the values are ascending.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.presentationVariant: [
  {
    // Search Term #DefaultSort
    sortOrder: [
      {
        by: 'StringProperty',
        direction: #ASC
      }
    ]
  }
]

🔼 Back to Content


Handling Semantic Key Fields

Search term: #SemanticKey

Semantic Key fields can be defined, with the annotation @ObjectModel.semanticKey, which consists of an array of properties from the entity. The given fields will be displayed in bold, and when possible the editing status will be displayed.

ℹ️ Source: CDS View /DMO/FSA_R_RootTP

// Search Term #SemanticKey
@ObjectModel.semanticKey: ['StringProperty']

🔼 Back to Content


Highlighting Line Items Based on Criticality

Search term: #LineItemHighlight

Line items can be highlighted based on criticality. The @UI.lineItem annotation should be annotated at Entity level.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #LineItemHighlight
@UI.lineItem: [{criticality: 'CriticalityCode'}] // Annotation, so that the line item row has a criticality

🔼 Back to Content


Adding a Rating Indicator to a Table

Search term: #DataPointRatingTable

To add a rating indicator (stars) to the table, you first need to define a datapoint with @UI.dataPoint. The property where datapoint is defined sets how many stars are visible. Values between x.25 and x.74 are displayed as a half star. The attribute targetValue defines how many stars are possible. Most importantly, the qualifier needs to match the property name.

To show it in the table, @UI.lineItem annotation is needed.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI: { 
  // Search Term #DataPointRating, #DataPointRatingTable
  dataPoint: {
    qualifier: 'StarsValue',
    targetValue: 4,
    visualization: #RATING,
    title: 'Rating Indicator (#DataPointRating)'
  },
  // Search Term #DataPointRatingTable
  lineItem: [
    {
      type: #AS_DATAPOINT,
      label: 'Rating Indicator (#DataPointRatingTable)',
      importance: #LOW,
      position: 70
    }
  ]
}
StarsValue;

Example: ABAP RESTful Application Programming Model - Develop Node Extensions - Extension Node with Rating

🔼 Back to Content


Adding a Progress Indicator to a Table

Search term: #DataPointProgressTable

To add a progress indicator to the table, you first need to define a datapoint with @UI.dataPoint. The property where datapoint is defined sets the current progress and the attribute targetValue, the maximum progress. Additionally, a criticality can be given, if wanted. Most importantly, the qualifier needs to match the property name.

To show it in the table, @UI.lineItem annotation is needed.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #DataPointProgress, #DataPointProgressTable
@UI: {
  dataPoint: {
    qualifier: 'ProgressIntegerValue',
    targetValue: 100,
    visualization: #PROGRESS,
    criticality: 'CriticalityCode',
    title: 'Progress Indicator (#DataPointProgress)'
  },
  // Search Term #DataPointProgressTable
  lineItem: [
    {
      type:#AS_DATAPOINT,
      label: 'Progress Ind. (#DataPointProgressTable)',
      importance: #LOW,
      position: 60
    }
  ]
}
ProgressIntegerValue;

Example: ABAP RESTful Application Programming Model - Develop Node Extensions - Extension Node with Progress

🔼 Back to Content


Adding a Smart Micro Chart to a Table

Bullet Micro Chart - Table

Search term: #BulletMicroChartTable

To add a bullet micro chart to a table you have to first define a data point at the property where the value is to be taken from, which is the actual bar. The following attributes are also mandatory: minimumValue to render the chart properly, forecastValue for the bar in the background with a lower opacity, targetValue (or targetValueElement) for the dark line and qualifier (qualifier must be set to the name of the property). Criticality is optional.

To show the chart, the property must then be annotated with @UI.lineItem.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

/// Search Term: #BulletMicroChart, #BulletMicroChartTable
@UI: {
  dataPoint: {
    qualifier: 'IntegerValue', //IntegerValue: horizontal bar in relation to the goal line
    targetValueElement: 'TargetValue', //visual goal line in the UI
    forecastValue: 'ForecastValue', //horizontal bar behind the value bar with, slightly larger with higher transparency
    criticality: 'CriticalityCode',
    minimumValue: 0 //Minimal value, needed for output rendering
  },
  // Search Term #BulletMicroChartTable
  lineItem: [{
    type:#AS_CHART,
    label: 'Bullet Chart (#BulletMicroChartTable)',
    valueQualifier: 'bulletChart',
    importance: #HIGH,
    position: 80
  }]
}
IntegerValue;

The data point needs to be referenced in a @UI.chart annotation in the measure attributes. The chartType must have value #BULLET for a bullet chart, attributes measures and measureAttributes are mandatory.

// Search Term #BulletMicroChart, #BulletMicroChartTable
@UI.chart: [{
  qualifier: 'bulletChart',
  title: 'Bullet Micro Chart (#BulletMicroChart)',
  description: 'This is a micro chart',
  chartType: #BULLET,
  measures: ['IntegerValue'],
  measureAttributes: [
    {
      measure: 'IntegerValue',
      role: #AXIS_1,
      asDataPoint: true
    }
  ]
}]

🔼 Back to Content


Radial Micro Chart - Table

Search term: #RadialMicroChartTable

To add a radial micro chart to a table you have to first define a data point at the property where the value is to be taken from. The percentage value is the fraction of the property value and the target value, which is set in attribute targetValue (or targetValueElement). Both criticality and criticalityCalculation are supported, but if both are given criticality overrides criticalityCalculation. Qualifier must be set to the name of the property.

To show the chart, the property must then be annotated with @UI.lineItem.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #RadialMicroChart, #RadialMicroChartTable
@UI: {
  dataPoint: {
    qualifier: 'RadialIntegerValue',
    targetValueElement: 'TargetValue', //The relation between the value and the target value will be displayed as a percentage
    criticality: 'CriticalityCode'
  },
  // Search Term #RadialMicroChartTable
  lineItem: [
    {
      type: #AS_CHART,
      label: 'Radial Chart (#RadialMicroChartTable)',
      valueQualifier: 'radialChart',
      position: 110
    }
  ]
}
RadialIntegerValue;

The data point needs to be referenced in a @UI.chart annotation in the measure attributes. The chartType must have value #Donut for a radial chart, attributes measures and measureAttributes are mandatory.

// Search Term #RadialMicroChart, #RadialMicroChartTable
@UI.chart: [{
  qualifier: 'radialChart',
  title: 'Radial Micro Chart (#RadialMicroChart)',
  description: 'This is a micro chart',
  chartType: #DONUT,
  measures: ['RadialIntegerValue'],
  measureAttributes: [
    {
      measure: 'RadialIntegerValue',
      role: #AXIS_1,
      asDataPoint: true
    }
  ]
}]

🔼 Back to Content


Adding a Contact Quick View to a Table

Search term: #ContactInHeader, #ContactInLineItem, #Contact

To have a data field which shows a contact with a contact quick view, the contact quick view needs to be implemented first. An example would be:

ℹ️ Source: CDS View /DMO/FSA_I_Contact

// Search Term #Contact
define view entity /DMO/FSA_I_Contact
{
      @ObjectModel.text.element: ['Name'] // Search Term #DisplayTextAndID
  key id            as ID,

      @Semantics.name.fullName: true
      name          as Name,

      @Semantics.telephone.type: [#PREF]
      phone         as Phone,

      @Semantics.address.country: true
      country       as Country,

      @Semantics.address.street: true
      street        as Street,

      @Semantics.address.city: true
      city          as City,

      @Semantics.address.zipCode: true
      postcode      as Postcode,

      @Semantics.address.label: true
      address_label as AddressLabel
}

To show the contact card in the table you need to annotate the contact property with @UI.lineItem or if in a facet, with @UI.fieldGroup.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [{
  purpose    : #HEADER, // or #STANDARD
  label      : 'General Data (#HeaderFieldGroup)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'HeaderData'
}]

// Search Term #ContactInHeader
@UI.fieldGroup: [{
  qualifier: 'HeaderData',
  type: #AS_CONTACT,
  label: 'Contact QuickView (#ContactInHeader)',
  position: 50,
  value: '_Contact'
}]

// Search Term #ContactInLineItem
@UI.lineItem: [{
  type:#AS_CONTACT,
  label: 'Contact QuickView (#ContactInLineItem)',
  value: '_Contact',
  position: 120
}]
ContactID; 

More Information: ABAP RESTful Application Programming Model - Contact Data

🔼 Back to Content


Adding a Quick View Facet to a Table

Search term: #QuickView

A quick view facet is a pop up for when you click on an entry in a column and get more information. Typically, it is used in combination with one-to-one associations, where the association name is displayed in the column. By clicking on the link, more information about the association entity can be displayed. To enable a quick view facet, the association entity needs to be annotated with @UI.facet with type: #QUICK_VIEW. For a better looking header of the quick view, the association entity gets typically annotated with @UI.headerInfo.

ℹ️ Source: CDS View /DMO/FSA_I_Navigation

@UI.headerInfo: {
  typeName: 'Navigation',
  typeNamePlural: 'Navigations',
  title.value: 'StringProperty',
  description.value: 'StringProperty',
  typeImageUrl: 'sap-icon://blank-tag'
}

@UI.facet: [{
  type: #FIELDGROUP_REFERENCE,
  label: 'Navigation',
  targetQualifier: 'data',
  purpose: #QUICK_VIEW
}]

@UI.fieldGroup: [{ qualifier: 'data', position: 10 }]
string_property  as StringProperty,

@UI.fieldGroup: [{ qualifier: 'data', position: 20 }]
integer_property as IntegerProperty,

@UI.fieldGroup: [{ qualifier: 'data', position: 30 }]
decimal_property as DecimalProperty,

Additionally, the key value can be replaced with another text property, so that the column is readable.

@ObjectModel.text.element: ['StringProperty'] // Search Term #DisplayTextAndID
key id               as ID, 

To show a property with QuickView, it should be annotated with @Consumption.semanticObject and either @UI.fieldGroup or @UI.lineItem.

// Search Term #QuickView
@UI.facet: [{
  purpose    : #HEADER, // or #STANDARD
  label      : 'General Data (#HeaderFieldGroup)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'HeaderData'
}]

@Consumption.semanticObject: 'FeatureShowcaseNavigation'
@UI.fieldGroup: [{
  qualifier: 'HeaderData',
  position: 40,
  label: 'Navigation (#QuickView)'
}]
      
// Search Tern #QuickView
@UI.lineItem: [{ 
  label: 'Navigation (#QuickView)',
  importance: #HIGH,
  position: 90
}]
NavigationID;

🔼 Back to Content


Adding Multiple Fields to one Column in a Table

Search term: #MultiFieldsCol

Multiple fields can be shown in one column, if a field group is added to line item (with annotations @UI.lineItem and @UI.fieldGroup). First you must define the field group and secondly the line item.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.fieldGroup: [{ qualifier: 'AdminData' }] // Search Term #MultiFieldsCol
CreatedAt;

@UI.fieldGroup: [{ qualifier: 'AdminData' }] // Search Term #MultiFieldsCol
LocalLastChangedBy;

@UI.fieldGroup: [{ qualifier: 'AdminData' }] // Search Term #MultiFieldsCol
LocalLastChangedAt;

// Search Term #MultiFieldsCol
@UI: { 
  fieldGroup: [{ qualifier: 'AdminData' }],
  lineItem: [
    {
      type: #AS_FIELDGROUP,
      label: 'Admin Data (#MultiFieldsCol)',
      valueQualifier: 'AdminData',
      importance: #HIGH,
      position: 100
    }
  ]
}
CreatedBy;

🔼 Back to Content


Adding Images to a Table

Search term: #Image

Images are typically the first column in a table and help to visually guide the user. An image can be added to a table by just adding a normal property to the line items.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #Image
@UI.lineItem: [{
  cssDefault.width: '5em',
  position: 10,
  importance: #HIGH,
  label: '(#Image)'
}]
@EndUserText.quickInfo: '(#Image)'
ImageUrl;

The property which contains the image url has to, additionally, be annotated with @UI.imageURL: true.

ℹ️ Source: CDS View /DMO/FSA_I_Root

@Semantics.imageUrl: true
image_url                 as ImageUrl,

🔼 Back to Content


Adding Currency or UoM Fields to a Table

Search term: #Units

The special thing about quantity or price properties, is that they have an additional property of unit/currency. The property containing the quantity/price should be linked with the property for unit/currency. For units of measure the annotation is @Semantic.quantity.unitOfMeasure and for currency, it is @Semantic.amount.currencyCode.

ℹ️ Source: CDS View /DMO/FSA_I_Root

// Search Term #Units
@Semantics.quantity.unitOfMeasure: 'Uom'
field_with_quantity       as FieldWithQuantity,

// Search Term #Units
@Semantics.amount.currencyCode: 'IsoCurrency'
field_with_price          as FieldWithPrice,

More Information: ABAP RESTful Application Programming Model - Interaction with Other Annotations

🔼 Back to Content


Adding Large Object/Stream Property to a Table

Search term: #Stream, #StreamTable

You can enable your RAP application for maintaining large objects (LOBs). By doing so, you provide end users the option to incorporate external binary files or text files when editing entity instances. First the appropriate fields should be added into the database table and the CDS view, and also the annotations @Semantics.largeObject and @Semantics.mimeType. To show it in a table, you will need annotation @UI.lineItem. Lastly, you should also update the mapping and the draft table in your behaviour definition.

ℹ️ Source: Database Table /DMO/FSA_ChildA

stream_filename    : abap.char(128);
stream_mimetype    : abap.char(128);
stream_file        : abap.rawstring(0);

ℹ️ Source: CDS View /DMO/FSA_C_ChildTP

StreamFilename, // Search Term #Stream

// Search Term #Stream
@Semantics.largeObject: {
  acceptableMimeTypes: [ 'image/*', 'application/*' ],
  cacheControl.maxAge: #MEDIUM,
  contentDispositionPreference: #INLINE, // #ATTACHMENT - download as file
                                             // #INLINE - open in new window
  fileName: 'StreamFilename',
  mimeType: 'StreamMimeType'
}
StreamFile,

// Search Term #Stream
@Semantics.mimeType: true
StreamMimeType,

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

// Search Term #Stream
@UI.hidden: true
StreamMimeType;

@UI.lineItem: [{ position: 40, label: 'Attachment (#StreamTable)' }] // Search Term #StreamTable
StreamFile;

// Search Term #Stream
@UI.hidden: true
StreamFilename;

ℹ️ Source: BDEF /DMO/FSA_R_ROOTTP

define behavior for /DMO/FSA_R_ChildTP alias Child {
...
mapping for /dmo/fsa_child_a {
  ..
  StreamFile = stream_file;
  StreamFilename = stream_filename;
  StreamMimeType = stream_mimetype;
}

More Information on data modelling for Large Object: ABAP RESTful Application Programming Model - Working with Large Objects

🔼 Back to Content


Object Page - General Features

Annotations for Data Fields

Communication Properties

Search term: #CommunicationFields

To display emails and phone numbers as a link, they are annotated with @Semantics.email.address: true or @Semantics.telephone.type

ℹ️ Source: CDS View /DMO/FSA_I_Root

// Search Term #CommunicationFields
@Semantics.eMail.address: true
email                     as Email,

// Search Term #CommunicationFields
@Semantics.telephone.type: [#CELL]
telephone                 as Telephone,

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #Communication
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  label      : 'Communication Subsection(#Communication)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'communication'
}]

@UI.fieldGroup: [{ qualifier: 'communication' }] // Search Term #Communication
Email;

@UI.fieldGroup: [{ qualifier: 'communication' }] // Search Term #Communication
Telephone;

More Information: ABAP RESTful Application Programming Model - Contact Data

🔼 Back to Content


Time and Date

Search term: #TimeAndDate

SAP Fiori Elements provides out of the box support for displaying and editing dates and times, as well as time stamps. No additional annotations are needed, the properties just need to have the corresponding data types.

The following annotations are used in the app, in order to group the time and date fields and show them in a facet.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #TimeAndDate
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  label      : 'Time and Date (#TimeAndDate)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'timeAndDate'
}]

@UI.fieldGroup: [{ qualifier: 'timeAndDate' }] // Search Term #TimeAndDate
ValidTo;

@UI.fieldGroup: [{ qualifier: 'timeAndDate' }] // Search Term #TimeAndDate
Time;

@UI.fieldGroup: [{ qualifier: 'timeAndDate' }] // Search Term #TimeAndDate  
Timestamp;

🔼 Back to Content


Multi line Text

Search term: #MultiLineText

With the annotation @UI.multiLineText longer strings are displayed in multiple lines.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.multiLineText: true // Search Term #MultiLineText
Description;

@UI.multiLineText: true // Search Term #MultiLineText
DescriptionCustomGrowing;

More Information: ABAP RESTful Application Programming Model - Multi-Line Text

🔼 Back to Content


Collective Value Help

Search term: #CollectiveValueHelp

For SAP GUI-based applications it is possible to define a collective search help that combines several elementary search helps. You can choose one of several alternative search paths and retrieve input values from multiple sources/tables in a single dialog. In Fiori UI this is also possible via a collective value help using an abstract entity comprising a list of assigned elementary search helps and potential mappings of the bound field names.

The collective value help shall be annotated with @ObjectModel.collectiveValueHelp.for.element pointing to the field, for which the collective value help is defined. The field referenced by @ObjectModel.collectiveValueHelp.for.element shall be assigned at least a single elementary value help using annotation @Consumption.valueHelpDefinition.

ℹ️ Source: CDS Abstract Entity /DMO/FSA_D_CountryCVH

@EndUserText.label: 'Country Collective Value Help'

@ObjectModel.collectiveValueHelp.for.element: 'Country'

// Search Term #CollectiveValueHelp
define abstract entity /DMO/FSA_D_CountryCVH
{
  @Consumption.valueHelpDefinition:[
    // 'Default' VH
    { 
      entity: { name:'I_Country' },
      label: 'Search by Country' 
    },
    // additional VH, set qualifier
    { 
      entity: { name:'/DMO/FSA_I_ContactVH',
                element:'Country' },
      label: 'Search by Contact',
      qualifier: 'ContactSearch' 
    },
    // additional VH, set qualifier
    { 
      entity: { name:'I_RegionVH',
                element:'Country' },
      additionalBinding: [{ localElement:'Region',
                            element:'Region'  }],
      label: 'Search by Region',
      qualifier:  'RegionSearch' 
    }
  ]
  Country : land1;
  Region  : regio;
}

The consumer view of the collective value help has to define the same fields, that are used in the collective value help definition (respectively bind all corresponding local fields via @Consumption.valueHelpDefinition.additionalBinding... to the collective value help fields).

ℹ️ Source: CDS View /DMO/FSA_R_RootTP

// Search Term #CollectiveValueHelp
@Consumption.valueHelpDefinition: [{ entity: { name: '/DMO/FSA_D_CountryCVH',  element: 'Country' },
                                      additionalBinding: [{ element: 'Region', 
                                                            localElement: 'Region' }]  }]
Country,
...
Region,

🔼 Back to Content


Object Page - Header Area

Title and Subtitle

Search term: #HeaderInfo

The title and subtitle of an Object Page are defined with the annotation @UI.headerInfo.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #HeaderInfo
@UI.headerInfo: {
  typeName: 'Object Page - Root',
  typeNamePlural: 'Root Entities (#ListTableTitle)', // Search Term #ListTableTitle
  typeImageUrl: 'sap-icon://sales-order',
  imageUrl: 'ImageUrl',
  title: {
    value: 'StringProperty',
    type: #STANDARD
  },
  description: {
    label: 'Root entity',
    type: #STANDARD,
    value: 'StringProperty'
  }
}

The attribute typeName is the title and it is displayed next to the SAP Logo in header bar on the Object Page. The attribute typeNamePlural will be shown, if all entities are shown in a table. The attribute title is displayed as the header in the Object Page in bold. Attribute description is shown beneath title and if the optional imageUrl is given, then the picture will be visible on the left side of the title and description. If no url is given for the imageUrl, but typeImageUrl is defined, it will be displayed instead.

More Information:

🔼 Back to Content


Header Facets

Search term: #HeaderFacet

The header facet is displayed in the header of an Object Page. The facet is annotated with UI.facet.purpose: #HEADER.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [
  // OPHEADER
  // Search Term #HeaderFacet, #KeyValue
  {
    purpose: #HEADER,
    type: #DATAPOINT_REFERENCE,
    targetQualifier: 'fieldWithPrice'
  }
]

// Search Term #HeaderFacet, #KeyValue
@UI.dataPoint: {
  qualifier: 'fieldWithPrice',
  title: 'Field with Price (#HeaderFacet)'
}
FieldWithPrice;

More Information: ABAP RESTful Application Programming Model - Using Facets to change the Object Page Layout

🔼 Back to Content


Header Field Group Facet

Search term: #HeaderFieldGroup

Field groups can be part of a header.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #HeaderFieldGroup
@UI.facet: [{
  purpose: #HEADER
  label      : 'General Data (#HeaderFieldGroup)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'HeaderData'
}]

A quick view contact card can be displayed (#ContactInHeader). A quick view facet can be displayed by just adding the property as a data field (#QuickView). Both implementations are identical to how they would be added as a line item in a List Report.

// Search Term #HeaderFieldGroup
@UI.fieldGroup: [{
  qualifier: 'HeaderData',
  position: 10
}]
StringProperty;

// Search Term #ContactInHeader, #HeaderFieldGroup
@UI.fieldGroup: [{
  qualifier: 'HeaderData',
  type: #AS_CONTACT,
  label: 'Contact QuickView (#ContactInHeader)',
  position: 50,
  value: '_Contact'
}]
ContactID;

// Search Term #HeaderFieldGroup
@UI.fieldGroup: [{
  qualifier: 'HeaderData',
  criticality: 'CriticalityCode',
  position: 20
}]
FieldWithCriticality;

// Search Term #HeaderFieldGroup, #QuickView
@UI.fieldGroup: [{
  qualifier: 'HeaderData',
  position: 40,
  label: 'Navigation (#QuickView)'
}]
NavigationID;

🔼 Back to Content


Plain Text

Search term: #PlainText

Plain text can be displayed, by adding a standard property to a field group and using this field group as a target of a reference facet.

The property in the field group can be optionally annotated with @UI.MultiLineText, especially if you have a long text and would like it to be show in the UI as a multi-line text, with an expand/collapse button.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #PlainText
@UI.facet: [{
  purpose: #HEADER,
  type: #FIELDGROUP_REFERENCE,
  label: 'Plain Text (#PlainText)',
  targetQualifier: 'plainText'
}]

@UI: {
  // Search Term #PlainText
  fieldGroup: [ { qualifier: 'plainText' } ]
  // Search Term #MultiLineText
  multiLineText: true
}
Description;

More Information: ABAP RESTful Application Programming Model - Grouping Fields

🔼 Back to Content


Data Points

Rating

Search term: #DataPointRating

To add a rating indicator (stars) to the object page header, you first need to define a datapoint with @UI.dataPoint. The property where datapoint is defined sets how many stars are visible. Values between x.25 and x.74 are displayed as a half star. The attribute targetValue defines how many stars are possible. Most importantly, the qualifier needs to match the property name.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI: { 
  // Search Term #DataPointRating, #DataPointRatingTable
  dataPoint: {
    qualifier: 'StarsValue',
    targetValue: 4,
    visualization: #RATING,
    title: 'Rating Indicator (#DataPointRating)'
  }
}
StarsValue;

After creating the data point, it has to be added to the @UI.facet annotation.

@UI.facet: [{
  // Search Term #DataPointRating
  purpose: #HEADER, // or #STANDARD
  type       : #DATAPOINT_REFERENCE,
  targetQualifier: 'StarsValue'
}]

Example: ABAP RESTful Application Programming Model - Develop Node Extensions - Extension Node with Rating

🔼 Back to Content


Progress

Search term: #DataPointProgress

To add a progress indicator to the object page header, you first need to define a datapoint with @UI.dataPoint. The property where datapoint is defined sets the current progress and the attribute targetValue, the maximum progress. Additionally, a criticality can be given, if wanted. Most importantly, the qualifier needs to match the property name.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #DataPointProgress, #DataPointProgressTable
@UI: {
  dataPoint: {
    qualifier: 'ProgressIntegerValue',
    targetValue: 100,
    visualization: #PROGRESS,
    criticality: 'CriticalityCode',
    title: 'Progress Indicator (#DataPointProgress)'
  }
}
ProgressIntegerValue;

After creating the data point, it has to be added to the @UI.facet annotation.

@UI.facet: [{
  // Search Term #DataPointProgress
  purpose: #HEADER, // or #STANDARD
  type       : #DATAPOINT_REFERENCE,
  targetQualifier: 'ProgressIntegerValue'
}]

Example: ABAP RESTful Application Programming Model - Develop Node Extensions - Extension Node with Rating

🔼 Back to Content


Key Value

Search term: #KeyValue

A key value is the default data point, when the attribute visualization is not specified in @UI.dataPoint.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [
  // Search Term #Headerfacet, #KeyValue
  {
    purpose: #HEADER,
    type: #DATAPOINT_REFERENCE,
    targetQualifier: 'fieldWithPrice'
  }
]

@UI: {
  // Search Term #HeaderFacet, #KeyValue
  dataPoint: {
    qualifier: 'fieldWithPrice',
    title: 'Field with Price (#HeaderDataPoint)'
  }
}
FieldWithPrice;

🔼 Back to Content


Micro Chart Facet

The following micro charts are supported: Area, Bullet, Radial, Column, Line, Harvey, Stacked bar and Comparison. Micro charts can only be displayed in the header.

A micro chart is defined with the @UI.chart annotation, which then is the target of a ReferenceFacet in the @UI.facet of purpose: #HEADER. The title of the facet is the attribute title of the annotation and the subtitle is description. If the property of the data point is a property with unit of measure, the unit will be displayed in the footer. The attribute measures of the chart has to be a data point.

The @UI.dataPoint supports generally the attributes criticality and criticalityCalculation, but the support varies between the micro chart types. If the value of the data point is annotated with a unit of measure, the unit will be shown as the footer of the micro chart facet.

In the following examples, all used attributes are mandatory.


Area Micro Chart

Search term: #AreaMicroChart

The area micro chart is a trend chart, which provides information for the actual and target value for a specified dimension. The displayed values at the bottom of the chart are the boundary values of the dimension. The values above the chart are the boundary values of the measure attribute.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

@UI.chart: [
  // Search Term #AreaMicroChart
  { 
    qualifier: 'areaChart',
    title: 'Area Micro Chart (#AreaMicroChart)',
    description: 'This is a micro chart',
    chartType: #AREA,
    dimensions: ['Dimensions'],
    measures: ['IntegerValueForAreaChart'],
    measureAttributes: [
      {
        measure: 'IntegerValueForAreaChart',
        role: #AXIS_1,
        asDataPoint: true
      }
    ]
  }
]

The criticality calculation of the data point is mandatory, as each value is shown with its threshold (error, warning, acceptance and good) ranges.

// Search Term #AreaMicroChart
@UI.dataPoint: { 
  qualifier: 'IntegerValueForAreaChart',
  targetValueElement: 'TargetValue',
  criticalityCalculation: { 
    improvementDirection: #TARGET,
    toleranceRangeLowValueElement: 'AreachartTolLowerboundValue',
    toleranceRangeHighValueElement: 'AreachartTolUpperboundValue',
    deviationRangeHighValueElement: 'AreachartDevUpperboundValue',
    deviationRangeLowValueElement: 'AreachartDevLowerboundValue'
  }
}
IntegerValueForAreaChart;

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #AreaMicroChart
@UI.facet: [
  {
    purpose: #HEADER, // or #STANDARD
    type       : #CHART_REFERENCE,
    targetQualifier: 'areaChart',
    targetElement: '_Chart'
  }
]

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Bullet Micro Chart

Search term: #BulletMicroChart

The bullet chart features a single measure and compares it to one or more other measures (e.g. value with target comparison). Both criticality and criticalityCalculation are supported, but if both are given criticality overrides criticalityCalculation. The bullet chart does not support the criticality value of 5 (new item). The measuresAttributes, while it is mandatory, has no effect on the chart as the values come from datapoint.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

Chart

// Search Term #BulletMicroChart, #BulletMicroChartTable
@UI.chart: [
  {
    qualifier: 'bulletChart',
    title: 'Bullet Micro Chart (#BulletMicroChart)',
    description: 'This is a micro chart',
    chartType: #BULLET,
    measures: ['IntegerValue'],
    measureAttributes: [
      {
        measure: 'IntegerValue',
        role: #AXIS_1,
        asDataPoint: true
      }
    ]
  }
]

Facet

// Search Term #BulletMicroChart
@UI.facet: [
  {
    purpose: #HEADER, // or #STANDARD
    type       : #CHART_REFERENCE,
    targetQualifier: 'bulletChart'
  }
]

Data Point. The attribute minimumValue is needed to render the chart properly. The value is the actual bar. The forecastValue is the bar in the background with a lower opacity and the targetValue is the dark line. Qualifier must be set to the name of the property.

// Search Term: #BulletMicroChart
@UI.dataPoint: {
  qualifier: 'IntegerValue', //IntegerValue: horizontal bar in relation to the goal line
  targetValueElement: 'TargetValue', //visual goal line in the UI
  forecastValue: 'ForecastValue', //horizontal bar behind the value bar with, slightly larger with higher transparency
  criticality: 'CriticalityCode',
  minimumValue: 0 //Minimal value, needed for output rendering
}
IntegerValue;

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Radial Micro Chart

Search term: #RadialMicroChart

The radial micro chart displays a single percentage value. The measureAttributes, while mandatory, has no effect on the chart as the values come from datapoint.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

Chart

// Search Term #RadialMicroChart
@UI.chart: [
  {
    qualifier: 'radialChart',
    title: 'Radial Micro Chart (#RadialMicroChart)',
    description: 'This is a micro chart',
    chartType: #DONUT,
    measures: ['RadialIntegerValue'],
    measureAttributes: [
      {
        measure: 'RadialIntegerValue',
        role: #AXIS_1,
        asDataPoint: true
      }
    ]
  }
]

Facet

// Search Term #RadialMicroChart
@UI.facet: [
  {
    purpose: #HEADER, // or #STANDARD
    type       : #CHART_REFERENCE,
    targetQualifier: 'radialChart'
  }
]

Data Point. The percentage value is the fraction of the property value and the target value. The unit of measure label will not be rendered, as the chart displays percentage values. Both criticality and criticalityCalculation are supported, but if both are given criticality overrides criticalityCalculation. Qualifier must be set to the name of the property.

// Search Term #RadialMicroChart
@UI.dataPoint: {
  qualifier: 'RadialIntegerValue',
  targetValueElement: 'TargetValue', //The relation between the value and the target value will be displayed as a percentage
  criticality: 'CriticalityCode'
}
RadialIntegerValue;

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Line Micro Chart

Search term: #LineMicroChart

The line chart displays a series of data points as a line. The bottom values are the border values of the dimension. The upper left value is the smallest value of the first measures property and the upper right value is the largest value of the last measures property. The shown unit of measure is from the first entry.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

// Search Term #LineMicroChart
@UI.chart: [{ 
  qualifier: 'lineChart',
  title: 'Line Micro Chart (#LineMicroChart)',
  description: 'This is a micro chart',
  chartType: #LINE,
  measures: ['IntegerValueForLineChart', 'TargetValue'],
  dimensions: ['Dimensions'],
  measureAttributes: [
    { 
      measure: 'IntegerValueForLineChart',
      role: #AXIS_2,
      asDataPoint: true
    },
    { 
      measure: 'TargetValue',
      role: #AXIS_2,
      asDataPoint: true
    }
  ]
}]

Data Points. It is recommended to only use one measure, and a maximum of three measures, if more is required. If the attribute criticality contains a path, then the value of the last data point's criticality determines the color of the line.

// Search Term #LineMicroChart
@UI: {
  dataPoint: {
    qualifier: 'TargetValue',
    criticality: 'CriticalityCode'
  }
}
TargetValue;

// Search Term #LineMicroChart
@UI.dataPoint: { 
  qualifier: 'IntegerValueForLineChart',
  criticality: 'CriticalityCode'
}
IntegerValueForLineChart;

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #LineMicroChart
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #CHART_REFERENCE,
  targetQualifier: 'lineChart',
  targetElement: '_Chart'
}]

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Column Micro Chart

Search term: #ColumnMicroChart

A column chart uses vertical bars to compare values of a dimension. The displayed values at the bottom of the chart are the boundary values of the dimensions. The values above the chart are the boundary values of the measureAttributes.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

// Search Term #ColumnMicroChart
@UI.chart: [{ 
  qualifier: 'columnChart',
  title: 'Column Micro Chart (#ColumnMicroChart)',
  description: 'This is a micro chart',
  chartType: #COLUMN,
  measures: ['IntegerValueForOtherCharts'],
  dimensions: ['Dimensions'],
  measureAttributes: [
    { 
      measure: 'IntegerValueForOtherCharts',
      role: #AXIS_1,
      asDataPoint: true
    }
  ]
}]

Data Point. Both criticality and criticalityCalculation are supported, but if both are given criticality overrides criticalityCalculation.

// Search Term #ColumnMicroChart, #StackedBarMicroChart, #ComparisonMicroChart
@UI.dataPoint: { 
  qualifier: 'IntegerValueForOtherCharts',
  criticality: 'CriticalityCode'
}
IntegerValueForOtherCharts;

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #ColumnMicroChart
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #CHART_REFERENCE,
  targetQualifier: 'columnChart',
  targetElement: '_Chart'
}]

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Harvey Micro Chart

Search term: #HarveyMicroChart

A harvey chart plots a single measure value against a maximum value.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

Chart

// Search Term #HarveyMicroChart
@UI.chart: [
  {
    qualifier: 'harveyChart',
    title: 'Harvey Micro Chart (#HarveyMicroChart)',
    description: 'This is a micro chart',
    chartType: #PIE,
    measures: ['HarveyFieldWithPrice'],
    measureAttributes: [
      {
        measure: 'HarveyFieldWithPrice',
        role: #AXIS_1,
        asDataPoint: true
      }
    ]
  }
]

Data Point. For the semantic coloring, only the attribute criticality is supported.

//Search-Term: #HarveyMicroChart
@UI.dataPoint: {
  qualifier: 'HarveyFieldWithPrice',
  maximumValue: 5000,
  criticality: 'CriticalityCode'
}
HarveyFieldWithPrice;

Facet

// Search Term #HarveyMicroChart
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #CHART_REFERENCE,
  targetQualifier: 'harveyChart'
}]

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Stacked Bar Micro Chart

Search term: #StackedBarMicroChart

A stacked bar chart uses vertical bars to compare values of a dimension. The displayed values at the bottom of the chart are the boundary values of the dimensions. The values above the chart are the boundary values of the measureAttributes.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

// Search Term #StackedBarMicroChart
@UI.chart: [ {
  qualifier: 'stackedBarChart',
  title: 'StackedBar Micro Chart (#StackedBarMicroChart)',
  description: 'This is a micro chart',
  chartType: #BAR_STACKED,
  measures: ['IntegerValueForOtherCharts'],
  dimensions: ['Dimensions'],
  measureAttributes: [
    { 
      measure: 'IntegerValueForOtherCharts',
      role: #AXIS_1,
      asDataPoint: true
    }
  ]
}]

Data Point. Both criticality and criticalityCalculation are supported, but if both are given criticality overrides criticalityCalculation.

// Search Term #ColumnMicroChart, #StackedBarMicroChart, #ComparisonMicroChart
@UI.dataPoint: { 
  qualifier: 'IntegerValueForOtherCharts',
  criticality: 'CriticalityCode'
}
IntegerValueForOtherCharts;

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #StackedBarMicroChart
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #CHART_REFERENCE,
  targetQualifier: 'stackedBarChart',
  targetElement: '_Chart'
}]

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Comparison Micro Chart

Search term: #ComparisionMicroChart

A comparison chart uses three horizontal bars to compare values of a dimension. If more values are defined in dimensions, they will only show up in the tooltip. The displayed values on the left represent the dimension value of each data point. The values on the right are the actual values. If a unit of measure is shown, then it is from the first data point to be plotted.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

// Search Term #ComparisonMicroChart
@UI.chart: [{ 
  qualifier: 'comparisonChart',
  title: 'Comparison Micro Chart (#ComparisonMicroChart)',
  description: 'This is a micro chart',
  chartType: #BAR,
  measures: ['IntegerValueForOtherCharts'],
  dimensions: ['Dimensions'],
  measureAttributes: [
    { 
      measure: 'IntegerValueForOtherCharts',
      role: #AXIS_1,
      asDataPoint: true
    }
  ]
}]

Data Point. For semantic coloring, only the attribute criticality is supported.

// Search Term #ColumnMicroChart, #StackedBarMicroChart, #ComparisonMicroChart
@UI.dataPoint: { 
  qualifier: 'IntegerValueForOtherCharts',
  criticality: 'CriticalityCode'
}
IntegerValueForOtherCharts;

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #ComparisonMicroChart
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #CHART_REFERENCE,
  targetQualifier: 'comparisonChart',
  targetElement: '_Chart'
}]

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


Large Object/Stream Property

Search term: #Stream

You can enable your RAP application for maintaining large objects (LOBs). By doing so, you provide end users the option to incorporate external binary files or text files when editing entity instances. First the appropriate fields should be added into the database table and the CDS view, and also the annotations @Semantics.largeObject and @Semantics.mimeType. To show it in a standard or header facet, you will need annotation @UI.facet. Lastly, you should also update the mapping and the draft table in your behaviour definition.

ℹ️ Source: Database Table /DMO/FSA_ChildA

stream_filename    : abap.char(128);
stream_mimetype    : abap.char(128);
stream_file        : abap.rawstring(0);

ℹ️ Source: CDS View /DMO/FSA_C_ChildTP

StreamFilename, // Search Term #Stream

// Search Term #Stream
@Semantics.largeObject: {
  acceptableMimeTypes: [ 'image/*', 'application/*' ],
  cacheControl.maxAge: #MEDIUM,
  contentDispositionPreference: #INLINE, // #ATTACHMENT - download as file
                                             // #INLINE - open in new window
  fileName: 'StreamFilename',
  mimeType: 'StreamMimeType'
}
StreamFile,

// Search Term #Stream
@Semantics.mimeType: true
StreamMimeType,

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

// Search Term #Stream
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #FIELDGROUP_REFERENCE,
  targetQualifier: 'Stream',
  label: 'Large Object (#Stream)'
}]

// Search Term #Stream
@UI.hidden: true
StreamMimeType;

@UI.fieldGroup: [{ position: 10, qualifier: 'Stream', label: 'Attachment (#Stream)' }] // Search Term #Stream
StreamFile;

// Search Term #Stream
@UI.hidden: true
StreamFilename;

ℹ️ Source: BDEF /DMO/FSA_R_ROOTTP

define behavior for /DMO/FSA_R_ChildTP alias Child {
...
mapping for /dmo/fsa_child_a {
  ..
  StreamFile = stream_file;
  StreamFilename = stream_filename;
  StreamMimeType = stream_mimetype;
}

More Information on data modelling for Large Object: ABAP RESTful Application Programming Model - Working with Large Objects

🔼 Back to Content


Actions - Object Page

Search term: #OPHeaderAction

Actions for the Object Page in general are annotated using @UI.identification. The criticality only supports the values 0 (normal), 1 (red) and 3 (green). For normal actions the Object Page content is passed and for static actions, no context is passed.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #OPHeaderAction
@UI.identification: [{
  type: #FOR_ACTION,  //Action in the RootEntities of the object page next to the edit button
  label: 'Change Criticality (#OPHeaderAction)',
  criticality: 'CriticalityCode',
  criticalityRepresentation: #WITH_ICON,
  dataAction: 'changeCriticality'
}]
ID;

ℹ️ Source: Behaviour Definition /DMO/FSA_R_RootTP

action changeCriticality parameter /DMO/FSA_D_ChangeCriticalityP result [1] $self;

More Information: ABAP RESTful Application Programming Model: Action Implementation - UI Consumption of actions

🔼 Back to Content


Object Page - Content Area

General Features

Displaying Text and ID for Value Help Input Fields

Search term: #DisplayTextAndID

Instead of showing unreadable long IDs, there is the option to replace the ID with another text property from the entity, for example a name property. The @ObjectModel.text.element annotation specifies which value should be displayed instead of the original value.

ℹ️ Source: CDS View /DMO/FSA_I_Criticality

@ObjectModel.text.element: ['Name']
key code  as Code,
    name  as Name,

The @UI.textArrangement annotation defines how the new text is displayed. The options are #TextOnly, #TextFirst, #TextLast, #TextSeparate.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #DisplayTextAndID
@UI.textArrangement: #TEXT_FIRST,
CriticalityCode;

More Information: ABAP RESTful Application Programming Model: Providing Text by Text Elements in the Same Entity

🔼 Back to Content


Hiding Features

Search term: #HidingContent

Any header facet, section or data field can be hidden with the annotation @UI.xx.hidden. The annotation supports either fixed boolean values or values from a referenced property, as shown below.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #HidingContent
@UI.facet: [{
  purpose: #HEADER, // or #STANDARD
  type: #FIELDGROUP_REFERENCE,
  label: 'Section Visible when in Edit(#HidingContent)',
  targetQualifier: 'ShowWhenInEdit',
  hidden: #( IsActiveEntity )
}]

@UI.fieldGroup: [ { qualifier: 'ShowWhenInEdit' }] // Search Term #HidingContent
StringProperty;

More Information: ABAP RESTful Application Programming Model: Hiding Fields Dynamically on the Object Page

🔼 Back to Content


Preview

Search term: #Preview

A reference facet in a collection facet is not shown after loading the app, when the reference facet has the @UI.facet.isPartOfPreview annotation and it is set to false. The sub section is then hidden beneath a "Show more" button on the UI.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #Preview
@UI.facet: [
  {
    purpose: #STANDARD
    type: #COLLECTION,
    label: 'Micro Chart Data(#MicroChartDataSection)',
    id: 'chartDataCollection'
  },
  {
    parentId   : 'chartDataCollection',
    label      : 'Chart Data Preview (#Preview)',
    type       : #FIELDGROUP_REFERENCE,
    targetQualifier: 'chartDataPreview',
    isPartOfPreview: false
  }
]

@UI.fieldGroup: [ { qualifier: 'chartDataPreview' }] // Search Term #Preview
IntegerValue;

🔼 Back to Content


Multi Input Field

Search term: #MultiInputField

It is possible to have a multi input field which displays values from an association. When the values are from a child entity with delete capability, you are able to delete the entity in edit mode, directly from the multi input field.

It is not necessary to use the @UI.fieldGroup annotation to display the field, it is just annotated as such in the app to group and display it. It is however necessary, to use the datafield attribute value to set the source of the input, in this case the field StringProperty via the association _Child.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [{
  // Search Term #OPForm
  purpose: #HEADER, // or #STANDARD
  label      : 'FieldGroup (#OPForm)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'OPForm',
  id: 'SubSectionID'
}]
// Search Term #MultiInputField
@UI.fieldGroup: [
  {
    label: 'Multi Input Field (#MultiInputField)',
    qualifier: 'OPForm',
    value: '_Child.StringProperty',
    position: 40
  }
]
Child;

🔼 Back to Content


Presentation Variant - Object Page

Search term: #PresentationVariant-Child

A presentation variant defines how the result of a queried collection of entities is shaped and how this result is displayed, for example as a list report or a chart (@UI.presentationVariant.visualizations), the sorting order (@UI.presentationVariant.sortOrder), or the number of items (@UI.presentationVariant.maxItems) to display per segment.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

// Search Term #PresentationVariant-Child
@UI.presentationVariant: [
  {
    qualifier: 'pVariant',
    maxItems: 5,
    sortOrder: [
      {
        by: 'StringProperty',
        direction: #DESC
      }
    ],
    visualizations: [{type: #AS_LINEITEM}]
  }
]

To use presentation variant for a child entity in the object page, it is necessary to annotate @UI.facet with the correct type in the root entity: #SELECTIONPRESENTATIONVARIANT_REFERENCE or #PRESENTATIONVARIANT_REFERENCE instead of #LINEITEM_REFERENCE.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #OPTable, #PresentationVariant-Child, #SelectionPresentationVariant-Child, #SelectionVariant-Child
@UI.facet: [{
  purpose: #STANDARD,
  type: #SELECTIONPRESENTATIONVARIANT_REFERENCE,
  targetElement: '_Child',
  targetQualifier: 'ChildSP',
  label: 'Child Entity (1..n)(#OPTable)',
  id: 'childEntitiesSection'
}]

🔼 Back to Content


Selection Variant - Object Page

Search term: #SelectionVariant-Child

With a selection variant, you can define how the fields of an entity set should be filtered. The attribute text is the title of the view and filter contains all filter parameters.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

// Search Term #SelectionVariant
@UI.selectionVariant: [
  {
    qualifier: 'sVariant',
    text: 'SelectionVariant (Positive criticality)',
    filter: 'CriticalityCode EQ 3'
  }
]

🔼 Back to Content


Selection Presentation Variant - Object Page

Search term: #SelectionPresentationVariant-Child

A SelectionPresentationVariant bundles a Selection Variant and a Presentation Variant.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

// Search Term #SelectionPresentationVariant-Child
@UI.selectionPresentationVariant: [
  {
    qualifier: 'ChildSP',
    presentationVariantQualifier: 'pVariant',
    selectionVariantQualifier: 'sVariant'
  }
]

🔼 Back to Content


Forms

Connected Fields

Search term: #ConnectedFields

When two properties are semantically connected, they can be displayed next to each other under one label, to show their data relation. The connected field is defined with the annotation @UI.connectedFields. The attribute template is a string which defines in which order the properties are displayed and what is displayed between both properties, for example a slash.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #ConnectedFields
@UI.connectedFields: [{
  qualifier: 'ConnectedFields',
  groupLabel: 'Connected Fields (#ConnectedFields)',
  name: 'integer',
  template: '{integer} / {target}'
}]
IntegerValue;

// Search Term #ConnectedFields
@UI.connectedFields: [{
  qualifier: 'ConnectedFields',
  name: 'target'
}]
TargetValue;

The connected field can only be displayed in a form using @UI.fieldGroup or in a #STANDARD facet. They cannot be rendered in a table with @UI.lineItem, with @UI.identification or in header facets.

@UI.facet: [{
  // Search Term #OPForm
  purpose    : #STANDARD,
  label      : 'FieldGroup (#OPForm)',
  type       : #FIELDGROUP_REFERENCE,
  targetQualifier: 'OPForm',
  id: 'SubSectionID'
}]

// Search Term #ConnectedFields
@UI.fieldGroup: [{
  qualifier: 'OPForm',
  type: #AS_CONNECTED_FIELDS,
  valueQualifier: 'ConnectedFields',
  position: 10
}]
IntegerValue;

🔼 Back to Content


Form Actions and Navigation

Search term: #ActionInSection

Sections can have their own actions, which show up in the upper right corner of the section by default. This is done through annotation @UI.facet.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [{
  // Search Term #OPForm
  {
    purpose    : #HEADER, // or #STANDARD,
    label      : 'FieldGroup (#OPForm)',
    type       : #FIELDGROUP_REFERENCE,
    targetQualifier: 'OPForm',
    id: 'SubSectionID'
  }
}]

// Search Term #ActionInSection
@UI.fieldGroup: [{
  qualifier: 'OPForm',
  dataAction: 'changeProgress',
  type: #FOR_ACTION,
  emphasized: true,
  criticality: 'CriticalityCode', 
  label: 'Change Progress (#ActionInSection)'
}]
LastChangedAt;

ℹ️ Source: Behaviour Definition /DMO/FSA_R_RootTP

action changeProgress parameter /DMO/FSA_D_ChangeProgressP result [1] $self;

Search term: #SectionNavigation, #FormNavigation

External or intent based navigations are added using @UI.fieldGroup. Depending on the type used (#FOR_INTENT_BASED_NAVIGATION or #WITH_INTENT_BASED_NAVIGATION), the navigation will either be rendered as a button at the section toolbar or a link.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

@UI.facet: [{
  // Search Term #OPForm
  {
    purpose    : #HEADER, // or #STANDARD,
    label      : 'FieldGroup (#OPForm)',
    type       : #FIELDGROUP_REFERENCE,
    targetQualifier: 'OPForm',
    id: 'SubSectionID'
  }
}]

@UI: {
  fieldGroup: [    
    // Search Term #SectionNavigation ( Button )
    {
      qualifier: 'OPForm',
      label: 'IntentBased Navi (#SectionNavigation)',
      type: #FOR_INTENT_BASED_NAVIGATION,
      semanticObjectAction: 'manage'
    },
    // Search Term #FormNavigation ( Link )
    {
      qualifier: 'OPForm',
      label: 'IntentBased Navi (#FormNavigation)',
      type: #WITH_INTENT_BASED_NAVIGATION,
      value: 'NavigationID',
      semanticObjectAction: 'manage',
      position: 50
    }
  ]
}
NavigationID;

More Information: ABAP RESTful Application Programming Model: Based on Intent

🔼 Back to Content


Table

Search term: #OPTable

Table sections are most commonly for child entities or other associated entities. The implementation consists of two parts. First the associated or child entity needs the @UI.lineItem annotation. This defines which fields are displayed.

ℹ️ Source: Metadata Extension /DMO/FSA_C_GrandchildTP

@UI.lineItem: [{ position: 10 }] // Search Term #OPTable
StringProperty;

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

Secondly the @UI.facet annotation needs to be added

// Search Term #OPTable
@UI.facet: [{ 
  purpose: #STANDARD,
  type: #LINEITEM_REFERENCE,
  targetElement: '_Grandchild',
  label: 'Grandchild Entities (1..n)(#OPTable)'
} ]

Additionally it is also possible to show a table in a facet using the type #SELECTIONPRESENTATIONVARIANT_REFERENCE.

First the associated or child entity needs @UI.presentationVariant, @UI.selectionVariant, @UI.selectionPresentationvariant and @UI.lineItem annotation. This defines which fields are displayed.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChildTP

// Search Term  #OPTable
@UI: {
  // Search Term #PresentationVariant-Child
  presentationVariant: [
    { 
      qualifier: 'pVariant',
      sortOrder: [
        {
          by: 'StringProperty',
          direction: #DESC
        }
      ],
      visualizations: [{type: #AS_LINEITEM}]
    }
  ],
  // Search Term #SelectionVariant-Child
  selectionVariant: [
    { 
      qualifier: 'sVariant',
      text: 'SelectionVariant (Positive criticality)',
      filter: 'CriticalityCode EQ 3'
    }
  ],
  // Search Term #SelectionPresentationVariant-Child
  selectionPresentationVariant: [
    { 
      presentationVariantQualifier: 'pVariant',
      selectionVariantQualifier: 'sVariant'
    }
  ]
}

annotate entity /DMO/FSA_C_ChildTP
  with 
{
  ...  
  @UI.lineItem: [{ position: 10 }] // Search Term #OPTable
  StringProperty;
  
  @UI.lineItem: [{ position: 20 }] // Search Term #OPTable
  FieldWithPercent;
  
  @UI.lineItem: [{ 
    position: 30,
    criticality: 'CriticalityCode' 
  }]
  BooleanProperty;
  
}

Secondly the @UI.facet annotation needs to be added.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #OPTable, #PresentationVariant-Child, #SelectionPresentationVariant-Child, #SelectionVariant-Child
@UI.facet: [{
  purpose: #STANDARD,
  type: #SELECTIONPRESENTATIONVARIANT_REFERENCE,
  targetElement: '_Child',
  label: 'Child Entity (1..n)(#OPTable)',
  id: 'childEntitiesSection'
}]

More Information: ABAP RESTful Application Programming Model: Tables

🔼 Back to Content


Adding Titles to Object Page Tables

Search term: #OPTableTitle

The title of an Object Page table is the attribute typeNamePlural of the @UI.headerInfo annotation.

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search Term #HeaderInfo
@UI.headerInfo: {
  ...
  typeNamePlural: 'Root Entities (#OPTableTitle)', // Search Term #OPTableTitle
  ...
}

If the section title and the table title are identical or the @UI.headerInfo annotation is not given, the table title will not be displayed. Also if the table is the only content in a subsection and has a title, the subsections title will not be displayed.

🔼 Back to Content


Chart

Search term: #ChartSection

As an alternative to micro charts in the header, charts are also possible as sections. However the implementation is more complex. As aggregation is not yet available for V4 services, which this app is based on, the following shows only an example of how a chart should be annotated.

First the entity needs @Aggregation.default annotations, which defines which aggregation methods are supported. This can only be done on views that are not transactional.

ℹ️ Source: CDS View /DMO/FSA_I_Chart

define view entity /DMO/FSA_I_Chart
  as select from zfsa_chart_a
  ...
{
  key id                             as ID,
      ...

      @EndUserText.label : 'Minimal Net Amount'
      @Aggregation.default: #MIN
      integer_value                  as MinAmount,

      @EndUserText.label : 'Maximal Net Amount'
      @Aggregation.default: #MAX
      integer_value                  as MaxAmount,

      @EndUserText.label : 'Average Net Amount'
      @Aggregation.default: #AVG
      integer_value                  as AvgAmount,
      ...
}

After that the @UI.chart can be defined. Please note, that the attribute measures contains the properties of the aggregation methods. If it is just a property of the entity, like "integerValue", the chart won't be displayed. The first property in the attribute dimensions has the default dimension. The second property is the category into which a drill down is possible.

The added actions to the attribute actions are shown in the chart toolbar.

ℹ️ Source: CDS View /DMO/FSA_C_ChartTP

// Search Term #ChartSection
@UI.chart: [{ 
  qualifier: 'Test',
  title: 'Chart (#ChartSection)',
  chartType: #COLUMN,
  dimensions: ['Dimensions', 'CriticalityCode'],
  measures: ['MaxAmount'],
  dimensionAttributes: [
    { 
      dimension: 'Dimensions', 
      role: #CATEGORY 
    },
    { 
      dimension: 'CriticalityCode', 
      role: #CATEGORY 
    }
  ],
  measureAttributes: [
    { 
      measure: 'MaxAmount',
      role: #AXIS_1
    }
  ],
  actions: [{ type: #FOR_ACTION, dataAction: 'updateChart', label: 'Action at Chart' }]
  }
]

Lastly the chart needs to be added to the @UI.facet annotation. This section is commented out in the Feature Showcase App as Aggregation annotations are still not yet available in V4 services

ℹ️ Source: Metadata Extension /DMO/FSA_C_RootTP

// Search term #ChartSection
@UI.facet: [{
  id: 'chart',
  purpose: #STANDARD,
  type: #CHART_REFERENCE,
  targetElement: '_Chart',
  label: 'Chart (#ChartSection)'
}]

For semantic coloring of a dimension, the dimension property "CriticalityCode" is annotated with @UI.valueCriticality, where possible values of the property are matched against a criticality.

ℹ️ Source: Metadata Extension /DMO/FSA_C_ChartTP

// Search Term #ChartSection
@UI.valueCriticality: [
  { 
    value: '1',
    criticality: #NEGATIVE
  },
  { 
    value: '2',
    criticality: #CRITICAL
  },
  { 
    value: '3',
    criticality: #POSITIVE
  }
]
CriticalityCode;

More Information: ABAP RESTful Application Programming Model: Visualizing Data with Charts

🔼 Back to Content


License

Copyright (c) 2022 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the SAP Sample Code License except as noted otherwise in the LICENSE file.

Clone this wiki locally