An open API service indexing awesome lists of open source software.

https://github.com/sap-samples/fiori-elements-feature-showcase

Sample application that demonstrates and documents a broad variety of features of SAP Fiori elements for OData V4. Developers can play around with the new features and learn how to implement them.
https://github.com/sap-samples/fiori-elements-feature-showcase

odatav4 sample sample-code sap-cap sap-fiori sap-fiori-elements

Last synced: 3 months ago
JSON representation

Sample application that demonstrates and documents a broad variety of features of SAP Fiori elements for OData V4. Developers can play around with the new features and learn how to implement them.

Awesome Lists containing this project

README

          

# SAP Fiori elements for OData V4 Feature Showcase

[![REUSE status](https://api.reuse.software/badge/github.com/SAP-samples/fiori-elements-feature-showcase)](https://api.reuse.software/info/github.com/SAP-samples/fiori-elements-feature-showcase)

![Screenshot](readmeImages/app-screenshot.png)


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](https://experience.sap.com/fiori-design/) 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](https://cap.cloud.sap/docs/get-started/)


To run the featue showcase locally install the dependencies in the [root folder](https://github.tools.sap/fiori-elements/feature-showcase) with `npm install`.

Then start the app with `cds watch`.

Open `http://localhost:4008/$launchpad` 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](#list-report)
- [General Features](#general-features)
- [Configure Draft](#configure-draft)
- [Replacing Standard UI Texts](#replacing-standard-ui-texts)
- [Custom Actions](#custom-actions)
- [Invoking CAP actions out of a Custom Action](#invoking-cap-actions-out-of-a-custom-action)
- [Default sorting and filtering](#default-sorting-and-filtering)
- [Header Area](#header-area-list-report)
- [Enabling Variant Management](#enabling-variant-management)
- [Enabling Live Mode](#enabling-live-mode)
- [Define Filters](#define-filters)
- [Default Values](#default-values)
- [Hide filters](#hide-filters)
- [Filter facets](#filter-facets)
- [Selection Fields](#selection-fields)
- [Mandatory filter fields](#mandatory-filter-fields)
- [Enable semantic dates for filter fields of type Date](#enable-semantic-dates-for-filter-fields-of-type-date)
- [Case insensitive filtering](#case-insensitive-filtering)
- [Value Help](#value-help)
- [Dependent Filtering (Value Help)](#dependent-filtering-value-help)
- [Dependent Filtering from parent (Value Help)](#dependent-filtering-multi-input-value-help)
- [Custom Filter](#custom-filter)
- [Custom Actions](#custom-actions-global-list-report)
- [Content Area](#content-area-list-report)
- [Configuring Tables](#configuring-tables)
- [Actions](#actions)
- [Side Effects of actions](#side-effects-of-actions)
- [Value Help for action parameter](#value-help-for-action-parameter)
- [Default Value for action parameter](#default-value-for-action-parameter)
- [Action Drop down menu](#action-drop-down-menu)
- [Dynamic CRUD Restrictions](#dynamic-crud-restrictions)
- [Navigation Button](#navigation-button)
- [Critical Actions](#critical-actions)
- [Message Toasts](#message-toasts)
- [Custom Actions](#custom-actions-table-list-report)
- [Setting the Table Type](#setting-the-table-type)
- [Tree Table](#tree-table)
- [Multiple Views](#multiple-views)
- [Single table mode](#single-table-mode)
- [Multiple table mode](#multiple-table-mode)
- [Selection Variant](#selection-variant)
- [Selection Presentation Variant](#selection-presentation-variant)
- [Creation Dialog](#creation-dialog)
- [Defining the Default Sort Order](#defining-the-default-sort-order)
- [Enabling Multiple Selection in Tables](#enabling-multiple-selection-in-tables)
- [Handling Semantic Key Fields](#handling-semantic-key-fields)
- [Highlighting Line Items Based on Criticality](#highlighting-line-items-based-on-criticality)
- [Adding a Rating Indicator to a Table](#adding-a-rating-indicator-to-a-table)
- [Adding a Progress Indicator to a Table](#adding-a-progress-indicator-to-a-table)
- [Adding a field with a tooltip to a Table](#adding-a-field-with-a-tooltip-to-a-table)
- [Adding a Smart Micro Chart to a Table](#adding-a-smart-micro-chart-to-a-table)
- [Adding a Contact Quick View to a Table](#adding-a-contact-quick-view-to-a-table)
- [Adding a Quick View Facet to a Table](#adding-a-quick-view-facet-to-a-table)
- [Links to the apps of the entity](#links-to-the-apps-of-the-entity)
- [Adding Multiple Fields to one Column in Responsive Tables](#adding-multiple-fields-to-one-column-in-responsive-tables)
- [Adding Images to a table](#adding-images-to-a-table)
- [Adding Currency or UoM Fields to a table](#adding-currency-or-uom-fields-to-a-table)
- [Customize Currency or UoM scale](#customize-currency-or-uom-scale)
- [Adding a link to a table](#adding-a-link-to-a-table)
- [Add custom column (Extensibility)](#add-custom-column-extensibility)
- [Object Page](#object-page)
- [General Features](#general-features-object-page)
- [Annotations for data fields](#annotations-for-data-fields)
- [Communication properties](#communication-properties)
- [Time and Date](#time-and-date)
- [Multi line text](#multi-line-text)
- [Placeholder values](#placeholder-values)
- [Replacing Standard UI Texts](#replacing-standard-ui-texts)
- [Custom Actions](#custom-actions)
- [Invoking CAP actions out of a Custom Action](#invoking-cap-actions-out-of-a-custom-action)
- [Header Area](#header-area-object-page)
- [Title and Subtitle](#title-and-subtitle)
- [Actions](#object-page-actions)
- [Custom Actions](#custom-actions-object-page-header)
- [Header Facets](#header-facets)
- [Plain Text](#plain-text)
- [Header Field Group Facet](#header-field-group-facet)
- [Custom Field](#custom-field)
- [Address facet](#address-facet)
- [Data Points](#data-points)
- [Rating](#rating)
- [Progress](#progress)
- [Key value](#key-value)
- [Micro chart facet](#micro-chart-facet)
- [Area Micro Chart](#area-micro-chart)
- [Bullet Micro Chart](#bullet-micro-chart)
- [Radial Micro Chart](#radial-micro-chart)
- [Line Micro Chart](#line-micro-chart)
- [Column Micro Chart](#column-micro-chart)
- [Harvey Micro Chart](#harvey-micro-chart)
- [Stacked Bar Micro Chart](#stacked-bar-micro-chart)
- [Comparison Micro Chart](#comparison-micro-chart)
- [Header Custom Facet](#Header-custom-facet)
- [Content Area](#content-area-object-page)
- [General features](#general-features-content-area-object-page)
- [Displaying Text and ID for Value help Input fields](#displaying-text-and-id-for-value-help-input-fields)
- [Hiding features](#hiding-features)
- [Preview](#preview)
- [Side Content](#side-content)
- [Forms](#forms)
- [Connected Fields](#connected-fields)
- [Custom Content](#custom-content)
- [Form Actions and Navigation](#form-actions-and-navigation)
- [Custom Actions](#custom-actions-object-page-section-form)
- [Table](#table)
- [Enable Variant Management](#enable-variant-management-object-page)
- [Enable Personalization (Filter, Sort, Columns)](#enable-personalization)
- [Enable Full Screen Mode](#enable-full-screen-mode)
- [Adding Titles to Object Page Tables](#adding-titles-to-object-page-tables)
- [Adding Segmented Buttons to a Table Toolbar](#adding-segmented-buttons-to-a-table-toolbar)
- [Enabling Inline Creation of Table Entries on Object Page](#enabling-inline-creation-of-table-entries-on-object-page)
- [Using the 'Export to Spreadsheet' Feature](#using-the-export-to-spreadsheet-feature)
- [Custom Actions](#custom-actions-object-page-section-table)
- [Chart](#chart)
- [Custom Section and Subsection](#custom-section-and-subsection)
- [Custom Subsection](#custom-subsection)
- [Footer Bar](#footer-bar)
- [Determining actions](#determining-actions)
- [Custom Actions](#custom-actions-object-page-footer)
- [Custom Object Page](#custom-object-page)


# [List Report](https://experience.sap.com/fiori-design-web/list-report-floorplan-sap-fiori-element/)

## 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`](../../search?q=Draft)

The annotation `@odata.draft.enabled` adds the draft mode to an entity.

```cds
annotate srv.RootEntities with @odata.draft.enabled;
```

### Replacing Standard UI Texts

Search term: [`"enhanceI18n"`](../../search?q=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](app/listreport-objectpage/webapp/manifest.json) file.

```json
"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" entity
- `C_OPERATIONS_ACTION_CONFIRM_MESSAGE|RootEntities|criticalAction` is the key for the "criticalAction" action of the "RootEntities" entity

```properties
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](https://sapui5.hana.ondemand.com/#/topic/b8cb649973534f08a6047692f8c6830d).

### Custom Actions

Search term: [`CustomActions`](../../search?q=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](app/listreport-objectpage/webapp/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.

```json
"CustomActionSection" : {
"press": "sap.fe.showcase.lrop.ext.CustomActions.messageBox",
"enabled": "{= ${ui>/editMode} !== 'Editable'}",
"visible" : true,
"text": "{i18n>CustomActionSection}"
}
```

The following code snippet is the [Extension controller for the list report](app/listreport-objectpage/webapp/ext/controller/RootEntityLRExtension.controller.ts) file from the example. "enabled" and "enabledForSingleSelect" are possible functions for the "enabled" property.

```ts
...
export default class RootEntityLRExtension extends ControllerExtension {
messageBox() {
MessageBox.alert("Button pressed");
}
enabled() {
return true;
}
enabledForSingleSelect(oBindingContext: ODataContextBinding, aSelectedContexts: [Context]) {
if (aSelectedContexts && aSelectedContexts.length === 1) {
return true;
}
return false;
}
}
```

#### Invoking CAP actions out of a Custom Action

Search term: [`#EditFlowAPI`](../../search?q=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.

```ts
...
export default class RootEntityOPExtension extends ControllerExtension {
...

//Search-Term: #EditFlowAPI
onChangeCriticality(oEvent: Button$PressEvent) {
let sActionName = "LROPODataService.changeCriticality";
this.base.getExtensionAPI().getEditFlow().invokeAction(sActionName, {
contexts: oEvent.getSource().getBindingContext()! as Context,
model: oEvent.getSource().getModel() as ODataModel,
label: 'Confirm',
invocationGrouping: "ChangeSet"
}); //SAP Fiori elements EditFlow API
}
}
```

### Default sorting and filtering

Search terms: [`"defaultTemplateAnnotationPath"`](../../search?q=defaultTemplateAnnotationPath), [`#DefaultSortFilter`](../../search?q=DefaultSortFilter)

It is possible to apply advanced default filters and sorting by specifying a `@UI.SelectionPresentationVariant` and referencing it in the [manifest](app/worklist/webapp/manifest.json). Only a `@UI.SelectionPresentationVariant` can be referenced.

```json
"OrdersList": {
...
"options": {
"settings": {
"contextPath": "/Orders",
"defaultTemplateAnnotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#DefaultFilter",
...
}
}
}
```

The `SelectionVariant` part is ignored when it is applied to a WorkList.

More information are available in the [SAP UI5 Dokumentation](https://sapui5.hana.ondemand.com/#/topic/49a6ba5b8d6946208322a9f7e16837c2.html)

## Header Area List Report

### Enabling Variant Management

Search term: [`"variantManagement"`](../../search?q=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](app/listreport-objectpage/webapp/manifest.json).

```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](app/listreport-objectpage/webapp/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](app/listreport-objectpage/webapp/i18n/i18n.properties) file within the webapp folder of the app.

```json
"sap.app": {
...
"subTitle": "{{appSubTitle}}",
...
}
```

### Enabling Live Mode

Search term: [`"liveMode"`](../../search?q=liveMode)

To simplify the user experience you can enable live mode in your app, which removes the "GO" button from the filter bar and directly applies filters and search queries.

It is enabled in the [manifest.json](app/listreport-objectpage/webapp/manifest.json):

```json
"RootEntityListReport": {
...
"options": {
"settings": {
"liveMode": true,
...
}
}
}
```

### Define Filters

Search term: [`#FilterDefault`](../../search?q=FilterDefault), [`#HideFilter`](../../search?q=HideFilter),[`#FilterGrouping`](../../search?q=FilterGrouping), [`#VisibleFilters`](../../search?q=VisibleFilters), `#ValueHelps`, [`#DependentFilter`](../../search?q=DependentFilter)

#### Default Values

Search term: [`#FilterDefault`](../../search?q=FilterDefault)

With the annotation `@Common.FilterDefaultValue` default values can be defined, like in [field-control.cds](app/listreport-objectpage/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.SelectionPresentationVariant], explained in [Default sorting and filtering](#default-sorting-and-filtering), is a better solution.
More information are available in the [SAP UI5 Dokumentation](https://sapui5.hana.ondemand.com/#/topic/f27ad7bc1f9c4b0d947b1fb18c37e94c)

#### Hide filters

Search term: [`#HideFilter`](../../search?q=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](app/listreport-objectpage/field-control.cds).

```cds
annotate srv.RootEntities {
...
fieldWithURLtext @UI.HiddenFilter;
...
};
```

#### Filter facets

Search term: [`#FilterGrouping`](../../search?q=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.

```cds
annotate srv.RootEntities with @(
UI.FilterFacets : [
{
Target : '@UI.FieldGroup#chartData',
Label : '{i18n>chartData}',
},
{
Target : '@UI.FieldGroup#location',
Label : '{i18n>location}',
},
],
);
annotate srv.RootEntities with @(
UI.FieldGroup #chartData : {
Data : [
{Value : integerValue},
{Value : targetValue},
{Value : forecastValue},
{Value : dimensions},
{Value : integerValue},
]
},
);
```

The implementation is in the [layout.cds](app/listreport-objectpage/layout.cds) file.

#### Selection Fields

Search term: [`#VisibleFilters`](../../search?q=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](app/listreport-objectpage/layout.cds) file.

```cds
annotate srv.RootEntities with @(
UI.SelectionFields : [
field,
fieldWithPrice,
criticality_code,
],
);
```

Further information are available in the [UI5 Dokumentation](https://sapui5.hana.ondemand.com/#/topic/4de40b31324e4876a8421f6f642e0140).

#### Mandatory filter fields

Search term: [`#RequiredFilter`](../../search?q="#RequiredFilter")

With the annotation `@Capabilities.FilterRestrictions.RequiredProperties` an array of mandatory filter fields can be defined. In the Feature showcase only the property 'stringProperty' is required for demonstration purposes. The annotation can be found in the [capabilities.cds](app/listreport-objectpage/capabilities.cds) file.

```cds
annotate srv.RootEntities with @(
...
Capabilities.FilterRestrictions : {
...
RequiredProperties : [
stringProperty
],

},
);
```

#### Enable semantic dates for filter fields of type Date

since UI5 Version: 1.99.0
Search term: [`#SemanticDateFilter`](../../search?q="#SemanticDateFilter"), [`useSemanticDateRange`](../../search?q=useSemanticDateRange)

For filter fields of type Date, semantic dates can be activated with the annotation `@Capabilities.FilterRestrictions.FilterExpressionRestrictions`. The annotation expects an array. Each object is for one field. The "Property" value has to be the name of the date field and the "AllowedExpressions" value is either 'SingleValue' or 'SingleRange'.
SingleValue currently gives the options to select a date or select 'Today', 'Yesterday' or 'Tomorrow'.
SingleRange additionally adds the options 'From/To', 'From', 'To' and 'Year To Date'.

```cds
annotate srv.RootEntities with @(
Capabilities.FilterRestrictions : {
FilterExpressionRestrictions : [
{
Property : 'validFrom',
AllowedExpressions : 'SingleRange'
}
],
...
},
);
```

If you want to disable semantic dates entirely you can do so, by setting the `useSemanticDateRange` property to false in the manifest.json file. The default value is true. In addition you can specify the default value for semantic date ranges in the manifest. The documentation link below lists all options. Please note, that they have to be fully in uppercase.

```json
"RootEntityListReport": {
"options": {
"settings": {
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.SelectionFields": {
"useSemanticDateRange": true,
"filterFields": {
"validFrom": {
"settings": {
"defaultValues": [{"operator": "LASTYEARS", "values": [10]}]
}
}
}
}
},
}
}
},
```

More information are available in the [SAP UI5 Documentation](https://sapui5.hana.ondemand.com/#/topic/fef65d03d01a4b2baca28983a5449cf7.html).

#### Case insensitive filtering

Search term: [`#CaseInsensitiveFiltering`](../../search?q="#CaseInsensitiveFiltering")

Case insensitive filtering can be activated with the annotation `@Capabilities.FilterFunctions` and the string 'tolower' as part of the array.
It can only be applied to the whole service and is then valid for filtering with the filter bar, with table personalization filters and within value helps.

```cds
annotate LROPODataService with @(
Capabilities.FilterFunctions : [
'tolower'
],
);
```

If the annotation does not exists, case sensitive filtering is active and the backend decides on the default behavior.
The example is in the [capabilities.cds](app/listreport-objectpage/capabilities.cds) file.

More information are available in the [SAP UI5 Documentation](https://sapui5.hana.ondemand.com/sdk/#/topic/609c39a7498541559dbef503c1ffd194.html).

#### Value Help

Search terms: [](../../search?q=)`#ValueHelps`, [](../../search?q=)`#RadioButtons`

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`.

```cds
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.

##### Value help as a dropdown

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.

##### Value help as radio buttons

If you, in addition, annotate the property with `@Common.ValueListWithFixedValues.@Common.ValueListShowValuesImmediately` the value help will not render as a dropdown, but instead with radio buttons.

```cds
annotate schema.RootEntities with{
criticality_code @(Common : {
ValueListWithFixedValues,
ValueListWithFixedValues.@Common.ValueListShowValuesImmediately,
});
};
```

By default the rendering is vertical and with a [manifest.json](app/listreport-objectpage/webapp/manifest.json) setting it can be adjusted to horizontal.

```json
"RootEntityListReport": {
"options": {
"settings": {
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.FieldGroup#ShowWhenInEdit": {
"fields": {
"DataField::criticality_code": {
"formatOptions": {
"radioButtonsHorizontalLayout": false
}
}
}
}
}
}
}
}
```

Rendering as radio buttons is currently only supported for fields on pages and not for fields in action dialogs.

All value help annotations are in the [value-helps.cds](app/listreport-objectpage/value-helps.cds) file.

#### Dependent Filtering (Value Help)

Search term: [`#DependentFilter`, `#ConstantFilter`](../../search?q=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.

```cds
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](app/listreport-objectpage/value-helps.cds#L71).

If you want to statically filter for a value you can use `Common.ValueListParameterConstant`, where you need to provide the property to filter and a constant value to use for filtering.

```cds
annotate schema.RootEntities with {
regionWithConstantValueHelp @(Common : {
Text : regionWithConstantValueHelp.name,
TextArrangement : #TextFirst,
ValueListWithFixedValues: true,
ValueList : {
Label : '{i18n>region}',
CollectionPath : 'Regions',
Parameters : [
{
$Type : 'Common.ValueListParameterInOut',
ValueListProperty : 'code',
LocalDataProperty : region_code
},
{
$Type : 'Common.ValueListParameterConstant',
ValueListProperty : 'country_code',
Constant : 'DE',
},
]
}
});
}
```

#### Dependent filtering (Multi-Input Value Help)

Search term: [`#MultiValueWithDependentFilter`](../../search?q=MultiValueWithDependentFilter)

Dependent filters can also use properties from the parent entity. This is especially useful for multi-input fields, which have a value help. In the example the root entity has a country assigned and multiple regions shall be assigned to the root entity. For that an assignment entity is being used. To only show regions of the selected country a reference to the root entity can be used.

```cds
annotate schema.AssignedRegions 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.ValueListParameterIn',
LocalDataProperty : root.country_code,
ValueListProperty : 'country_code',
},

]
}
});
}
```

In the code snippet the 'LocalDataProperty' refers to the country reference and maps it to the 'country_code' property of the 'Regions' entity, which is the target of the value help.

The value help itself is annotated on the property within the assignment entity. This is also the target property of the DataField value path.

```cds
annotate srv.RootEntities with @(
...
UI.FieldGroup #location : {
Data : [
...
{
Value : regions.region_code,
Label : '{i18n>MultiInputFieldWithVH}'
}
]
},
...
)
```

#### Adding navigation properties

Search term: [`navigationProperties`](../../search?q=navigationProperties), [`#NavigationProperties`](../../search?q="#NavigationProperties")

Navigation properties can be as well added to the filter bar. For this the navigation path has to be added to the `@UI.SelectionFields` annotation.

```cds
annotate srv.RootEntities with @(
UI.SelectionFields : [
...
childEntities1.criticalityValue_code
],
);
```

If you want to add navigation properties to the "Adapt Filters" dialog as filter facets, they have to be referenced in the [manifest.json](app/listreport-objectpage/webapp/manifest.json) file.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
...
"@com.sap.vocabularies.UI.v1.SelectionFields": {
"navigationProperties": [ "childEntities1", "Order/decimalProperty" ],
...
}
},
...
}
}
},
```

When only the association is referenced, all fields of it will be available in a separate filter facet for the specified association. Defining a path to a specific property of the association, will only add the specified property to the "Adapt Filters" dialog.

More information regarding navigation properties as filter fields are in the [SAP Fiori elements Documentation](https://sapui5.hana.ondemand.com/#/topic/609c39a7498541559dbef503c1ffd194).

#### Custom Filter

Search term: [`customFilter`](../../search?q=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](app/listreport-objectpage/webapp/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.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
...
"@com.sap.vocabularies.UI.v1.SelectionFields": {
"filterFields": {
"starsValue": {
"label": "{i18n>customFilter}",
"property": "starsValue",
"template": "sap.fe.showcase.lrop.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'.

```xml






```

The following code is an example for a reset function. "starsValue" is the property name of the entity set which is filtered.

```ts
...
export default class RootEntityLRExtension extends ControllerExtension {
...

onResetRating(oEvent: Button$PressEvent) {
this.base.getExtensionAPI().setFilterValues("starsValue");
}
}
```

More information regarding custom filter are in the [SAP Fiori elements Documentation](https://sapui5.hana.ondemand.com/#/topic/5fb9f57fcf12401bbe39a635e9a32a4e).

### Custom Actions (Global List Report)

Search term: [`"CustomActionLRGlobal"`](../../search?q=CustomActionLRGlobal)

With extension points custom actions can be added in the header area of the List Report.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"content" : {
"header" : {
"actions" : {
"CustomActionLRGlobal" : {
"press": "sap.fe.showcase.lrop.ext.CustomActions.messageBox",
"enabled": "sap.fe.showcase.lrop.ext.CustomActions.enabled",
"visible" : true,
"text": "{i18n>CustomActionLRGlobal}"
}
}
}
}
}
}
},
```

The custom action itself is described here: [Custom Actions](#custom-actions)

## Content Area List Report

### Configuring Tables

#### Actions

Search term: [`#UnboundAction`](../../search?q=UnboundAction), [`#BoundAction`](../../search?q=BoundAction), [`#SideEffect`](../../search?q=SideEffect), [`#ValueHelpParameter`](../../search?q=ValueHelpParameter), [`"MenuActions"`](../../search?q=MenuActions), [`#DynamicCRUD`](../../search?q=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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAction',
Action : 'LROPODataService.changeCriticality',
Label : '{i18n>changeCriticality}',
},
...
],
);
```

[layouts_RootEntities.cds](app/listreport-objectpage/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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAction',
Action : 'LROPODataService.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 `srv.unboundAction` you have to refer to `LROPODataService.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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAction',
Action : 'LROPODataService.EntityContainer/unboundAction',
Label : '{i18n>unboundAction}',
},
...
],
);
```

With `@Core.OperationAvailable` actions can by enabled or disabled. This can be done dynamically by using $edmJson for its value, like:

```cds
@Core.OperationAvailable: {$edmJson: {$Path: '/Singleton/enabled'}}
action unboundAction(@(title : '{i18n>inputValue}')input : String);
```

The path can be absolute like in the example pointing to a singleton or also for bound actions relative to the bound context, like:

```cds
@(
...
Core.OperationAvailable: ($self.integerValue > 0)
)
action changeProgress (
...
);
```

'in' refers to the bound context. Without 'in' the path would refer to an action parameter.

##### Side Effects of actions

Search term: [`#SideEffect`](../../search?q=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.

```cds
entity RootEntities as select from persistence.RootEntities actions {
...
@(
Common.SideEffects : {
TargetProperties : ['in/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`](../../search?q=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.

```cds
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`](../../search?q=ParameterDefaultValue)

With the annotation `@UI.ParameterDefaultValue` a default value for the parameter is set.

```cds
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"`](../../search?q=MenuActions)

A dropdown menu to group actions is possible with an annotation in the [manifest.json](app/listreport-objectpage/webapp/manifest.json) file.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
"actions": {
"MenuActions": {
"text": "{i18n>MenuButton}",
"menu": [
"DataFieldForAction::LROPODataService.changeCriticality",
"DataFieldForAction::LROPODataService.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`](../../search?q="#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.

Since UI5 Version 1.100 also Singleton are supported as values.
The Syntax for Singletons is special, as it can be seen in the code snippet. The path value starts with a '/' followed by the name of the singleton, in the Feature Showcase it is 'Singleton', ending with the property path segment.

```cds
annotate srv.RootEntities with @(
Capabilities.DeleteRestrictions : {
Deletable : deletePossible,
},
UI.UpdateHidden : updateHidden,
UI.CreateHidden: { $edmJson: { $Path: '/Singleton/createHidden' } },
);
```

[capabilities.cds](app/listreport-objectpage/capabilities.cds)

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`](../../search?q=NavAction)

A navigation action navigating to an associated entity can be added, through adding the `UI.DataFieldForIntentBasedNavigation` as a line item.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForIntentBasedNavigation',
Label : '{i18n>IntentBasedNavigation}',
SemanticObject : 'FeatureShowcaseOrder',
Action : 'manage',
RequiresContext : true,
Inline : true,
IconUrl : 'sap-icon://cart',
Mapping : [
{
$Type : 'Common.SemanticObjectMappingType',
LocalProperty : integerValue,
SemanticObjectProperty : 'integerProperty',
},
],
@UI.Importance : #High,
},
...
],
);
```

[layouts_RootEntities.cds](app/listreport-objectpage/layouts_RootEntities.cds)

The semantic object and the action are in the [manifest.json](app/worklist/webapp/manifest.json) file. The application property in this contains the following code snippet:

```json
"sap.app" : {
...,
"crossNavigation": {
"inbounds": {
"feature-showcase-worklist": {
"signature": {
"parameters": {},
"additionalParameters": "allowed"
},
"semanticObject": "FeatureShowcaseOrder",
"action": "manage",
"title": "Work List",
"subTitle": "Manage"
}
}
}
}
```

Here "FeatureShowcaseOrder" 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`](../../search?q=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.

```cds
annotate srv.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](https://cap.cloud.sap/docs/node.js/events#req-msg).

```ts
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"`](../../search?q=CustomActionLR)

With extension points custom actions can be added in the table toolbar of the List Report.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
"actions": {
...
"CustomActionLR" : {
"press": "sap.fe.showcase.lrop.ext.CustomActions.messageBox",
"enabled": "sap.fe.showcase.lrop.ext.CustomActions.enabledForSingleSelect",
"visible" : true,
"text": "{i18n>CustomActionLR}"
}
},
...
}
},
...
}
}
},
```

The custom action itself is described here: [Custom Actions](#custom-actions-list-report)

#### Setting the Table Type

INFO: We recommend that you use [SAP Fiori tools](http://help.sap.com/disclaimer?site=https://help.sap.com/viewer/product/SAP_FIORI_tools/Latest/en-US), 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"`](../../search?q=tableSettings), [`"ResponsiveTable"`](../../search?q=ResponsiveTable), [`"GridTable"`](../../search?q=GridTable), [`"AnalyticalTable"`](../../search?q=AnalyticalTable)

Supported table types are the ResponsiveTable, the GridTable, the AnalyticalTable and the TreeTable. The table type of the List Report can be adjusted in the [manifest.json](app/listreport-objectpage/webapp/manifest.json) file.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"tableSettings": {
"type": "ResponsiveTable",
...
},
...
},
...
},
...
}
}
},
```

The analytical table sample is located on the Object Page in the WorkList application, defined in the WorkList [annotations.cds file](./app/worklist/annotations.cds#74).

##### Tree Table

Search term: [`#TreeTable`](../../search?q=`#TreeTable`), [`"TreeTable"`](../../search?q=TreeTable)

Tree tables allow you to display hierarchical data, namely parent-child hierarchies. To enable those in the tree table, the table type has to be set in the [manifest.json](app/listreport-objectpage/webapp/manifest.json):

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"/OrganizationalUnits/@com.sap.vocabularies.UI.v1.LineItem": {
"tableSettings": {
"type": "TreeTable",
"hierarchyQualifier": "OrgUnitsHierarchy"
}
}
},
...
}
}
}
```

Most importantly, the 'hierarchyQualifier' in the manifest needs to match the qualifier of the `@Aggregation.RecursiveHierarchy` annotation, which specifies the parent-child hierarchy.

```cds
annotate srv.OrganizationalUnits @Aggregation.RecursiveHierarchy #OrgUnitsHierarchy : {
ParentNavigationProperty : superOrdinateOrgUnit,
NodeProperty : ID,
};
```

`ParentNavigationProperty` must have the association as its value, which points back to the same entity, for example `OrganizationalUnits`, and determines the parent of a node, where the `NodeProperty` uniquely identifies a node in the hierarchy, usually the UUID property of said entity.

For CAP you must also add the following annotations and properties, as SAP Fiori elements requires those for the tree table to work:

> [!NOTE]
> It is planned that this is automatically added in the future by CAP to reduce setup overhead.

```cds
extend srv.OrganizationalUnits with @(
// The columns expected by Fiori to be present in hierarchy entities
Hierarchy.RecursiveHierarchy #OrgUnitsHierarchy : {
LimitedDescendantCount : LimitedDescendantCount,
DistanceFromRoot : DistanceFromRoot,
DrillState : DrillState,
LimitedRank : LimitedRank
},
// Disallow filtering on these properties from Fiori UIs
Capabilities.FilterRestrictions.NonFilterableProperties: [
'LimitedDescendantCount',
'DistanceFromRoot',
'DrillState',
'LimitedRank'
],
// Disallow sorting on these properties from Fiori UIs
Capabilities.SortRestrictions.NonSortableProperties : [
'LimitedDescendantCount',
'DistanceFromRoot',
'DrillState',
'LimitedRank'
],
) columns { // Ensure we can query these fields from database
null as LimitedDescendantCount : Int16,
null as DistanceFromRoot : Int16,
null as DrillState : String,
null as LimitedRank : Int16,
};
```

The tree table works with draft-enabled entities, although some restrictions apply, such as only active entities being shown, and having a draft indicator if a draft exists, instead of showing the draft.

For a full list of restrictions, see the [documentation](https://ui5.sap.com/#/topic/7cf7a31fd1ee490ab816ecd941bd2f1f).

You can use `@Hierarchy.RecursiveHierarchyActions` to specify some additional actions:

- `ChangeSiblingForRootsSupported` is a Boolean tag that controls whether root nodes can be moved up or down and whether nodes can be placed between two root nodes. If it is not defined, it is considered to be true.
- `ChangeNextSiblingAction` specifies a bound action that can be used to move a node up or down in the hierarchy. The bound action is called by the UI, passing a NextSibiling parameter, when a node is dropped onto another node for switching positions, or when the Move Up/Down buttons are pressed to change the order of nodes that are on the same level.
- `CopyAction` specifies the bound action that is called to copy the bound entity to later paste it in the hierarchy.

```cds
annotate srv.OrganizationalUnits @(
...
Hierarchy.RecursiveHierarchyActions #OrgUnitsHierarchy : {
ChangeSiblingForRootsSupported,
ChangeNextSiblingAction : 'LROPODataService.moveOrgUnit',
CopyAction : 'LROPODataService.copyOrgUnit',
},
);
```

Using `Capabilities.UpdateRestrictions.NonUpdatableNavigationProperties` and providing the association of the parent disables all change actions on the hierarchy.

> [!CAUTION]
> The restriction is currently not enforced on the API level!

```cds
annotate srv.OrganizationalUnits @(
...
Capabilities.UpdateRestrictions.NonUpdatableNavigationProperties: [superOrdinateOrgUnit]
);
```

You can also customize the create button to show special options for different entities in the hierarchy using the [manifest.json](app/listreport-objectpage/webapp/manifest.json).

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"/OrganizationalUnits/@com.sap.vocabularies.UI.v1.LineItem": {
"tableSettings": {
"type": "TreeTable",
"hierarchyQualifier": "OrgUnitsHierarchy",
"creationMode": {
"name": "CreationDialog",
"createInPlace": true,
"creationFields": "@com.sap.vocabularies.UI.v1.FieldGroup#creationDialog",
"nodeType": {
"propertyName": "category_code",
"values": {
"01": "Create a new department",
"02": {
"label": "Create a new division",
"creationFields": "name,description,isActive"
},
"03": "Create a new business unit"
}
},
"isCreateEnabled": ".extension.sap.fe.showcase.lrop.ext.controller.RootEntityLRExtension.isCreateEnabled"
},
...
}
}
},
...
}
}
}
```

The sample uses the "CreationDialog" creation mode, but "NewPage" and "Inline" also work ("Inline" only on the Object Page).

Tip: Use the "nodeType" property in the tree table to achieve a creation menu in which a separate option is shown for each key in the "values" object.

The "values" object accepts two value types: strings (used directly as labels) or objects, for the "CreationDialog" only, that contain both a label and an alternative creation dialog, which overrides the original dialog, specified through "creationFields" in "creationMode".

Use the extension hook `isCreateEnabled` to control in which context the create button can be pressed to provide a callback function. It must return a Boolean value determining whether creation is allowed for a specific combination of a given value from the "values" object and a selected node in the tree table.

In the showcase, this allows you to specify that only business units can be created at root level, only divisions under business units, and only departments under divisions.

> [!CAUTION]
> This only enables/disables the create buttons, backend restrictions are still necessary for enforcing this at an API level!

```ts
export default class RootEntityLRExtension extends ControllerExtension {
...
isCreateEnabled(value: String, parentContext?: Context) {
switch (parentContext?.getProperty("category_code")) {
case "03":
return value === "02"; // Only Divisions under Business Units
case "02":
return value === "01"; // Only Departments under Divisions
case "01":
return false; // Nothing under Departments
default:
return value === "03"; // Only Business Units at root level
}
}
...
}
```

You can use further extension hooks to customize the tree table behavior.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"/OrganizationalUnits/@com.sap.vocabularies.UI.v1.LineItem": {
"tableSettings": {
"type": "TreeTable",
"hierarchyQualifier": "OrgUnitsHierarchy",
...
"isMoveToPositionAllowed": ".extension.sap.fe.showcase.lrop.ext.controller.RootEntityLRExtension.isMoveToPositionAllowed",
"isNodeMovable": ".extension.sap.fe.showcase.lrop.ext.controller.RootEntityLRExtension.isNodeMovable",
"isCopyToPositionAllowed": ".extension.sap.fe.showcase.lrop.ext.controller.RootEntityLRExtension.isCopyToPositionAllowed",
"isNodeCopyable": ".extension.sap.fe.showcase.lrop.ext.controller.RootEntityLRExtension.isNodeCopyable"
}
}
},
...
}
}
}
```

`isNodeMovable` needs a callback function that provides the OData context and returns a Boolean value that determines whether a node can be moved around the hierarchy via drag & drop or the move up and down buttons. Furthermore, it determines if a node can be cut.

`isMoveToPositionAllowed` also needs a callback function and is the counterpart to `isNodeMovable`. It returns a Boolean value that determines if a node can be moved to a given position. To determine this, SAP Fiori elements passes the OData context of the node to be moved and the OData context of the node under which the node should be moved or dropped.

`isNodeCopyable` and `isCopyToPositionAllowed` have the same signatures, but `isNodeCopyable` specifies whether a node can be copied and `isCopyToPositionAllowed` specifies whether the copied node can be pasted at a given position.

#### Multiple Views

Search terms: [`#multipleViews`](../../search?q=`#multipleViews`), [`"views"`](../../search?q=views), `[`#multipleViews`](../../search?q=`#multipleViews`), ["quickVariantSelection"`](../../search?q=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"`](../../search?q=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).

```json
"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"`](../../search?q=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](app/listreport-objectpage/webapp/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.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"views": {
"paths": [
{
"key": "tab1",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#variant1"
},
{
"key": "tab2",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SelectionPresentationVariant"
},
{
"key": "tab3",
"entitySet": "OrganizationalUnits",
"annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#activeOrgUnits"
}
],
"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](app/listreport-objectpage/webapp/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](https://sapui5.hana.ondemand.com/#/topic/b6b59e4a4c3548cf83ff9c3b955d3ba3).

##### Selection Variant

Search term: [`#SVariant`](../../search?q=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.

```cds
annotate srv.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](app/listreport-objectpage/layouts_RootEntities.cds) file.

##### Selection Presentation Variant

Search term: [`#SPVariant`](../../search?q=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.

```cds
annotate srv.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](https://sapui5.hana.ondemand.com/#/topic/37aeed74e17a42caa2cba3123f0c15fc).

#### Creation Dialog

Search term: [`#CreationDialog`](../../search?q=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.

```cds
annotate srv.RootEntities {
...
stringProperty @Core.Immutable;
...
};
```

#### Defining the Default Sort Order

Search term: [`#DefaultSort`](../../search?q=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.

```cds
annotate srv.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](app/listreport-objectpage/layout.cds)

#### Enabling Multiple Selection in Tables

INFO: We recommend that you use [SAP Fiori tools](http://help.sap.com/disclaimer?site=https://help.sap.com/viewer/product/SAP_FIORI_tools/Latest/en-US), 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"`](../../search?q=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](https://sapui5.hana.ondemand.com/#/topic/116b5d82e8c545e2a56e1b51b8b0a9bd).

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"tableSettings": {
"type": "ResponsiveTable",
"selectionMode": "Multi",
...
},
...
},
...
},
...
}
}
},
```

#### Handling Semantic Key Fields

Search term: [`#SemanticKey`](../../search?q=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.

```cds
annotate srv.RootEntities with @(
Common.SemanticKey : [ field ],
);
```

[layouts_RootEntities.cds](app/listreport-objectpage/layouts_RootEntities.cds)

#### Highlighting Line Items Based on Criticality

Search term: [`#LineItemHighlight`](../../search?q=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.

```cds
annotate srv.RootEntities with @(
UI.LineItem.@UI.Criticality : criticality_code,
);
```

#### Adding a Rating Indicator to a Table

Search term: [`#RatingIndicator`](../../search?q=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.

```cds
annotate srv.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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Label : '{i18n>ratingIndicator}',
Target : '@UI.DataPoint#ratingIndicator',
@UI.Importance : #Low,
},
...
],
);
```

The annotations are in the [layouts_RootEntities.cds](app/listreport-objectpage/layouts_RootEntities.cds) file.

#### Adding a Progress Indicator to a Table

Search term: [`#ProgressIndicator`](../../search?q=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.

```cds
annotate srv.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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Label : '{i18n>progressIndicator}',
Target : '@UI.DataPoint#progressIndicator',
@UI.Importance : #Low,
},
...
],
);
```

The annotations are in the [layouts_RootEntities.cds](app/listreport-objectpage/layouts_RootEntities.cds) file.

#### Adding a field with a tooltip to a Table

Search term: [`#ToolTip`](../../search?q=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.

```cds
annotate srv.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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : '@UI.DataPoint#fieldWithTooltip',
Label : '{i18n>fieldWithToolTip}',
},
...
],
);
```

#### Adding a Smart Micro Chart to a Table

Search term: [`#MicroChart`](../../search?q=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.

```cds
annotate srv.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.

```cds
annotate srv.RootEntities with @(
...
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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : '@UI.Chart#radialChart',
Label : '{i18n>radialChart}',
},
...
],
);
```

The annotations of the example are in the [layouts_RootEntities.cds](app/listreport-objectpage/layouts_RootEntities.cds) file.

#### Adding a Contact Quick View to a Table

Search term: [`#Contact`](../../search?q=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:

```cds
annotate srv.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](https://sapui5.hana.ondemand.com/#/topic/a6a8c0c4849b483eb10e87f6fdf9383c.html).
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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$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](app/listreport-objectpage/layouts_RootEntities.cds#L315) file.

#### Adding a Quick View Facet to a Table

Search term: [`#QuickView`](../../search?q=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`.

```cds
annotate srv.Orders with @(
UI.FieldGroup #data : {
Label : '{i18n>Order}',
Data : [
{Value : field2},
{Value : integerProperty},
{Value : field4},
],
},
);
```

```cds
annotate srv.Orders with @(
UI.HeaderInfo :{
TypeName : '{i18n>Order}',
TypeNamePlural : '{i18n>Order.typeNamePlural}',
Title : {
$Type : 'UI.DataField',
Value : '{i18n>Order}',
},
Description : {
$Type : 'UI.DataField',
Value : field,
},
ImageUrl : '',
TypeImageUrl : 'sap-icon://blank-tag',
},
);
```

```cds
annotate srv.Orders 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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataField',
Value : association2one_ID,
Label : '{i18n>Order}',
@UI.Importance : #High,
},
...
],
);
```

The annotations of the example are in the [layouts_RootEntities.cds](app/listreport-objectpage/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.

```cds
association2one @title : '{i18n>Order}' @Common.Text : association2one.field @Common.TextArrangement : #TextOnly;
```

The annotations are in the [labels.cds](app/listreport-objectpage/labels.cds) file.

##### Links to the apps of the entity

Search term: [`FeatureShowcaseOrder`](../../search?q=FeatureShowcaseOrder), [`#Navigation`](../../search?q=Navigation)

The quick view facet also shows links to the apps of the entity, when the entity is annotated with `@Common.SemanticObject`.

```cds
association2one @Common.SemanticObject : 'FeatureShowcaseOrder';
```

The semantic object is the application name in the [manifest.json](app/worklist/webapp/manifest.json). The application property in this contains the following code snippet:

```json
"sap.app" : {
...,
"crossNavigation": {
"inbounds": {
"feature-showcase-worklist": {
"signature": {
"parameters": {
"ID": {
"required": false
},
"field3": {
"required": false
},
"integerProperty": {
"required": false
}
},
"additionalParameters": "ignored"
},
"semanticObject": "FeatureShowcaseOrder",
"action": "manage",
"title": "Work List",
"subTitle": "Manage"
}
}
}
}
```

Here "FeatureShowcaseOrder" 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. In the deployed version with a SAP WorkZone the subtitle of the app is used.

#### Adding Multiple Fields to one Column in Responsive Tables

Search term: [`#MultiFieldsCol`](../../search?q=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.

```cds
annotate srv.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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
...
{
$Type : 'UI.DataFieldForAnnotation',
Target : '@UI.FieldGroup#AdminData',
Label : '{i18n>adminData}',
@UI.Importance : #High,
},
...
],
);
```

#### Adding Images to a table

Search term: [`#Image`](../../search?q=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.

```cds
annotate srv.RootEntities with @(
UI.LineItem : [
{
$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](app/listreport-objectpage/labels.cds) file.

#### Adding Currency or UoM Fields to a table

Search term: [`#Units`](../../search?q=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](app/listreport-objectpage/labels.cds) file.

##### Customize Currency or UoM scale

Search term: [`#CustomUnitScale`](../../search?q=CustomUnitScale)

By default the scale of a field annotated with a unit or currency, is the scale contained in the datatype. E.g. `Decimal(4,2)` will have two fractional digits while `Decimal(4,3)` will have three.

If the shown fractional digits on the UI shall differ from the backend, you can customize the behaviour by adjusting the Units of Measure or Currency value list entity.

```cds
@CodeList.UnitsOfMeasure : {
Url : './$metadata',
CollectionPath : 'UnitOfMeasures',
}
service LROPODataService @(path : '/srv1') {

entity UnitOfMeasures as projection on persistence.UnitOfMeasures;
}
```

In the sample the units are customized, by specifying the `@CodeList.UnitsOfMeasure` annotation. The url points to the metadata of the same service, but you could also point to an URL of another service and the CollectionPath points to the entity of the targeted service.

The key property of the entity which is targeted then needs to be annotated with `@Common.UnitSpecificScale`, pointing to the property storing how many fractional digits should be shown for the respective unit. The fields referred to by `@Common.Text` and `@CodeList.ExternalCode` are shown in the value help when selecting a unit.

```cds
entity sap.common.UnitOfMeasures : CodeList {
// Search-Term: #CustomUnitScale
key code : String(30) @Common.Text : descr @Common.UnitSpecificScale : scale @CodeList.ExternalCode : name;
scale: Integer;
};
```

For further information check out the [documentation](https://sapui5.hana.ondemand.com/#/topic/4d1b9d44941f483f9b7f579873d38685).

#### Adding a link to a table

Search term: [`#Link`](../../search?q=Link)

With a `UI.DataFieldWithUrl` a link can be added to the table. The 'Value' property is the visible text and the 'Url' is the target.

```cds
@UI.LineItem : [
{
$Type : 'UI.DataFieldWithUrl',
Url : fieldWithURL, //Target, when pressing the text
Value : fieldWithURLtext, //Visible text
Label : '{i18n>dataFieldWithURL}',
@UI.Importance : #Medium,
},
]
```

Since UI5 1.129.0 the 'Value' property can also be annotated to determine how the link opens.

```cds
annotate srv.RootEntities with {
fieldWithURLtext @HTML5.LinkTarget : '_blank';
}
```

The annotation is documented [here](https://sap.github.io/odata-vocabularies/vocabularies/HTML5.html#LinkTarget).

#### Add custom column (Extensibility)

Search term: [`#CustomColumn`](../../search?q=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.

```xml

```

This label shall be visible as an additional column. For this the manifest.json file needs to be adjusted.

```json
"RootEntityListReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
...
"columns": {
"CustomColumn": {
"key": "customColumnLR",
"header": "{i18n>validityPeriodLR}",
"template": "sap.fe.showcase.lrop.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.showcase.lrop), 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](https://sapui5.hana.ondemand.com/#/topic/d525522c1bf54672ae4e02d66b38e60c).


# [Object Page](https://experience.sap.com/fiori-design-web/object-page/)

## General Features Object Page

### Annotations for data fields

#### Communication properties

Search term: [`#CommunicationFields`](../../search?q=CommunicationFields)

To display emails and phone numbers as a link, they are annotated with `@Communication.IsEmailAddress` or `@Communication.IsPhoneNumber`

```cds
annotate schema.RootEntities with{
...
email @title : '{i18n>email}' @Communication.IsEmailAddress;
telephone @title : '{i18n>telephone}' @Communication.IsPhoneNumber;
...
```

#### Time and Date

Search term: [`#TimeAndDate`](../../search?q=TimeAndDate)

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

```cds
aspect rootBasis : {
...
validFrom : Date;
validTo : DateTime;
time : Time;
timeStamp : Timestamp;
...
};
```

Since UI5 1.129.0 you can use `@UI.DateTimeStyle` to modify how the date is displayed.

```cds
annotate srv.RootEntities with {
validTo @UI.DateTimeStyle : 'short'
}
```

Allowed values are 'short', 'medium', 'long' and 'full'.

#### Multi line text

Search terms: `#MultiLineText`, `"formatOptions"`

With the annotation `@UI.MultiLineText` longer Strings are displayed in multiple lines.

```cds
annotate schema.RootEntities with{
...
description @title : '{i18n>description}' @UI.MultiLineText;
...
};
```

Additionally the maximum number of lines can be defined in the [manifest.json](app/listreport-objectpage/webapp/manifest.json). The data field which is annotated with the `@UI.MultiLineText` annotation is the qualifier. The format option "textLinesDisplay" defines how many lines are displayed in the read only mode and "textLinesEdit" defines it correspondingly for the edit mode. "textMaxLines" defines how many lines are maximal possible, if lesser are used, lesser are displayed.
Another option for "textMaxCharactersDisplay" is "Infinity", to display the text completely and for "textExpandBehaviorDisplay" "InPlace", to expand the text on the page. "InPlace" is the default option.

```json
"RootEntityObjectReport": {
...
"options": {
"settings": {
...
"controlConfiguration": {
...
"@com.sap.vocabularies.UI.v1.FieldGroup#Section": {
"fields": {
"DataField::description": {
"formatOptions": {
"textLinesDisplay": 1,
"textLinesEdit": 3
}
},
"DataField::description_customGrowing": {
"formatOptions": {
"textMaxLines": "5",
"textMaxCharactersDisplay": 400,
"textExpandBehaviorDisplay" : "Popover"
}
}
},
...
},
...
},
...
}
}
},
```

More information are available in the [SAP Fiori elements Documentation](https://sapui5.hana.ondemand.com/1.94.1/#/topic/c18ada4bc56e427a9a2df2d1898f28a5.html).

#### Placeholder values

Search term: [`#Placeholder`](../../search?q=Placeholder)

With `@UI.Placeholder` a placeholder value can be defined, for when the field is in edit mode.

```cds
annotate schema.RootEntities with {
...
region @title : '{i18n>region}' @UI.Placeholder : 'Select a region';
...
};
```

The value can also be a property path.

## Header Area Object Page

INFO: We recommend that you use [SAP Fiori tools](http://help.sap.com/disclaimer?site=https://help.sap.com/viewer/product/SAP_FIORI_tools/Latest/en-US), 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: [`"anchorBarVisible"`](../../search?q=anchorBarVisible)

By default, the header of an Object Page and the anchor bar are enabled. Both can be disabled with the SAP Fiori tools or in the manifest.json.

```json
"RootEntityObjectReport": {
...
"options": {
"settings": {
...
"content": {
"header": {
"anchorBarVisible": true,
"visible": true,
...
},
...
}
}
}
},
```

### Title and Subtitle

Search term: [`#HeaderInfo`](../../search?q=HeaderInfo)

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

```cds
annotate srv.RootEntities with @(
UI.HeaderInfo :{
TypeName : '{i18n>RootEntities}',
TypeNamePlural : '{i18n>RootEntities.typeNamePlural}',
Title : {
$Type : 'UI.DataField',
Value : field,
},
Description : {
$Type : 'UI.DataField',
Value : '{i18n>RootEntities}',
},
ImageUrl : imageUrl,
TypeImageUrl : 'sap-icon://sales-order',
},
);
```

[layouts_RootEntities.cds](app/listreport-objectpage/layouts_RootEntities.cds).
The "TypeName" is the Title and it is displayed next to the SAP Logo in header bar on the Object Page.
The "TypeNamePlural" will be shown, if all entities are shown in a table on the parent Object Page (this is not the case in the example).
The "Title" of the Object Page, displayed in the actual header on the left side in bold. It should display a language-dependent product text in SAP back-end systems.
The "Description" is beneath the "Title" and displays normally the product title in SAP back-end systems.
If the optional "ImageUrl" property 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.

#### Dynamic title or subtitle

Search term: [`#ODataConcat`](../../search?q=ODataConcat)

It is possible to use an expression in the `@UI.HeaderInfo` annotation for the "Title" and "Description" values to concat multiple properties together.

```cds
annotate service.ChildEntities1 with @(
UI.HeaderInfo : {
...
Description : {
Value : ('Using odata.concat - Field: ' || field),
},
...
},
);
```

In this sample a string is concatenated to the value of the 'field' property. More complex scenarios, using the "$If" are also possible, like:

```cds
annotate service.ChildEntities1 with @(
UI.HeaderInfo : {
...
Description : {
Value : ('Using odata.concat - Field: ' || (field = 'child entity 1' ? field : 'Other child entities')),
},
...
},
);
```

### Header Facets

Search term: [`#HeaderFacets`](../../search?q=HeaderFacets)

The header facets are a collection of facets which are displayed in the header of an Object Page. Both `UI.ReferenceFacet` and `UI.CollectionFacet` are supported. The facets are added to the `@UI.HeaderFacets` annotation. Collection facets need to have an ID, to work properly.

```cds
annotate srv.RootEntities with @(
UI.HeaderFacets : [
{
$Type : 'UI.ReferenceFacet',
Target : '@UI.DataPoint#fieldWithPrice',
},
{
$Type : 'UI.CollectionFacet',
Facets : [
...
],
},
...
],
)
```

#### Plain Text

Search term: [`#PlainText`](../../search?q=PlainText)

Plain text can be displayed, by adding a normal data field to a field group and use this field group as a target of a reference facet.

```cds
annotate srv.RootEntities with @(
UI.HeaderFacets : [
...
{
$Type : 'UI.ReferenceFacet',
Target : '@UI.FieldGroup#plainText',
Label : '{i18n>plainText}'
},
],
);
```

```cds
annotate srv.RootEntities with @(
UI.FieldGroup #plainText : {
Data : [
{Value : description}