capcap v1.0.0
SAP Fiori elements for OData V4 Feature Showcase
The main focus of this project is to present features from the List Report & Object Page floorplan. Please note, some feature combinations might not be intended by the SAP Fiori UX Guidelines but are shown here for the sake of demonstration.
Start the app and search for features you might want to use or search through the content overview. When you find something you can look for the corresponding topic for more information regarding the implementation.
Some topics have a hint, that the implementation is possible using SAP Fiori tools, which we recommend to use.
If you use CAP for the first time, please follow the instructions from the CAP Getting started
To run the featue showcase locally install the dependencies in the root folder with npm install
.
Then start the app with cds watch
.
Open http://localhost:4004/
in the Browser to get to the SAP Fiori launchpad sandbox from where you can navigate to the feature showcases.
Finding code: Each of the following topics has search terms, to find the related code snippets in the repository.
Content
- List Report
- General Features
- Header Area
- Content Area
- Configuring Tables
- Actions
- Setting the Table Type
- Multiple Views
- Creation Dialog
- Defining the Default Sort Order
- Enabling Multiple Selection in Tables
- Handling Semantic Key Fields
- Highlighting Line Items Based on Criticality
- Adding a Rating Indicator to a Table
- Adding a Progress Indicator to a Table
- Adding a field with a tooltip to a Table
- Adding a Smart Micro Chart to a Table
- Adding a Contact Quick View to a Table
- Adding a Quick View Facet to a Table
- Adding Multiple Fields to one Column in Responsive Tables
- Adding Images to a table
- Adding Currency or UoM Fields to a table
- Add custom column (Extensibility)
- Configuring Tables
- Object Page
List Report
General Features
Flexible Column Layout
The Flexible Column Layout (FCL) enables the app, to display the Object Page and possibly a further Object Page next to the List Report on the same page instead of navigating to the next page. To enable the Flexible Column Layout please use the Application Modeler from the SAP Fiori tools. The setting can be found in the Global Page Settings, which are part of the Page Map.
Configure Draft
Search term: #Draft
The annotation @odata.draft.enabled
adds the draft mode to an entity.
annotate service1.RootEntities with @odata.draft.enabled;
Replacing Standard UI Texts
Search term: "enhanceI18n"
If wanted, the replacement of standard UI texts is possible. For this a new i18n file is needed, for example "customI18N.properties" which is then referenced in the manifest.json file.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"enhanceI18n": "i18n/customI18N.properties",
...
}
}
},
The replacement can be for all entities, for specific entities or for specific actions of specific entities.
C_COMMON_DIALOG_OK
is the key for all entities.C_TRANSACTION_HELPER_OBJECT_PAGE_CONFIRM_DELETE_WITH_OBJECTTITLE_SINGULAR|RootEntities
is the key for the "RootEntities" entityC_OPERATIONS_ACTION_CONFIRM_MESSAGE|RootEntities|criticalAction
is the key for the "criticalAction" action of the "RootEntities" entity
C_COMMON_ACTION_PARAMETER_DIALOG_CANCEL|RootEntities = Custom cancel text
More information about replacing standard UI texts and what can be overridden is available in the SAP Fiori elements Documentation.
Custom Actions
Search term: CustomActions
With extensions points it is possible to add custom front-end actions to the UI at different places. Custom actions are added to the manifest.json file. The location depends on where the action shall be visible on the UI. In general a custom action consists of a unique qualifier for the action. The property "press" is the path to the event handler in a JavaScript file. Both the "enabled" and "visible" property accept either static values (true/false), a binding path, like in the example, or another path to a JavaScript function which returns true or false. The "text" property is the label of the button.
"CustomActionSection" : {
"press": "sap.fe.featureShowcase.mainApp.ext.CustomActions.messageBox",
"enabled": "{= ${ui>/editMode} !== 'Editable'}",
"visible" : true,
"text": "{i18n>CustomActionSection}"
}
The following code snippet is the CustomActions.js file from the example. "enabled" and "enabledForSingleSelect" are possible functions for the "enabled" property.
sap.ui.define([
"sap/m/MessageBox",
"sap/ui/core/library"
], function(MessageBox, coreLibrary) {
"use strict";
return {
messageBox: function() {
MessageBox.alert("Button pressed");
},
enabled : function() {
return true;
},
enabledForSingleSelect: function(oBindingContext, aSelectedContexts) {
if (aSelectedContexts && aSelectedContexts.length === 1) {
return true;
}
return false;
}
};
});
Invoking CAP actions out of a Custom Action
Search term: #EditFlowAPI
It is also possible to invoke CAP actions out of a JavaScript function using the "invokeAction" function of the SAP Fiori elements Edit flow API.
sap.ui.define([
"sap/m/MessageBox",
"sap/ui/core/library"
], function(MessageBox, coreLibrary) {
"use strict";
return {
onChangeCriticality: function(oEvent) {
let sActionName = "service1.changeCriticality";
let mParameters = {
contexts: oEvent.getSource().getBindingContext(),
model: oEvent.getSource().getModel(),
label: 'Confirm',
invocationGrouping: true
};
this.editFlow.invokeAction(sActionName, mParameters); //SAP Fiori elements EditFlow API
},
...
};
});
Header Area List Report
Enabling Variant Management
Search term: "variantManagement"
Variant Management (saving the filter settings and the personalization of tables) is by default enabled. However with the annotation "variantManagement": "None"
it can be disabled in the manifest.json.
"RootEntityListReport": {
...
"options": {
"settings": {
"entitySet": "RootEntities",
"variantManagement": "None",
...
}
}
}
When the Variant Management is disabled, the App title will be shown instead at this place. With the subTitle
annotation in the manifest.json file, you can change that to a custom name. The corresponding name for the property appSubTitle
has to be in the i18n.properties file within the webapp folder of the app.
"sap.app": {
...
"subTitle": "{{appSubTitle}}",
...
}
Define Filters
Search term: #FilterDefault
, #HideFilter
, #FilterGrouping
, #VisibleFilters
, #ValueHelps
, #DependentFilter
Default Values
Search term: #FilterDefault
With the annotation @Common.FilterDefaultValue
default values can be defined, like in field-control.cds. 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.
More information are available in the SAP UI5 Dokumentation
Hide filters
Search term: #HideFilter
To reduce the amount of available filters in a List Report, properties can be annotated with @UI.HiddenFilter
to hide them. An example is in the file field-control.cds.
annotate service1.RootEntities {
...
areaChartDeviationLowerBoundValue @UI.HiddenFilter;
areaChartDeviationUpperBoundValue @UI.HiddenFilter;
areaChartToleranceLowerBoundValue @UI.HiddenFilter;
areaChartToleranceUpperBoundValue @UI.HiddenFilter;
...
};
Filter facets
Search term: #FilterGrouping
Another nice feature are @UI.FilterFacets
, which allow one to structure the available properties of the entity into groups, so that filter adaptation is easier.
annotate service.RootEntities with @(
UI.FilterFacets : [
{
Target : '@UI.FieldGroup#chartData',
Label : '{i18n>chartData}',
},
{
Target : '@UI.FieldGroup#location',
Label : '{i18n>location}',
},
],
);
annotate service.RootEntities with @(
UI.FieldGroup #chartData : {
Data : [
{Value : integerValue},
{Value : targetValue},
{Value : forecastValue},
{Value : dimensions},
{Value : integerValue},
]
},
);
The implementation is in the layout.cds file.
Selection Fields
Search term: #VisibleFilters
@UI.SelectionFields
is the annotation, which allows 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. The annotation is used in the layout.cds file.
annotate service.RootEntities with @(
UI.SelectionFields : [
field,
fieldWithPrice,
criticality_code,
],
);
Further information are available in the UI5 Dokumentation.
Value Help
Search term: #ValueHelps
While CAP delivers the value help for Code Lists out of the box. For other associations this is not the case. To get a value help for a filter (and for the corresponding field on the Object Page), the entity has to be annotated with @Common.ValueList
.
annotate schema.RootEntities with{
...
contact @(Common : {
Text : contact.name,
TextArrangement : #TextOnly,
ValueList : {
Label : '{i18n>customer}',
CollectionPath : 'Contacts',
Parameters : [
{
$Type : 'Common.ValueListParameterInOut',
ValueListProperty : 'ID',
LocalDataProperty : contact_ID
},
{
$Type: 'Common.ValueListParameterDisplayOnly',
ValueListProperty: 'country_code',
},
{
$Type: 'Common.ValueListParameterDisplayOnly',
ValueListProperty: 'city',
}
]
}
});
...
};
The Label
property will be shown as the title of the value help dialog und the CollectionPath
property refers to the entity set of the service, which provides the values for the value help. If the value help is more complex and property names do not match or you want to configure, which fields should be visible in the value help, you can provide parameters to the Parameters
property.
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 @Common.ValueListWithFixedValues
annotation.
The implementation is in the value-helps.cds file.
Dependent Filtering (Value Help)
Search term: #DependentFilter
Dependent filtering can be achieved with an input parameter for the value help. An example would be with countries and regions. The value help for the region should only show regions of the selected country, which is another property of the entity.
annotate schema.RootEntities with{
...
region @(Common : {
Text : region.name,
TextArrangement : #TextFirst,
ValueListWithFixedValues: true,
ValueList : {
Label : '{i18n>Region}',
CollectionPath : 'Regions',
Parameters : [
{
$Type : 'Common.ValueListParameterInOut',
ValueListProperty : 'code',
LocalDataProperty : region_code
},
{
$Type: 'Common.ValueListParameterOut',
ValueListProperty: 'name',
LocalDataProperty : region.name,
},
//To only show the connected values
{
$Type : 'Common.ValueListParameterFilterOnly',
ValueListProperty : 'country_code',
},
{
$Type : 'Common.ValueListParameterIn', //Input parameter used for filtering
LocalDataProperty : country_code,
ValueListProperty : 'country_code',
},
]
}
});
};
Here the region property (which is an Association to a Code List) is annotated with the ValueList
annotation. To achieve the filtering, the country_code property from the header is mapped against the country_code property of the region via the Common.ValueListParameterIn
parameter. The implementation can be found in the value-helps.cds.
Custom Filter
Search term: customFilter
Custom filter are useful, when the data value is in a special format, for example a rating. The implementation consists of multiple parts. First List Report in the manifest.json is extended with the following lines. Under "controlConfiguration" the selection fields ("@com.sap.vocabularies.UI.v1.SelectionFields") are extended. The "property" property is the property of the entity set, which is filtered. The "template" property leads to a XML fragment, which is the filter. A "position" property with "placement" and "anchor" is also possible. When not given, the custom filter is placed at the end. The name of the custom filter has to be the property name, else it would cause errors.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
...
"@com.sap.vocabularies.UI.v1.SelectionFields": {
"filterFields": {
"starsValue": {
"label": "{i18n>customFilter}",
"property": "starsValue",
"template": "sap.fe.featureShowcase.mainApp.ext.CustomFilter-Rating"
}
}
}
},
...
}
}
},
The recommended way is to bind the filter value directly with value="{path: 'filterValues>', type: 'sap.fe.macros.filter.type.Value'}"
and using a filter value type (Value or Range for example).
Additionally format options are possible to use another operator instead of the default 'EQ'.
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:l="sap.ui.layout">
<!-- Search-Term: "customFilter" -->
<HBox alignItems="Center" core:require="{handler: 'sap/fe/featureShowcase/mainApp/ext/CustomFilter-Rating'}" width="100%" >
<!-- Example for adapting the used operator, using GT (greater than) instead of default EQ -->
<RatingIndicator
id="MyCustomRatingIndicatorId" maxValue="4" class="sapUiTinyMarginBegin"
value="{path: 'filterValues>', type: 'sap.fe.macros.filter.type.Value', formatOptions: { operator: 'GE' }}"
/>
<core:Icon src="sap-icon://reset" press="handler.onReset" class="sapUiSmallMarginBegin" />
</HBox>
</core:FragmentDefinition>
The following code is an example for a reset function. "starsValue" is the property name of the entity set which is filtered.
sap.ui.define(["sap/ui/model/Filter", "sap/ui/model/FilterOperator"], function(Filter, FilterOperator) {
"use strict";
return {
onReset: function(oEvent) {
this.setFilterValues("starsValue");
}
};
});
More information regarding custom filter are in the SAP Fiori elements Documentation.
Custom Actions (Global List Report)
Search term: "CustomActionLRGlobal"
With extension points custom actions can be added in the header area of the List Report.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"content" : {
"header" : {
"actions" : {
"CustomActionLRGlobal" : {
"press": "sap.fe.featureShowcase.mainApp.ext.CustomActions.messageBox",
"enabled": "sap.fe.featureShowcase.mainApp.ext.CustomActions.enabled",
"visible" : true,
"text": "{i18n>CustomActionLRGlobal}"
}
}
}
}
}
}
},
The custom action itself is described here: Custom Actions
Content Area List Report
Configuring Tables
Actions
Search term: #UnboundAction
, #BoundAction
, #SideEffect
, #ValueHelpParameter
, "MenuActions"
, #DynamicCRUD
In CAP, actions can be bound to a specific entity or unbound and just be a part of the service. Bound actions can only be executed, when at least one entity is selected. Unbound actions can be executed anytime.
If an action shall be visible, the UI.DataFieldForAction
has to be added to the UI.LineItem
annotation of the table. The action is called through the service.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAction',
Action : 'service1.changeCriticality',
Label : '{i18n>changeCriticality}',
},
...
],
...
},
);
layouts_RootEntities.cds
With this default annotation, the action is displayed above the table on the right, with other possible actions. If you want to display the action inline, the property Inline : true
has to be added. Additionally instead of the action name, an icon can be displayed, if the action is in line.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAction',
Action : 'service1.changeProgress',
Label : '{i18n>changeProgess}',
IconUrl : 'sap-icon://status-critical',
Inline : true,
},
...
],
...
},
);
While you can add the property Determining : true
, determining actions are not supported and the action will just disappear from the UI. The action annotations so far were for bound actions. If you want to add unbound actions, you have to change the action annotation slightly. Instead of referring to service1.unboundAction
you have to refer to service1.EntityContainer/unboundAction
in order to have a working unbound action. The other path will display an action on the UI, but it would not work, if you click it.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAction',
Action : 'service1.EntityContainer/unboundAction',
Label : '{i18n>unboundAction}',
},
...
],
...
},
);
Side Effects of actions
Search term: #SideEffect
If your action triggers changes on the entities, you need side effects so that the UI updates automatically. These side effect annotations have to be added to the action.
entity RootEntities as select from persistence.RootEntities actions {
...
@(
cds.odata.bindingparameter.name : '_it',
Common.SideEffects : {
TargetProperties : ['_it/integerValue']
}
)
action changeProgress (@(title : '{i18n>newProgress}', UI.ParameterDefaultValue : 50)newProgress : Integer);
};
The OData binding parameter is needed, in order to refer to the fields of the entity, which need to be updated. These fields are then listed in the array of the TargetProperties
property of @Common.SideEffects
.
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.
entity RootEntities as select from persistence.RootEntities actions {
...
action changeCriticality (
@(
title : '{i18n>newCriticality}',
UI.ParameterDefaultValue : 0,
Common : {
ValueListWithFixedValues : true,
ValueList : {
Label : '{i18n>Criticality}',
CollectionPath : 'Criticality',
Parameters : [
{
$Type : 'Common.ValueListParameterInOut',
ValueListProperty : 'code',
LocalDataProperty : newCriticality
},
{
$Type : 'Common.ValueListParameterDisplayOnly',
ValueListProperty : 'name'
},
]
}
}
)
newCriticality : Integer);
...
};
This can be achieved, by just annotating the parameter with a common valueList. The annotation has to be inline with the parameter.
Default Value for action parameter
Search term: #ParameterDefaultValue
With the annotation @UI.ParameterDefaultValue
a default value for the parameter is set.
entity RootEntities as select from persistence.RootEntities actions {
...
action changeProgress (@(title : '{i18n>newProgress}', UI.ParameterDefaultValue : 50)newProgress : Integer);
};
Action Drop down menu
Search term: "MenuActions"
A dropdown menu to group actions is possible with an annotation in the manifest.json file.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
"actions": {
"MenuActions": {
"text": "{i18n>MenuButton}",
"menu": [
"DataFieldForAction::service1.changeCriticality",
"DataFieldForAction::service1.EntityContainer::unboundAction"
]
}
},
...
},
...
}
}
}
},
In the control configuration of the List Report, the line item annotation of the table (it does not affect other line item definitions which may be used in other table views) has a property "actions"
under which the menu button needs to be added. "MenuActions"
is in this case just the identifier of this specific menu button. The text property is the actual label of the menu button and the "menu"
property contains all actions, which should be included. "changeCriticality" is a bound action and can be directly accessed through the service. The unbound action on the other side, needs to be accessed through the EntityContainer. The slash is replaced with two colons in the identifier for the action.
Dynamic CRUD Restrictions
Search term: #DynamicCRUD
The visibility of the "Edit", "Create" and "Delete" actions can be dynamically adjusted. For example the delete operation can be dependent on a field of the entity, through the annotation @Capabilities.DeleteRestrictions
. Fixed values are also possible.
annotate service1.RootEntityVariants with @(
Capabilities.DeleteRestrictions : {
Deletable : deletePossible,
},
UI.UpdateHidden : updateHidden
);
While @Capabilities.UpdateRestrictions
would restrict the update possibilities of the entity in the edit mode, e.g. all fields are read only, the "Edit" button would not disappear. Instead the @UI.UpdateHidden
annotation should be used, which when true, hides the "Edit" button as intended.
Navigation Button
Search term: #NavAction
A navigation action navigating to an associated entity can be added, through adding the UI.DataFieldForIntentBasedNavigation
as a line item.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForIntentBasedNavigation',
Label : '{i18n>inboundNavigation}',
SemanticObject : 'FeatureShowcaseChildEntity2',
Action : 'manage',
RequiresContext : true,
Inline : true,
IconUrl : 'sap-icon://cart',
Mapping : [
{
$Type : 'Common.SemanticObjectMappingType',
LocalProperty : integerValue,
SemanticObjectProperty : 'integerProperty',
},
],
![@UI.Importance] : #High,
},
...
],
...
},
);
The semantic object and the action are in the fiori.html file. The application property in this contains the following code snippet:
"FeatureShowcaseChildEntity2-manage": {
title: "ChildEntities2",
description:"Manage",
additionalInformation: "SAPUI5.Component=sap.fe.featureShowcase.childEntities2ui",
applicationType: "URL",
url: "/featureShowcaseNavigationTarget/webapp",
navigationMode: "embedded",
},
Here "FeatureShowcaseChildEntity2" is the semantic object to be referenced. The second part of the name is the action of the app. As an example you may have the apps "SalesOrder-manage", "SalesOrder-view" and so on. Semantic object and action have to be divided by a dash.
The property RequiresContext
determines, whether an entry needs to be selected to enable the navigation button or not. If it is set to true, it may be needed, to add the Mapping
property. This property is an array of mappings between local and semantic object properties and it is needed if local properties should be used to filter in the app of the semantic object, but the property names differ. In this example, the local property 'integerValue' is mapped to the semantic object property 'integerProperty', so when selecting an entity where integerValue equals 22, the navigation would filter for entries where the 'integerProperty' property equals 22 in the semantic object app.
Icons can be displayed as the label of the button instead of text, but only if the button is inline. When Icons are displayed, the criticality is being ignored.
Critical Actions
Search term: #CriticalAction
When an action is annotated with @Common.IsActionCritical : true
, a popover will appear before invoking the action, asking the user if he/she is sure about invoking the selected action.
annotate service1.criticalAction with @(
Common.IsActionCritical : true
);
Message Toasts
Search term: #MessageToast
Message toasts are shown on the UI when the Backend sends a message with the severity equaling 1. If the severity is higher, a dialog will be shown. For more information regarding the sending of messages from a CAP Backend, please have a look at the SAP CAP Documentation for messaging.
req.notify(`Critical action pressed`);
notify
is the method to send a message with the severity of 1 and req
is the request received by CAP.
Custom Actions (Table List Report)
Search term: "CustomActionLR"
With extension points custom actions can be added in the table toolbar of the List Report.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
"actions": {
...
"CustomActionLR" : {
"press": "sap.fe.featureShowcase.mainApp.ext.CustomActions.messageBox",
"enabled": "sap.fe.featureShowcase.mainApp.ext.CustomActions.enabledForSingleSelect",
"visible" : true,
"text": "{i18n>CustomActionLR}"
}
},
...
}
},
...
}
}
},
The custom action itself is described here: Custom Actions
Setting the Table Type
INFO: We recommend that you use SAP Fiori tools, which is a set of extensions for SAP Business Application Studio and Visual Studio Code, to configure the app using the Application Modeler tool.
Search term: "tableSettings"
, "ResponsiveTable"
, "GridTable"
Supported table types are the ResponsiveTable and the GridTable. The table type of the List Report can be adjusted in the manifest.json file (Line 146).
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"tableSettings": {
"type": "ResponsiveTable",
...
},
...
},
...
},
...
}
}
},
Multiple Views
Search term: #multipleViews
, "views"
, "quickVariantSelection"
With multiple views, you can display different selections and/or presentations of the entity set, without the need to set the filter manually.
Single table mode
Search term: "quickVariantSelection"
In the single table mode all views are displayed in the same table. You can switch between the views through a segmented button next to the table title. If you define more than three views, a drop down menu will be displayed instead. A restriction of the single table mode is, that you can change the selected entities (@UI.SelectionVariant
), but not the presentation (@UI.SelectionPresentationVariant
) of the entities, nor the entity set itself.
To implement the single table mode, you need to define a selection variant and refer to it in the manifest.json file, through using its qualifier (e.g. #variant1).
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"tableSettings": {
...
"quickVariantSelection": {
"paths": [
{
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#variant1"
},
{
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#variant2"
}
],
"hideTableTitle": false,
"showCounts": true
}
},
...
},
...
},
...
}
}
}
Further you can define, if each view should show the amount of rows it displays and if the table title should be hidden for all views. By default the "showCounts"
property is false, as additional $count requests impact the performance.
Multiple table mode
Search term: "views"
In multiple table mode, a icon tab bar will be rendered above the table to switch between the views. Each view has its own table with its own table tool bar and variant management (if activated), but only the table of the selected tab will be shown. Here you have the possibility to use the @UI.SelectionPresentationVariant
annotation and there is the possibility to define another entity set to be displayed in a tab.
The single and multiple table mode do not exclude each other completely. When using a SelectionVariant as the annotation for a view of the multiple table mode, the different views of the single table mode can be additionally applied. When using a UI.SelectionPresentationVarian
in the multiple table mode for the view, you cannot apply the view from the single table mode.
To implement the multiple table mode, you need to refer to the Selection- or SelectionPresentationVariants via the qualifier in the manifest.json file. Each view has to have a unique "key"
property for the tab. The "annotationPath"
property refers to the qualifier. There is again the option to display the counts of each view, but it affects the performance.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"views": {
"paths": [
{
"key": "tab1",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#variant1"
},
{
"key": "tab2",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#variant2"
},
{
"key": "tab3",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SelectionPresentationVariant"
},
{
"key": "tab4",
"entitySet": "RootEntityVariants",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#variant3"
}
],
"showCounts": false
},
...
}
}
}
When you want to have a view with a different entity set, you just need to add the "entitySet"
property to a path entry in the manifest.json. The referenced entity name equals the entity name in the CAP Service. The Selection- or SelectionPresentationVariant has to be annotated to the different entity set. When displaying a different entity set, the counts of each view will be automatically shown, ignoring the showCounts
annotation. Filters from the main entity set will be applied, when the property exist in the other entity set, else they will be ignored. There is no option to add filters for unique properties of the other entity set.
More information are available in the SAP UI5 Documentation.
Selection Variant
Search term: #SVariant
With a selection variant, you can define how the fields of an entity set should be sorted. The "Text" property is the title of the view and the property "SelectOptions" contains all sorting parameters.
annotate service.RootEntities with @(
UI.SelectionVariant #variant1 : {
Text : '{i18n>SVariant1}',
SelectOptions : [
{
PropertyName : criticality_code,
Ranges : [
{
Sign : #I,
High : 2,
Option : #BT,
Low : 0,
},
],
},
],
},
...
);
The "Option" property supports the following options: Equal To (EQ), Between (BT), Less than or equal to (LE), Greater than or equal to (GE), Not equal to (NE), Greater than (GT) and Less than (LT). The annotations are in the layouts_RootEntities.cds file.
Selection Presentation Variant
Search term: #SPVariant
With a selection presentation variant a selection of entities and a presentation can be defined. The PresentationVariant
currently supports the properties SortOrder
and Visualizations
. The selection and presentation variants are basically identical to their stand-alone counterparts, only the selection variant here does not include the text property.
annotate service.RootEntities with @(
UI.SelectionPresentationVariant #SelectionPresentationVariant : {
Text : '{i18n>SelectionPresentationVariant}',
SelectionVariant : {
$Type : 'UI.SelectionVariantType',
SelectOptions : [
{
PropertyName : criticality_code,
Ranges : [
{
Sign : #I,
Option : #GT,
Low : 0,
},
],
},
],
},
PresentationVariant :{
SortOrder : [
{
Property : fieldWithPrice,
Descending : false,
},
],
Visualizations : [
'@UI.LineItem#simplified',
],
},
},
);
You can refer to a specialised UI.LineItem
collection, when you define one with a qualifier. The view with this UI.SelectionPresentationVariant
will then have other columns.
More information are available in the SAP UI5 Documentation.
Creation Dialog
Search term: #CreationDialog
When creating a new entity, a creation dialog will pop up for all fields, which are annotated with @Core.Immutable
, because fields with this annotation cannot be updated and the value has to be provided during creation.
annotate service1.RootEntities {
...
stringProperty @Core.Immutable;
...
};
Defining the Default Sort Order
Search term: #DefaultSort
Use the UI.PresentationVariant
annotation to define a default sort order. The attribute Visualizations
defines, on which line items the sort order should be applied.
annotate service.RootEntities with @(
UI.PresentationVariant :{
SortOrder : [
{
Property : field,
Descending : false,
},
],
Visualizations : [
'@UI.LineItem',
],
},
);
Without a sort order defined, the values are ascending. The implementation is in the File: layout.cds
Enabling Multiple Selection in Tables
INFO: We recommend that you use SAP Fiori tools, which is a set of extensions for SAP Business Application Studio and Visual Studio Code, to configure the app using the Application Modeler tool.
Search term: "selectionMode"
Multiple Selection can be enabled in the List Report with the property "selectionMode": "Multi"
in the table Settings. Other possible values are: Auto, Single or None. More Information about these are available in the SAP Fiori elements Documentation.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"tableSettings": {
"type": "ResponsiveTable",
"selectionMode": "Multi",
...
},
...
},
...
},
...
}
}
},
Handling Semantic Key Fields
Search term: #SemanticKey
Semantic Key fields can be defined, with the annotation Common.SemanticKey
, which consists of an Array of fields from the entity. The given fields will be displayed in bold, and when possible the editing status will be displayed. Currently this is only possible for the default DataField.
annotate service.RootEntities with @(
Common.SemanticKey : [ field ],
);
Highlighting Line Items Based on Criticality
Search term: #LineItemHighlight
Line items can be highlighted based on there criticality with the annotation ![@UI.Criticality]
. The annotation has to be a part of the @UI.LineItem
annotation.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
],
![@UI.Criticality] : criticality_code,
},
);
Adding a Rating Indicator to a Table
Search term: #RatingIndicator
To add a rating indicator (stars) to the table, the entity needs to be annotated with @UI.DataPoint
. The Value Property of the annotation defines, how many stars are visible. Values between x.25 and x.74 are displaced as a half star. The target property defines, how many stars are possible.
annotate service.RootEntities with @(
...
UI.DataPoint #ratingIndicator : {
Value : starsValue,
TargetValue : 4,
Visualization : #Rating,
Title : '{i18n>ratingIndicator}',
![@Common.QuickInfo] : 'Tooltip via Common.QuickInfo',
},
...
);
After creating the data point, it has to be added to the @UI.LineItem
annotation. For that the UI.DataFieldForAnnotation type is used and the target is the data point.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Label : '{i18n>ratingIndicator}',
Target : '@UI.DataPoint#ratingIndicator',
![@UI.Importance] : #Low,
},
...
],
...
},
);
The annotations are in the layouts_RootEntities.cds file.
Adding a Progress Indicator to a Table
Search term: #ProgressIndicator
To add a progress indicator to a table, the entity needs to be annotated with @UI.DataPoint
. The value property defines the current progress and the target property the maximum progress. Additionally a criticality can be given, if wanted.
annotate service.RootEntities with @(
UI.DataPoint #progressIndicator : {
Value : integerValue,
TargetValue : 100,
Visualization : #Progress,
Title : '{i18n>progressIndicator}',
//Criticality: criticality,
},
...
);
After creating the data point, it has to be added to the @UI.LineItem
annotation. For that the UI.DataFieldForAnnotation type is used and the target is the data point.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Label : '{i18n>progressIndicator}',
Target : '@UI.DataPoint#progressIndicator',
![@UI.Importance] : #Low,
},
...
],
...
},
);
The annotations are in the layouts_RootEntities.cds file.
Adding a field with a tooltip to a Table
Search term: #ToolTip
Fields can have a tooltip in the List Report through a work around. First a data point is created, only with the property 'Value' and the annotation '@Common.QuickInfo', which defines the displayed tool tip.
annotate service.RootEntities with @(
...
UI.DataPoint #fieldWithTooltip : {
Value : dimensions,
![@Common.QuickInfo] : '{i18n>Tooltip}',
},
);
Secondly the data point is added as a line item with the '@UI.DataFieldForAnnotation' type to the table.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : '@UI.DataPoint#fieldWithTooltip',
Label : '{i18n>fieldWithToolTip}',
},
...
],
...
},
);
Adding a Smart Micro Chart to a Table
Search term: #MicroChart
To add a smart micro chart to a table you have again to define a @UI.DataPoint
. In the case of a radial chart, the properties value and target value are mandatory and the criticality is optional.
annotate service.RootEntities with @(
...
UI.DataPoint #radialChart : {
Value : integerValue,
TargetValue : targetValue,
Criticality : criticality_code,
},
...
);
The data point needs to be referenced in an @UI.Chart
annotation in the measure attributes. The chart type has to be "#Donut" for a radial chart and Measures and MeasureAttributes are mandatory.
UI.Chart #radialChart : {
Title : '{i18n>radialChart}',
Description : '{i18n>ThisIsAMicroChart}',
ChartType : #Donut,
Measures : [integerValue],
MeasureAttributes : [{
$Type : 'UI.ChartMeasureAttributeType',
Measure : integerValue,
Role : #Axis1,
DataPoint : '@UI.DataPoint#radialChart',
}]
},
The chart is then the target of a DataFieldForAnnotation
in the @UI.LineItem
annotation, to be shown in the table.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : '@UI.Chart#radialChart',
Label : '{i18n>radialChart}',
},
...
],
...
},
);
The annotations of the example are in the layouts_RootEntities.cds file.
Adding a Contact Quick View to a Table
Search term: #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:
annotate service1.Contacts with @(
Communication.Contact : {
fn : name, //full name
kind : #org,
tel : [{
uri : phone,
type : #preferred
}],
adr : [{
building : building,
country : country.name,
street : street,
locality : city,
code : postCode,
type : #preferred
}],
}
);
There are more supported properties for the Contact, which are listed in the SAP Fiori elements Documentation.
This contact card then needs to be a target of a DataFieldForAnnotation, which itself is a port of the @UI.LineItem
annotation, to be shown in the table.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : 'contact/@Communication.Contact',
Label : '{i18n>contactQuickView}'
},
...
],
...
},
);
The contact card is referenced through the contact attribute of the entity. The annotations of the example are in the layouts_RootEntities.cds file. The contact card starts in Line 761.
Adding a Quick View Facet to a Table
Search term: #QuickView
A quick view facet is a pop up, when you click on an entry in a column and get more information. Typically it is used in combination with associations to one, where the association name is displayed in the column and with a click on it, more information about the association entity can be consumed. To enable a quick view facet, the association entity needs to be annotated with @UI.QuickViewFacet
. It is an array of reference facets, where you can reference field groups (a group of properties) to be shown in the quick view. For a better looking header of the quick view, the association entity gets typically also annotated with @UI.HeaderInfo
.
annotate service1.ChildEntities2 with @(
UI.FieldGroup #data : {
Label : '{i18n>ChildEntity2}',
Data : [
{Value : field2},
{Value : integerProperty},
{Value : field4},
],
},
);
annotate service1.ChildEntities2 with @(
UI.HeaderInfo :{
TypeName : '{i18n>ChildEntity2}',
TypeNamePlural : '{i18n>ChildEntity2.typeNamePlural}',
Title : {
$Type : 'UI.DataField',
Value : '{i18n>ChildEntity2}',
},
Description : {
$Type : 'UI.DataField',
Value : field,
},
ImageUrl : '',
TypeImageUrl : 'sap-icon://blank-tag',
},
);
annotate service1.ChildEntities2 with @(
UI.QuickViewFacets : [
{
$Type : 'UI.ReferenceFacet',
Target : '@UI.FieldGroup#data',
}
],
);
The last step is, that a UI.DataField
has to be added to the @UI.LineItem
annotation. The value of the data field is the key attribute and then the quick view facet will be automatically visible.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataField',
Value : childEntity2_ID,
Label : '{i18n>ChildEntity2}',
![@UI.Importance] : #High,
},
...
],
...
},
);
The annotations of the example are in the layouts_RootEntities.cds file.
Additionally the @Common.Text
and @Common.TextArrangement
might be used, to replace the ID value with a name property, so that the column is easier to understand.
childEntity2 @title : '{i18n>ChildEntity2}' @Common.Text : childEntity2.field @Common.TextArrangement : #TextOnly;
The annotations are in the labels.cds file.
Links to the apps of the entity
Search term: FeatureShowcaseChildEntity2
, #Navigation
The quick view facet also shows links to the apps of the entity, when the entity is annotated with @Common.SemanticObject
.
childEntity2 @Common.SemanticObject : 'FeatureShowcaseChildEntity2';
The semantic object is the application name in the html file. The application property in this contains the following code snippet:
"FeatureShowcaseChildEntity2-manage": {
title: "ChildEntities2",
description:"Manage",
additionalInformation: "SAPUI5.Component=sap.fe.featureShowcase.childEntities2ui",
applicationType: "URL",
url: "/featureShowcaseNavigationTarget/webapp",
navigationMode: "embedded",
},
Here "FeatureShowcaseChildEntity2" is the semantic object to be referenced. The second part of the name is the action of the app. As an example you may have the apps "SalesOrder-Manage", "SalesOrder-View" and so on. Semantic object and action have to be divided by a dash. The description of the app in the html file is the name of the app in the quick view facet.
Adding Multiple Fields to one Column in Responsive Tables
Search term: #MultiFieldsCol
Multiple fields can be in one column, if a field group is added to table with the UI.DataFieldForAnnotation. First you have to define the field group.
annotate service.RootEntities with @(
UI.FieldGroup #AdminData : {
Data : [
{Value : createdAt},
{Value : createdBy},
{Value : modifiedAt},
{Value : modifiedBy},
]
},
...
);
Secondly you have to add a DataField For Annotation to the @UI.LineItem
annotation.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : '@UI.FieldGroup#AdminData',
Label : '{i18n>adminData}',
![@UI.Importance] : #High,
},
...
],
...
},
);
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 data field to the line items.
annotate service.RootEntities with @(
UI.LineItem : {
$value : [
{
$Type : 'UI.DataField',
Value : imageUrl,
![@UI.Importance] : #High,
},
...
],
...
},
);
The special thing is just, that the property, which contains the image url has to be annotated with @UI.IsImageURL
. The example is annotated in the labels.cds file.
Adding Currency or UoM Fields to a table
Search term: #Units
The special thing about currency or unit of measure fields is, that they have an additional field with the unit. In order to not have to add both properties to the table, and may risk, that through personalisation one might be not visible, the property with the value can be annotated with the unit.
For units of measure the annotation is @Measures.Unit
. For currencies the annotation is @Measures.ISOCurrency
and for percentage value the annotation is @Measures.Unit : '%'
.
The examples from the feature showcase are in the labels.cds file.
Add custom column (Extensibility)
Search term: #CustomColumn
To fulfill business requirements, there might be the need, to add custom columns to a table. With the SAP Fiori elements extension points this is possible. First the additional column needs to be created als a xml fragment. This fragment should be in a separate folder of the webapp. In this example, the fragment contains a label which consists of the validFrom and validTo property of the entity.
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m">
<Label text="{validFrom} - {validTo}"/>
</core:FragmentDefinition>
This label shall be visible as an additional column. For this the manifest.json file needs to be adjusted.
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"columns": {
"CustomColumn": {
"key": "customColumnLR",
"header": "{i18n>validityPeriodLR}",
"template": "sap.fe.featureShowcase.mainApp.ext.CustomColumn-DateRangeLR",
"availability": "Adaptation",
"horizontalAlign": "Center",
"width": "auto",
"properties": [
"validFrom",
"validTo"
],
"position": {
"placement": "After",
"anchor": "DataField::fieldWithCriticality"
}
}
}
},
...
},
...
}
}
}
The columns of the line item property need to be extended with the additional field. The key property needs to be unique and the template refers to the xml fragment. The path consists of two parts. The first one is the namespace of the application (sap.fe.featureShowcase.mainApp), the second one is the navigation to the fragment within the webapp folder of the app (.ext.CustomColumn-DateRangeLR). The "availability"
property defines, whether the column is visible or not. Possible values are "Default", "Adaption" or "Hidden". The "properties
property defines, which properties should be used, when sorting is available, to sort. The given properties have to be part of the entity and cannot be navigation properties.
Lastly "position"
defines, were the column should be added in the table. For "position" there are the options "Before" or "After" and the "anchor" has to ba an existing data field of the table, for example "DataField::fieldWithCriticality".
Additional information are available in the SAP UI5 Documentation.
Object Page
General Features Object Page
Annotations for data fields
Communication properties
Search term: #CommunicationFields
To display emails and phone numbers as a link, they are annotated with @Communication.IsEmailAddress
or `@Communicatio
10 months ago