**TITLE**: Adapting Texts in the Delete Dialog (Object Page Header)

**INTRODUCTION**: Configure and customize the Delete dialog text shown when deleting an entire Object Page in SAP Fiori elements (OData V2) by registering a controller extension and implementing beforeDeleteExtension in that controller. Use only the extensionAPI and, where needed, securedExecution to integrate safely with the framework.

**TAGS**: fiori-elements-framework, odata-v2, extension, object-page, extensionAPI, controller-extension, delete-dialog

**STEP**: 1 — Register controller extension in manifest.json

**DESCRIPTION**: Register your controller extension by adding it to the "sap.ui.controllerExtensions" section of manifest.json. Reference the controller class name you will implement in your app (example: "MY_APP.ext.controller.DetailsExtension").

**LANGUAGE**: JSON

**CODE**:
```json
"extends": {
   "extensions": {
      ...
      "sap.ui.controllerExtensions": {
         ...
         "sap.suite.ui.generic.template.ObjectPage.view.Details": {
            ...
            "controllerName": "MY_APP.ext.controller.DetailsExtension",
            ...
         }
      }
      ...
```

**STEP**: 2 — Place and maintain controller extension files in your app

**DESCRIPTION**: Add the controller extension file(s) referenced in the manifest to your application source tree (for example: ext/controller/DetailsExtension.js). Maintain the files alongside your other app extension resources. Ensure the controllerName in manifest.json matches the implemented controller module path and name.

**LANGUAGE**: JSON

**CODE**:
```json
// (No code change required; ensure file path and manifest.controllerName match)
```

**STEP**: 3a — Implement beforeDeleteExtension: return an object

**DESCRIPTION**: Implement beforeDeleteExtension in your controller extension to return an object with title and text properties. The object is used as the dialog title and content. This synchronous form returns the object directly.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeDeleteExtension: function() {
    var oMessageText = {
        title: "My title";
        text: "My text"
    };
    return oMessageText;
}
```

**STEP**: 3b — Implement beforeDeleteExtension: return a Promise

**DESCRIPTION**: For asynchronous determinations (e.g., fetching localized texts or data), return a Promise that resolves to the message object with title and text.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeDeleteExtension: function() {
    var oMessageText = {
        title: "My title";
        text: "My text"
    };
    return Promise.resolve(oMessageText);
}
```

**STEP**: 3c — Implement beforeDeleteExtension: use extensionAPI.securedExecution

**DESCRIPTION**: If your implementation must run inside the Fiori elements secured context (recommended when interacting with framework services or protected operations), wrap asynchronous logic with this.extensionAPI.securedExecution and resolve the message object inside the secured callback.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeDeleteExtension: function() {
    var oMessageText = {
        title: "My title";
        text: "My text"
    };
    return this.extensionAPI.securedExecution(function() {
        return new Promise(function(resolve) {
            ...
            resolve(oMessageText);
            ...
        });
    });
}
```

**NOTE**: This topic applies only to SAP Fiori elements for OData V2. Use app extensions with caution: prefer manifest settings or annotations if possible. When implementing extensions, use only the official extensionAPI of SAP Fiori elements. See "Using the extensionAPI" and "Using the SecuredExecution Method" for more details.

fiori-elements-framework odata-v2 extension object-page extensionAPI controller-extension delete-dialog


**TITLE**: Adapting Delete Dialog Texts for Nested Smart Table (Object Page) — SAP Fiori elements (OData V2)

**INTRODUCTION**: Customize the title, main text, and undeletable text shown in the Delete dialog that appears when users delete selected items from a nested Smart Table on an Object Page. Applicable only to SAP Fiori elements for OData V2. Implement a controller extension and return the dialog text either as an object, a Promise, or via extensionAPI.securedExecution.

**TAGS**: fiori-elements-framework, odata-v2, extension, controller-extension, manifest.json, delete-dialog, nested-smart-table

**STEP**: 1 — Register the controller extension in manifest.json

**DESCRIPTION**: Add a controller extension entry for the Object Page Details view in your app's manifest.json. Point the framework to your custom controller (controllerName). Keep the mapping under "extends" -> "extensions" -> "sap.ui.controllerExtensions" -> "sap.suite.ui.generic.template.ObjectPage.view.Details".

**LANGUAGE**: JSON

**CODE**:
```json
"extends": {
   "extensions": {
      ...
      "sap.ui.controllerExtensions": {
         ...
         "sap.suite.ui.generic.template.ObjectPage.view.Details": {
            ...
            "controllerName": "MY_APP.ext.controller.DetailsExtension",
            ...
         }
      }
      ...
```

**STEP**: 2 — Add and maintain controller extension files in your application

**DESCRIPTION**: Place your extension controller file(s) in your app extension folder structure. Ensure the file path and naming match the controllerName registered in manifest.json. Example app extension file tree (refer to image in your project):

- Image reference in project: images/AppExtensionTree_ObjectPage_318f52b.png

Keep the controller file (for example, MY_APP/ext/controller/DetailsExtension.js) under your app extension folder.

**LANGUAGE**: Text

**CODE**:
```text
(images/AppExtensionTree_ObjectPage_318f52b.png)
```

**STEP**: 3 — Implement beforeLineItemDeleteExtension in the controller extension

**DESCRIPTION**: Implement beforeLineItemDeleteExtension(oBeforeLineItemDeleteProperties) in your controller extension. Check oBeforeLineItemDeleteProperties.sUiElementId to identify the nested Smart Table that triggered the delete. Return one of:
- an object with keys title, text, undeletableText,
- a Promise that resolves to that object, or
- use this.extensionAPI.securedExecution to return a Promise that resolves to that object.

The property oBeforeLineItemDeleteProperties contains info about selected items and sUiElementId identifies the nested Smart Table source.

Use only the extensionAPI of SAP Fiori elements; avoid accessing internal controls, models, or framework internals. This approach is for OData V2 applications.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeLineItemDeleteExtension: function(oBeforeLineItemDeleteProperties) {
    if (oBeforeLineItemDeleteProperties.sUiElementId !== "My_APP::sap.suite.ui.generic.template.ObjectPage.view.Details::MY_EntitySet--to_NavProperty::com.sap.vocabularies.UI.v1.LineItem::Table") {
        return;
    }
    var oMessageText = {
        title: "My title",
        text: "My text",
        undeletableText: "My undeletable text"
    };
    return oMessageText;
}
```

**STEP**: 4 — Return dialog texts using a Promise

**DESCRIPTION**: If your logic requires async operations (e.g., server checks), return a Promise that resolves to the message object.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeLineItemDeleteExtension: function(oBeforeLineItemDeleteProperties) {
    if (oBeforeLineItemDeleteProperties.sUiElementId !== "My_APP::sap.suite.ui.generic.template.ObjectPage.view.Details::MY_EntitySet--to_NavProperty::com.sap.vocabularies.UI.v1.LineItem::Table") {
        return;
    }
    var oMessageText = {
        title: "My title",
        text: "My text",
        undeletableText: "My undeletable text"
    };
    return Promise.resolve(oMessageText);
}
```

**STEP**: 5 — Use extensionAPI.securedExecution for secure async execution

**DESCRIPTION**: For secure async execution integrated with the framework, wrap your Promise in this.extensionAPI.securedExecution and return it. This ensures the framework's securedExecution behavior is honored.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeLineItemDeleteExtension: function(oBeforeLineItemDeleteProperties) {
    if (oBeforeLineItemDeleteProperties.sUiElementId !== "My_APP::sap.suite.ui.generic.template.ObjectPage.view.Details::MY_EntitySet--to_NavProperty::com.sap.vocabularies.UI.v1.LineItem::Table") {
        return;
    }
    var oMessageText = {
        title: "My title",
        text: "My text",
        undeletableText: "My undeletable text"
    };
    return this.extensionAPI.securedExecution(function() {
        return new Promise(function(resolve) {
            ...
            resolve(oMessageText);
            ...
        });
    });
}
```

**STEP**: 6 — Notes and cautions

**DESCRIPTION**:
- This customization is only supported for SAP Fiori elements (OData V2).
- Use app extensions only when manifest settings or annotations cannot achieve the required behavior.
- Use only the official extensionAPI; do not access or manipulate internal controls, properties, models, or other internal objects created by the SAP Fiori elements framework.
- For more information about securedExecution, see your project's documentation on Using the SecuredExecution Method.

fiori-elements-framework odata-v2 extension controller-extension manifest.json delete-dialog nested-smart-table


**TITLE**: Adapting Delete Dialog Texts in List Report via Controller Extension

**INTRODUCTION**: Use a controller extension to customize the texts shown in the Delete confirmation dialog of a SAP Fiori elements List Report (OData V2). You can provide static values, asynchronous values (Promise), or run secure logic via extensionAPI.securedExecution. This approach is only for OData V2 List Report and should use only the official extensionAPI.

**TAGS**: fiori-elements-framework, odata-v2, extensions, list-report, delete-dialog, extensionAPI, securedExecution

**STEP**: 1 — Register the controller extension in manifest.json

**DESCRIPTION**: Add a controller extension entry for the List Report in your app's manifest.json. Replace controllerName with your extension controller full name (for example, "MY_APP.ext.controller.ListReportExtension"). This registration tells the Fiori elements framework to load your extension controller for the List Report view.

**LANGUAGE**: JSON

**CODE**:
```json
"extends": {
    "extensions": {
        ...
         "sap.ui.controllerExtensions": {
            ...
            "sap.suite.ui.generic.template.ListReport.view.ListReport": {
                ...
                "controllerName": "MY_APP.ext.controller.ListReportExtension",
                ...
            }
        }
        ...
```

**STEP**: 2 — Place and maintain the controller extension file in your app

**DESCRIPTION**: Create the controller file at the path matching the controllerName used in the manifest (for example, src/ext/controller/ListReportExtension.controller.js or corresponding namespace MY_APP/ext/controller/ListReportExtension). Maintain your extension file in the application source tree. The framework will load this controller when rendering the List Report. (Reference image: images/AppExtension_Tree_List_Report_cc8015b.png)

**LANGUAGE**: —

**CODE**:
```text
// Place your extension controller at the namespace/path used in manifest
// Example path: MY_APP/ext/controller/ListReportExtension.controller.js
```

**STEP**: 3 — Implement beforeDeleteExtension to adapt dialog texts (synchronous object)

**DESCRIPTION**: Implement the beforeDeleteExtension hook in your controller extension. Return an object with any of these properties to override texts in the Delete dialog: title, text, unsavedChanges, undeletableText. This synchronous variant returns the object directly.

- Note: oBeforeDeleteProperties contains information about the selected items for deletion.
- Use only extensionAPI functions when interacting with the framework.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeDeleteExtension: function(oBeforeDeleteProperties) {
    var oMessageText = {
        title: "My title";
        text: "My text",
        unsavedChanges: "My unsaved changes",
        undeletableText: "My undeletable text"
    };
    return oMessageText;
}
```

**STEP**: 4 — Implement beforeDeleteExtension to adapt dialog texts (returning a Promise)

**DESCRIPTION**: If your logic requires asynchronous processing (for example, fetching translations or computing values), return a Promise that resolves to the message object with keys: title, text, unsavedChanges, undeletableText.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeDeleteExtension: function(oBeforeDeleteProperties) {
    var oMessageText = {
        title: "My title";
        text: "My text",
        unsavedChanges: "My unsaved changes",
        undeletableText: "My undeletable text"
    };
    return Promise.resolve(oMessageText);
}
```

**STEP**: 5 — Implement beforeDeleteExtension using extensionAPI.securedExecution

**DESCRIPTION**: For secure execution within the extensionAPI context (recommended for operations that must respect the framework's secured execution model), use this.extensionAPI.securedExecution and return a Promise that resolves to the message object.

For more details, see Using the SecuredExecution Method (using-the-securedexecution-method-6a39150.md).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
beforeDeleteExtension: function(oBeforeDeleteProperties) {
    var oMessageText = {
        title: "My title";
        text: "My text",
        unsavedChanges: "My unsaved changes",
        undeletableText: "My undeletable text"
    };
    return this.extensionAPI.securedExecution(function() {
        return new Promise(function(resolve) {
            ...
            resolve(oMessageText);
            ...
        });
    });
}
```

**STEP**: 6 — Behavior details and unsaved changes display conditions

**DESCRIPTION**: The Delete dialog shows Title, Text, and (if applicable) Unsaved Changes. The "Unsaved Changes" text appears only when any selected items meet one of the following conditions:
- Selected items having editing status unsavedChanges.
- Selected items having editing status unsavedChanges and locked.
- Selected items having editing status unsavedChanges and cannot be deleted using deletablePath.
- Selected items having editing status unsavedChanges, locked, and cannot be deleted using deletablePath.
- Selected items having editing status unsavedChanges and cannot be deleted using deletablePath.

Use app extensions only if manifest settings or annotations cannot achieve the required behavior. After adding an extension, controls, properties, models, and busy handling inside the extension are the app's responsibility. Do not access or manipulate internal framework objects—use only the public extensionAPI.

**LANGUAGE**: —

**CODE**:
```text
// Keys you can return from beforeDeleteExtension:
{
  title: "string",            // dialog title
  text: "string",             // dialog main text
  unsavedChanges: "string",   // text shown when selected items have unsaved changes
  undeletableText: "string"   // text shown for undeletable items
}

// Note: oBeforeDeleteProperties parameter contains info about selected items.
```

fiori-elements-framework odata-v2 extensions list-report delete-dialog extensionAPI securedExecution


**TITLE**: Adapting the Filter Bar (SAP Fiori Elements — V2 & V4)

**INTRODUCTION**: Practical, code-focused instructions for adapting the Fiori Elements filter bar: include navigation properties, control case sensitivity, add a Clear button, and move filter fields to the Adapt Filters dialog. Contains manifest.json and annotation code snippets to copy/paste and integrate.

**TAGS**: fiori-elements, filter-bar, manifest.json, ODataV2, ODataV4, navigationProperties, FilterFunctions, showClearButton, SelectionFields

**STEP**: 1 — Include Navigation Properties (OData V2)

**DESCRIPTION**: For SAPUI5 >= 1.126.0 the Adapt Filters dialog only lists properties from the main entity set by default. To include properties from navigation entities, add a navigationProperties array under filterSettings in the list report section of manifest.json. Each entry is a navigation path relative to the main entity; you can list a single property (e.g., to_Supplier/EmailAddress) or a navigation property (e.g., to_DeliveryStatus) to include all its simple properties (excluding ones annotated Hidden or HiddenFilter).

**LANGUAGE**: JSON

**CODE**:
```json
"ListReport|C_STTA_SalesOrder_WD_20": {
    "entitySet": "C_STTA_SalesOrder_WD_20",
    "component": {
        "name": "sap.suite.ui.generic.template.ListReport",
        "list": true,
        "settings": {
            "tableSettings": {
…
            },

            "filterSettings": {
                "navigationProperties": [
                    "to_Supplier/EmailAddress ",
                    "to_DeliveryStatus"
                ]
            }
        }
```

**STEP**: 2 — Include Navigation Properties (OData V4)

**DESCRIPTION**: In OData V4 the filter bar shows fields from @com.sap.vocabularies.UI.v1.SelectionFields. To add navigation properties only for the Adapt Filters dialog, configure navigationProperties inside the controlConfiguration selection fields in manifest.json. The array accepts navigation paths relative to the current entity type. If a path ends at a navigation or complex property, all of its simple properties are added; if the path points to a simple property, only that single property is added. Note: only one-level navigation is supported (no nested navigation).

**LANGUAGE**: JSON

**CODE**:
```json
"ListReport": {
    ...
    "options": {
        "settings": {
            ...
            "controlConfiguration": {
                ...
                "@com.sap.vocabularies.UI.v1.SelectionFields": {
                    "navigationProperties":  [ "_DistributionChannel", "_Partner/FullName" ],
                    ...
                }
            },
            ...
        }
    }
},
```

**STEP**: 3 — Behavior Notes for Navigation Properties and 1:n Associations

**DESCRIPTION**: When filtering on a field from a 1:n navigation entity:
- The list report fetches main records that have at least one related record matching the filter.
- When opening the object page for a selected main record, the object page shows all related records from the 1:n association (not just the related records that matched the original filter).

**LANGUAGE**: Text

**CODE**:
```text
- Navigation properties are added only one level deep. Nested navigation properties aren't supported.
- 1:n filter behavior: main records with at least one matching related record are returned;
  selecting a main record shows all its related records on the object page.
```

**STEP**: 4 — Control Case Sensitivity via FilterFunctions Annotation (OData V4)

**DESCRIPTION**: Case sensitivity of filter comparisons depends on back end and what filter functions the OData service declares. To make the Fiori client treat filtering as case-insensitive, include the tolower function in the Org.OData.Capabilities.V1.FilterFunctions annotation in the EntityContainer. SAP Fiori elements checks for the presence of "tolower" and sets caseSensitive as follows:
- tolower exists => caseSensitive = false (client expects back end to normalize values to lowercase)
- tolower does not exist => caseSensitive = true (back end decides default)
- No annotation configured => caseSensitive = false (client expects back end to normalize)

This logic applies to: Filter bar, Table personalization filters, Filters created from semantic keys, Value help dialogs.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotations Target="namespace.EntityContainer">
    <Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
      <Collection>
        ....
        <String>tolower</String>
        ...
      </Collection>
    </Annotation>
</Annotations>
```

**STEP**: 5 — Add a Clear Button to the Filter Bar

**DESCRIPTION**: Enable a Clear button in the list report filter bar by setting showClearButton: true in the manifest.json controlConfiguration selection fields. The Clear button clears all filter values (not restoring default values) and resets Editing Status filters to "All". To execute additional custom clear actions, implement the controller extension onAfterClear.

**LANGUAGE**: JSON

**CODE**:
```json
"SalesOrderManageList": {
    "options": {
        "settings": {
            "controlConfiguration": {
                "@com.sap.vocabularies.UI.v1.SelectionFields": {
                    "showClearButton": true,
                }
            }
        }
    }
}
```

**LANGUAGE**: JavaScript

**CODE**:
```javascript
onAfterClear: function (oEvent) {
  var oView = this.getView();
  oView.byId("CustomSegmentedButton").setSelectedKey("none");
}
```

**STEP**: 6 — Move Explicit Filter Fields to the Adapt Filters Dialog (OData V4)

**DESCRIPTION**: To move an explicitly included filter field from the filter bar to the Adapt Filters dialog, set availability: "Adaptation" for the field under @com.sap.vocabularies.UI.v1.SelectionFields -> filterFields in controlConfiguration of manifest.json. See V4-specific docs for additional availability values.

**LANGUAGE**: JSON

**CODE**:
```json
"SalesOrderManageList": {
    "options": {
        "settings": {
            "controlConfiguration": {
                "@com.sap.vocabularies.UI.v1.SelectionFields": {
                    "filterFields": {
                        "postingDate": {
                            "availability": "Adaptation"
                        }
                    }
                }
            }
        }
    }
}
```

**STEP**: 7 — References and Related Controls

**DESCRIPTION**: Use these references while implementing:
- Smart Filter Bar control docs to understand API and lifecycle: sap.ui.comp.smartfilterbar.SmartFilterBar
- Related guides: enabling search, enabling semantic operators, adding custom fields to filter bar

**LANGUAGE**: Text

**CODE**:
```text
Related documentation:
- Smart Filter Bar: ../10_More_About_Controls/smart-filter-bar-7bcdffc.md
- Enabling the Search Function: enabling-the-search-function-3cdebee.md
- Enabling Semantic Operators in the Filter Bar: enabling-semantic-operators-in-the-filter-bar-fef65d0.md
- Adding Custom Fields to the Filter Bar (V4): adding-custom-fields-to-the-filter-bar-5fb9f57.md
```

fiori-elements filter-bar manifest.json ODataV2 ODataV4 navigationProperties FilterFunctions showClearButton SelectionFields


**TITLE**: Adapting the UI — Developer and Key User Configuration for SAP Fiori Elements (OData V2 & V4)

**INTRODUCTION**: Practical, code-focused guidance for enabling and configuring UI adaptation in SAP Fiori Elements apps. Includes conceptual manifest.json examples for common key-user and developer settings (list report, object page, filter bar, tables), plus operational notes to use while implementing adaptation projects or enabling runtime key-user adaptation.

**TAGS**: fiori-elements, sapui5, manifest.json, key-user-adaptation, odata-v2, odata-v4, variant-management, filter-bar, tables, personalization

**STEP**: 1 — Decide adaptation approach

**DESCRIPTION**: Choose whether UI changes are performed at design time by an application developer (Adaptation Project) or at runtime by a key user (Key User Adaptation). Developer changes are applied in the project files; key-user changes are applied to the app's manifest/settings and may override end-user personalizations.

- Developer adaptation: implement changes in the app sources or via an Adaptation Project.
- Key user adaptation: enable runtime adaptation in the app; key users use the User Menu > Adapt UI.

**LANGUAGE**: text

**CODE**:
```text
Actions:
- For design-time changes: modify app sources or create an Adaptation Project (SAP Fiori tools).
- For runtime adaptation: ensure the app is enabled for key-user adaptation (manifest + flexibility enabled).
- Note: Key-user changes can override end-user personalizations; communicate this to stakeholders.
```

**STEP**: 2 — Conceptual manifest.json structure (centralized example)

**DESCRIPTION**: Use a manifest.json "settings" section to hold the adaptation-related configuration. The following conceptual JSON demonstrates the exact property names referenced in the documentation (variantManagement, initialLoad, useSemanticDateRange, scrollThreshold, threshold, enableExport, personalization, selectionMode, etc.). This example is a canonical, implementation-oriented reference: copy the keys you need into your app's manifest.json in the appropriate section (for example under sap.ui.generic.app or template-specific configuration). Adjust locations according to your Fiori elements version and tooling.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui.generic.app": {
    "settings": {
      "listReport": {
        "variantManagement": "Page",        // values: "Page" | "Control" | "None" (V4 also supports "None")
        "initialLoad": "Auto",             // values: "Auto" | "Enabled" | "Disabled"
        "hideVariantManagement": false
      },
      "filterBar": {
        "displayClearButton": true,        // V4: Clear button
        "displayGoButton": false,          // V2: visual filter bar Go button (ALP only)
        "useSemanticDateRange": true       // V4: enable semantic date-range options in manifest.json
      },
      "objectPage": {
        "editableHeaderContent": true,
        "tableVariantManagement": true,
        "chartVariantManagement": true,
        "showRelatedApps": true
      },
      "table": {
        "selectionMode": "Multi",          // values: "Single" | "Multi"
        "createMode": "Inline",            // values: "New Page" | "Inline" | "Inline Creation Rows" | etc.
        "condensed": true,                 // condensed table layout (not for responsive tables)
        "widthIncludingColumnHeader": true,
        "enableSelectAll": true,
        "selectionLimit": 100,             // maximum selectable rows (not for responsive tables)
        "scrollThreshold": 20,             // additional records to load when scrolling (not for responsive)
        "threshold": 50,                   // initial load record count
        "enableExport": true,              // V4: show Export button
        "frozenColumnCount": 1,            // V4: columns always visible when scrolling horizontally
        "rowCount": 20,                    // V4: number of rows to display (object page; not responsive)
        "enableAddCardToInsights": false,  // list report only (S/4HANA My Home card feature)
        "personalization": {
          "enabled": true,                 // enable table personalization
          "ownSettings": [ "Sorting", "Columns", "Filtering", "Grouping" ]
        }
      }
    }
  }
}
```

**STEP**: 3 — Table personalization and selection controls

**DESCRIPTION**: Configure table behavior and personalization keys referenced above. Use "personalization" to selectively enable sorting, columns, filtering, and grouping. Enforce selection policy with selectionMode, selectionLimit, and enableSelectAll. Tune data-loading performance with scrollThreshold and threshold.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui.generic.app": {
    "settings": {
      "table": {
        "selectionMode": "Multi",
        "enableSelectAll": true,
        "selectionLimit": 200,
        "scrollThreshold": 25,
        "threshold": 100,
        "personalization": {
          "enabled": true,
          "ownSettings": [ "Sorting", "Columns", "Filtering" ]
        },
        "enableExport": true,
        "frozenColumnCount": 2
      }
    }
  }
}
```

**STEP**: 4 — Filter bar configuration (semantic dates, clear/go buttons)

**DESCRIPTION**: Enable or disable semantic date ranges and the Clear/Go buttons used in filter bars and Visual Filter Bars (ALP). Use the settings keys exactly as shown to ensure the runtime key-user adapter and templates read them.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui.generic.app": {
    "settings": {
      "filterBar": {
        "useSemanticDateRange": true,      // V4: applies semantic operators / date ranges
        "displayClearButton": true,        // V4: Clear button visible
        "displayGoButton": false           // V2 ALP only: Go button in visual filter bar
      }
    }
  }
}
```

**STEP**: 5 — Object Page header and variants

**DESCRIPTION**: Control header editability and enable variant management for tables and charts on the object page. Variant management settings can be overridden by key-user changes and can be made public for delivery to roles.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui.generic.app": {
    "settings": {
      "objectPage": {
        "editableHeaderContent": true,
        "tableVariantManagement": true,
        "chartVariantManagement": true,
        "showRelatedApps": true
      }
    }
  }
}
```

**STEP**: 6 — Key user variant behavior and operational notes

**DESCRIPTION**: Important operational behavior to consider when enabling key-user adaptation:

- Key users can create, rename, modify, and deliver public variants to all users or specific roles (page variants for list pages, table variants for list report & object pages).
- Entering adaptation mode starts the app with a fresh runtime state; applied changes are not preserved in the internal runtime state. Exiting adaptation mode restores the app to the previous state until the new version is activated.
- Settings made by key users can override end-user personalizations; end users may need to reapply their settings.
- Recommendation: Do not embed iFrames in SAP Fiori Elements for OData V2 apps when using UI adaptation.

**LANGUAGE**: text

**CODE**:
```text
Operational notes:
- Public variants: key users can create and deliver public variants to roles.
- Runtime adaptation behavior: entering adaptation mode resets the app to a fresh state; exiting reverts to the previous runtime state until activation.
- Overrides: key-user settings override end-user personalization.
- V2 note: avoid embedding iFrames in apps that rely on UI adaptation.
```

**STEP**: 7 — Version-specific guidance and references

**DESCRIPTION**: Use the following references and actions depending on your Fiori elements OData version:

- OData V2:
  - Review "Adapting the UI: List Report and Object Page" and "Adapting the UI: Analytical List Page".
  - For enabling key-user adaptation developer support, read "SAPUI5 Flexibility: Enable Your App for UI Adaptation".
- OData V4:
  - For adaptation project creation: use SAP Fiori tools Create Adaptation Project (S/4HANA Cloud Public).
  - For on-premise: use Fiori tools "Creating a Project".
  - Refer to "Enabling an App for Key User Adaptation" and SAPUI5 flexibility documentation.

Preserve image references and documentation links in your implementation notes.

**LANGUAGE**: text

**CODE**:
```text
References & files:
- manifest.json: update settings under appropriate template-specific node (sap.ui.generic.app or equivalent).
- Images referenced in docs:
  - images/Key_Users_Manage_Views1_9ff91e8.png
  - images/Key_Users_Manage_Views_2_f31343c.png

Useful documentation links (place in implementation notes):
- SAPUI5 Flexibility: Adapting UIs Made Easy
- SAPUI5 Flexibility: Enable Your App for UI Adaptation
- Create the Adaptation Project (SAP Fiori tools)
- Creating a Project (SAP Fiori tools)
- Adapting the Filter Bar, Variant Management, Tables, Object Page topics
```


**TITLE**: Adapting the UI: Analytical List Page (SAP Fiori elements, OData V2)

**INTRODUCTION**: This document collects actionable UI Adaptation settings for the Analytical List Page (ALP) in SAP Fiori elements (OData V2). Use these configuration snippets with SAP Fiori tools (Business Application Studio or VS Code extensions) to programmatically hide/show controls, set chart/table behaviors, and tune columns, chart types, and visual filter dialog controls. Apply only for the use cases described here to avoid unsupported control replacements.

**TAGS**: fiori-elements-framework, analytical-list-page, ui-adaptation, odata-v2, smart-chart, smart-table, visual-filters

**STEP**: 1 — Template-level UI settings (header, filter bar, variants, general visibility)

**DESCRIPTION**: Configure ALP template-level properties to collapse/expand the smart filter bar, freeze it on scroll, enable variant-management options, and control visibility of share, clear, table toolbar and page footer. Use these keys in the UI Adaptation layer (JSON configuration or UI Editor) for the ALP template.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "template": {
    "headerExpanded": false,                        // collapse and hide the smart filter bar when false
    "preserveHeaderStateonScroll": true,            // freeze filter bar on scroll when true
    "pageVariants": {
      "showSetAsDefault": true,                     // enable "Set as Default" per-user variant
      "showShare": true                             // enable visibility/sharing of variants
    },
    "shareIcon": {
      "visible": true
    },
    "clearButton": {
      "visibleOnSmartFilterBar": true,              // visible on the smart filter bar (when Go button enabled)
      "visibleOnHeaderBar": false                   // visible in header area (when Go button disabled)
    },
    "tableToolbar": {
      "visible": true
    },
    "pageFooter": {
      "visible": false
    }
  }
}
```

**STEP**: 2 — Chart configuration (smart chart top-level properties)

**DESCRIPTION**: Configure smart chart behavior and allowed chart types. Use `ignoredChartTypes` as a comma-separated string of chart type codes to hide them from the chart type selector. Control selection mode, tooltips and buttons for chart type selection, download and legend.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "smartChart": {
    "ignoredChartTypes": "pie,donut,scatter",      // comma-separated chart type codes to hide
    "selectionMode": "single",                     // "single", "multiple", or "none"
    "showChartTooltip": true,
    "showChartTypeSelectionButton": true,
    "showDownloadButton": false,
    "showLegendButton": true,
    "noData": "No chart data available"            // override default "no data" text
  }
}
```

**STEP**: 3 — List of available chart type codes (use in ignoredChartTypes)

**DESCRIPTION**: Map of human-readable chart types to the exact codes used by `ignoredChartTypes`. Use these codes in comma-separated lists.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "chartTypeCodes": {
    "Bar Chart": "bar",
    "Column Chart": "column",
    "Line Chart": "line",
    "Combined Column Line Chart": "combination",
    "Pie Chart": "pie",
    "Doughnut Chart": "donut",
    "Scatter Plot": "scatter",
    "Bubble Chart": "bubble",
    "Heat Map": "heatmap",
    "Bullet Chart": "bullet",
    "Vertical Bullet Chart": "vertical_bullet",
    "Stacked Bar Chart": "stacked_bar",
    "Stacked Column Chart": "stacked_column",
    "Combined Stacked Line Chart": "stacked_combination",
    "Horizontal Combined Stacked Line Chart": "horizontal_stacked_combination",
    "Bar Chart with 2 X-Axes": "dual_bar",
    "Column Chart with 2 Y-Axes": "dual_column",
    "Line Chart with 2 Y-Axes": "dual_line",
    "Stacked Bar Chart with 2 X-Axes": "dual_stacked_bar",
    "Stacked Column Chart with 2 Y-Axes": "dual_stacked_column",
    "Combined Column Line Chart with 2 Y-Axes": "dual_combination",
    "Combined Bar Line Chart with 2 X-Axes": "dual_stacked_combination",
    "Combined Stacked Line Chart with 2 Y-Axes": "dual_horizontal_combination",
    "Horizontal Combined Stacked Line Chart with 2 X-Axes": "dual_horizontal_stacked_combination",
    "100% Stacked Bar Chart": "100_stacked_bar",
    "100% Stacked Column Chart": "100_stacked_column",
    "100% Stacked Bar Chart with 2 X-Axes": "100_dual_stacked_bar",
    "100% Stacked Column Chart with 2 Y-Axes": "100_dual_stacked_column",
    "Waterfall Chart": "waterfall",
    "Horizontal Waterfall Chart": "horizontal_waterfall"
  }
}
```

**STEP**: 4 — Chart toolbar settings (personalization and drill-down)

**DESCRIPTION**: Toggle chart toolbar controls: settings (personalization) button visibility and drill-down button visibility/text. The UI adaptation key names should match the property labels used by the editor (example provided).

**LANGUAGE**: JSON

**CODE**:
```json
{
  "chartToolbar": {
    "personalisationButton": {
      "visible": true
    },
    "drillDownButton": {
      "visible": true,
      "textKey": "C_ContrItemMonitoringResults--chart-btnDrillDownText"
    }
  }
}
```

**STEP**: 5 — Table-level settings (noData, personalization, export, scrolling, selection)

**DESCRIPTION**: Configure table UI behavior: override no-data text, show/hide personalization settings icon, turn on/off Export to Excel, tune dynamic loading (scrollThreshold), and control whether responsive table row selections persist (`rememberSelections`).

**LANGUAGE**: JSON

**CODE**:
```json
{
  "smartTable": {
    "C_ContrItemMonitoringResults--table-nodata": "No table data available", // override no-data text
    "personalization": {
      "visible": true    // show/hide the Settings icon for table personalization
    },
    "enableExport": false, // set to false to hide Export to Excel button
    "showRowCount": true,
    "scrollThreshold": 500, // default 300; increase/decrease to change dynamically loaded records while scrolling
    "rememberSelections": false // default false; set true to persist row selections across refreshes
  }
}
```

**STEP**: 6 — Table column properties (per-column tuning)

**DESCRIPTION**: Each smart table column exposes properties you can adjust in UI Adaptation: visibility, width, auto-resize behavior, inclusion in query (`inResult`), resizable, personalization sort entry, sort order, sorted indicator, and summed. Apply per-column configuration objects.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "columns": [
    {
      "id": "Column_Product",
      "property": "Product",
      "visible": true,
      "width": "200px",
      "autoResizable": false,
      "inResult": true,
      "resizable": true,
      "showSortMenuEntry": true,
      "sortOrder": "Ascending",   // or "Descending"
      "sorted": false,
      "summed": false
    },
    {
      "id": "Column_Quantity",
      "property": "Quantity",
      "visible": true,
      "width": "100px",
      "autoResizable": true,
      "inResult": true,
      "resizable": true,
      "showSortMenuEntry": true,
      "sortOrder": "Descending",
      "sorted": true,
      "summed": true
    }
  ]
}
```

**STEP**: 7 — Visual Filters Dialog: button and micro-chart properties

**DESCRIPTION**: Configure each button or micro chart in the Adapt Filters (Visual Filter) dialog. Common properties: visibility, width, icon and activeIcon sources, displayed text, busy/enabled/blocked states.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "visualFilterDialog": {
    "buttons": [
      {
        "id": "VF_Status",
        "text": "Status",
        "visible": true,
        "width": "150px",
        "icon": "sap-icon://filter",
        "activeIcon": "sap-icon://accept",
        "busy": false,
        "enabled": true,
        "blocked": false
      },
      {
        "id": "VF_Category",
        "text": "Category",
        "visible": true,
        "width": "180px",
        "icon": "sap-icon://category",
        "activeIcon": "sap-icon://category2",
        "busy": false,
        "enabled": true,
        "blocked": false
      }
    ],
    "microCharts": [
      {
        "id": "VF_Sparkline",
        "visible": true,
        "width": "120px"
      }
    ]
  }
}
```

fiori-elements-framework analytical-list-page ui-adaptation odata-v2 smart-chart smart-table visual-filters


**TITLE**: UI Adaptations for Fiori Elements List Report and Object Page (OData V2)

**INTRODUCTION**: Practical, code-focused reference for adapting UI behavior and control properties in Fiori elements List Report and Object Page (OData V2). Use these snippets in XML fragments or UI5 views (or via Page Editor where supported). Notes mention Page Editor limitations and defaults to preserve compatibility.

**TAGS**: fiori-elements, ui5, list-report, object-page, manifest, fragment, table, dynamicpage, smartfilterbar, binding

STEP: List Report — Enable/Disable "Export to Excel" button
DESCRIPTION: Toggle the Export to Excel button on a table toolbar. Can be set on the table node in the Page Editor or in an XML fragment for custom configuration.
LANGUAGE: XML
CODE:
```xml
<!-- Set to true to show Export to Excel, false to hide -->
<Table id="listReportTable" enableExport="true">
  <!-- table columns / items -->
</Table>
```

STEP: List Report — Column width and horizontal alignment (custom columns)
DESCRIPTION: Change column width or center-align status columns. Page Editor can change Width/hAlign for standard columns. For custom columns, define these properties directly in the fragment (Page Editor does not support custom column width/hAlign).
LANGUAGE: XML
CODE:
```xml
<!-- Example column in an XML fragment (use for custom columns) -->
<Column id="colStatus" width="120px" hAlign="Center">
  <Text text="{Status}"/>
</Column>
```

STEP: List Report — DynamicPage fitContent (prevent tables from occupying full container)
DESCRIPTION: For analytical, grid, and tree tables the default is fitContent="true". Set it to false to allow the container to show free space (Page Editor setting or fragment).
LANGUAGE: XML
CODE:
```xml
<!-- Prevent full-height fitting for the dynamic page -->
<DynamicPage id="listReportDynamicPage" fitContent="false">
  <!-- header / content -->
</DynamicPage>
```

STEP: List Report — Change popinLayout for many columns
DESCRIPTION: Use one of the supported popinLayout values to improve readability when many columns are present.
LANGUAGE: XML
CODE:
```xml
<!-- Options: Block (default), GridSmall, GridLarge -->
<Table id="listReportTable" popinLayout="GridSmall">
  <!-- content -->
</Table>
```

STEP: List Report — scrollThreshold for grid/analytical/tree tables
DESCRIPTION: Change scrollThreshold to control when additional data loads during scrolling. Default is 300.
LANGUAGE: XML
CODE:
```xml
<!-- Increase or decrease from default (300) -->
<Table id="gridTable" scrollThreshold="500">
  <!-- content -->
</Table>
```

STEP: List Report — SmartFilterBar liveMode
DESCRIPTION: Enable or disable live mode in the SmartFilterBar so filters apply automatically as changed.
LANGUAGE: XML
CODE:
```xml
<!-- liveMode true for immediate filtering, false for manual apply -->
<SmartFilterBar id="smartFilterBar" liveMode="true">
  <!-- filter items -->
</SmartFilterBar>
```

STEP: List Report — rememberSelections for responsive tables
DESCRIPTION: Controls whether row selection persists after data refresh/update. Default is false.
LANGUAGE: XML
CODE:
```xml
<!-- Set to true to persist selections across refreshes -->
<Table id="responsiveTable" rememberSelections="true" type="ResponsiveTable">
  <!-- content -->
</Table>
```

STEP: Object Page — Avatar shape in dynamic header
DESCRIPTION: Change the object page dynamic header avatar shape to circle.
LANGUAGE: XML
CODE:
```xml
<!-- ObjectPageHeader displayShape: Square (default) or Circle -->
<ObjectPageHeader id="objectHeader" displayShape="Circle">
  <!-- title, attributes, actions -->
</ObjectPageHeader>
```

STEP: Object Page — Hide anchor bar
DESCRIPTION: Remove the anchor bar/navigation bar from the Object Page layout.
LANGUAGE: XML
CODE:
```xml
<!-- Hide anchor bar -->
<ObjectPageLayout id="objectLayout" showAnchorBar="false">
  <!-- sections / subsections -->
</ObjectPageLayout>
```

STEP: Object Page — Use icon tab bar (switch to tabs)
DESCRIPTION: Render sections as icon tab bar instead of anchor bar.
LANGUAGE: XML
CODE:
```xml
<!-- Switch to tab layout -->
<ObjectPageLayout id="objectLayout" useIconTabBar="true">
  <!-- sections / subsections -->
</ObjectPageLayout>
```

STEP: Object Page — Enable Export to Excel in object page tables
DESCRIPTION: Show the Export to Excel button for object page tables by enabling the property on the table node.
LANGUAGE: XML
CODE:
```xml
<!-- Enable Export on object page table -->
<Table id="objectPageTable" enableExport="true">
  <!-- table content -->
</Table>
```

STEP: Object Page — Show header content in edit mode (static or bound)
DESCRIPTION: Control header content visibility in edit mode. Can be static true/false or a binding/expression. See "Creating a Binding Change" for binding examples.
LANGUAGE: XML
CODE:
```xml
<!-- Static -->
<ObjectPageLayout id="objectLayout" showHeaderContent="true">
  <!-- header content -->
</ObjectPageLayout>

<!-- Binding example (use when value depends on model/expression) -->
<ObjectPageLayout id="objectLayout" showHeaderContent="{= ${ui>/editable} }">
  <!-- header content -->
</ObjectPageLayout>
```

STEP: Object Page — Prevent header collapse when scrolling (always show header)
DESCRIPTION: Keep header visible while scrolling by setting alwaysShowContentHeader to true. Note: on small-screen devices (tablet/phone) header still collapses automatically.
LANGUAGE: XML
CODE:
```xml
<!-- Keep header expanded while scrolling on larger screens -->
<ObjectPageLayout id="objectLayout" alwaysShowContentHeader="true">
  <!-- content -->
</ObjectPageLayout>
```

STEP: Object Page — Table growingThreshold (sap.m.Table)
DESCRIPTION: Change growingThreshold for sap.m.Table. Default is 10. Exception: single section + single subsection with one table defaults to 20 and cannot be changed.
LANGUAGE: XML
CODE:
```xml
<!-- Change growingThreshold (default 10) -->
<Table id="objectMTable" growingThreshold="15">
  <!-- items -->
</Table>
```

STEP: Object Page — Make inner tables non-editable and set navigation mode
DESCRIPTION: By default object page tables become editable when the page is in edit mode. Set editable="false" on the outer table to force non-editable mode and ensure the inner table navigationMode is Navigation so keyboard navigation works across focusable content.
LANGUAGE: XML
CODE:
```xml
<!-- Outer table set to not editable -->
<Table id="outerObjectTable" editable="false">
  <!-- The inner table (framework renders an inner sap.m.Table or similar) -->
  <core:FragmentFragmentName> <!-- placeholder to indicate inner table -->
    <Table id="innerTable" navigationMode="Navigation">
      <!-- columns / items -->
    </Table>
  </core:FragmentFragmentName>
</Table>
```

STEP: Object Page — includeItemInSelection for tables
DESCRIPTION: Set includeItemInSelection to true so selections remain shown when navigating away from the table.
LANGUAGE: XML
CODE:
```xml
<!-- Show item selection even after moving focus away -->
<Table id="objectTable" includeItemInSelection="true">
  <!-- content -->
</Table>
```

STEP: Object Page — "Save and Edit" action visibility binding in Footer
DESCRIPTION: In non-draft apps, enable the Save and Edit action and bind its visibility so it is visible only when the page is editable (example uses ui model path).
LANGUAGE: XML
CODE:
```xml
<!-- Footer action bound to ui>/editable -->
<Button id="saveAndEdit" text="Save and Edit" visible="{ui>/editable}" press="onSaveAndEdit"/>
```

STEP: Object Report & List Report — table popinLayout, threshold, and scrollThreshold defaults
DESCRIPTION: Configure table popinLayout for readability and thresholds for initial loading and scrolling. Default scrollThreshold is 300. For threshold defaults across table types and guidance see the tables reference (tables-c0f6592.md).
LANGUAGE: XML
CODE:
```xml
<!-- Examples -->
<Table id="tableExample" popinLayout="GridLarge" threshold="50" scrollThreshold="300">
  <!-- content -->
</Table>
```

STEP: General — rememberSelections default reminder
DESCRIPTION: rememberSelections defaults to false for responsive tables; explicitly set to true to persist selections across data updates/refreshes.
LANGUAGE: XML
CODE:
```xml
<!-- Persist selection across refreshes -->
<Table id="anyResponsiveTable" rememberSelections="true">
  <!-- content -->
</Table>
```

Related links / files referenced:
- Creating a Binding Change: creating-a-binding-change-4754094.md
- Tables threshold reference: tables-c0f6592.md
- SAP Fiori Tools Page Editor documentation: https://help.sap.com/docs/SAP_FIORI_tools/17d50220bcd848aa854c9c182d65b699/047507c86afa4e96bb3d284adb9f4726.html

Notes preserved:
- Use Page Editor where supported; Page Editor displays properties with spaces for readability but actual property names are used in code (e.g., enableExport, fitContent, popinLayout).
- Custom column width and hAlign must be defined in fragments (Page Editor cannot change custom columns).
- Small-screen devices auto-collapse header despite alwaysShowContentHeader on larger screens.
- Default values: scrollThreshold = 300; sap.m.Table growingThreshold = 10 (special-case single-section single-subsection = 20, immutable); rememberSelections default = false.

fiori-elements ui5 list-report object-page manifest fragment table dynamicpage smartfilterbar binding


**TITLE**: Adapting Transient Messages from the Back End (SAP Fiori elements — OData V2)

**INTRODUCTION**: Use the adaptTransientMessageExtension extension point to inspect and adapt transient messages (from the back end) before they are displayed in List Report, Object Page, or Analytical List Page. Applicable only for SAP Fiori elements for OData V2. Use app extensions sparingly and only via the official extensionAPI; do not manipulate internal controls, models, or binding structures directly.

**TAGS**: fiori-elements-framework, OData V2, extension, transient-messages, ListReport, ObjectPage, AnalyticalListPage, manifest.json, controller-extension, Messaging

**STEP**: 1 — Register controller extension in manifest.json

**DESCRIPTION**: Register your controller extension in the app manifest under "extends" → "extensions" → "sap.ui.controllerExtensions". Add a controller entry for the relevant view (ListReport, ObjectPage, or AnalyticalListPage). Keep other manifest entries as-is; the example below shows registering a ListReport controller extension. Replace controllerName with your extension controller path.

**LANGUAGE**: JSON

**CODE**:
```json
"extends": {
   "extensions": {
      ...
      "sap.ui.controllerExtensions": {
         ...
         "sap.suite.ui.generic.template.ListReport.view.ListReport": {
            ...
            "controllerName": "STTA_MP.ext.controller.ListReportExtension",
            ...
         }
      }
      ...
```

**STEP**: 2 — Implement adaptTransientMessageExtension in the controller extension

**DESCRIPTION**: Implement the adaptTransientMessageExtension function inside your controller extension (ListReport, ObjectPage, or AnalyticalListPage). This function is invoked before a transient message is displayed. Import the required modules: sap/ui/core/Messaging, sap/ui/core/message/Message, sap/ui/core/MessageType. Inside the function you can add or modify transient messages via the Messaging API (Messaging.getMessageModel(), Messaging.addMessages()). Do not change the target of existing messages and do not modify state messages from Messaging.getMessageManager().getMessageModel().

Ensure the message model has been adapted for each page type you support. In Flexible Column Layout (FCL) the extension points for list report, object page, and analytical list page are all invoked.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
    // "Messaging" required from module "sap/ui/core/Messaging"
    // "Message" required from module "sap/ui/core/message/Message"
    // "MessageType" required from module "sap/ui/core/MessageType"
    adaptTransientMessageExtension:function() {
            if (Messaging.getMessageModel().oData.length) {
                    var msgText = "This message has been added through List Extension" ;
                    var consolidatedMessage = new Message({
                        message: msgText,
                        type: MessageType.Information,
                        target: '',
                        persistent: true
                    });
                    Messaging.addMessages(consolidatedMessage);
            }
    }
```

**STEP**: 3 — Important constraints and best practices

**DESCRIPTION**: Follow these constraints to prevent breaking framework behavior:
- This extension point applies only to transient messages (the transient message model). Do not change state messages from the message model accessed via Messaging.getMessageManager().getMessageModel().
- Do not alter the target property of any message from the message model — changing targets may break message model services.
- Use only the official SAP Fiori elements extensionAPI; avoid accessing or manipulating internal controls, properties, models, or bindings created by the framework.
- Use app extensions only when required; prefer manifest settings or annotations where possible.

**LANGUAGE**: Text

**CODE**:
```
- Applicable only to SAP Fiori elements for OData V2.
- Only adapt transient messages (Messaging.getMessageModel()).
- Do NOT modify state messages (Messaging.getMessageManager().getMessageModel()).
- Do NOT change message targets from the message model.
- Use only the official extensionAPI. Do not access internal framework objects.
- In Flexible Column Layout ensure message model adaptation is handled for ListReport, ObjectPage, and AnalyticalListPage because all extension points are invoked.
```

fiori-elements-framework
OData V2
extension
transient-messages
ListReport
ObjectPage
AnalyticalListPage
manifest.json
controller-extension
Messaging


**TITLE**: Adding a Chart Facet to an Object Page

**INTRODUCTION**: This guide explains how to add a chart facet to an object page in SAP Fiori Elements. It covers the general approach (UI.Facet → UI.ReferenceFacet → UI.Chart) and provides concrete code examples for OData V4 (XML annotations), ABAP CDS annotations, and CAP CDS annotations. It also states the OData V2 limitation on using qualified UI.Chart annotations in object pages.

**TAGS**: fiori-elements, object-page, chart, UI.Chart, UI.ReferenceFacet, UI.PresentationVariant, OData V4, OData V2, CDS, ABAP, CAP

STEP: 1 — Add a Chart Facet to an Object Page (concept)
DESCRIPTION: Use the UI.Facet term with the UI.ReferenceFacet complex type and reference the UI.Chart annotation (or reference a UI.PresentationVariant that contains UI.Chart). Place the ReferenceFacet inside the object page content section to display a chart facet. This is typically rendered as a chart inside a content section of the object page (see image reference below).
- Image reference: images/ObjectPage_SmartChart_69b1977.png
LANGUAGE: Text
CODE:
```text
To add a chart facet, use the UI.Facet term and include the UI.ReferenceFacet complex type, and then reference the UI.Chart annotation.
```

STEP: 2 — OData V4: XML Annotation example (ReferenceFacet → PresentationVariant with UI.Chart)
DESCRIPTION: For OData V4 applications, point the ReferenceFacet Target to a UI.PresentationVariant annotation that lists UI.Chart as the first visualization. This enables showing the chart as the first visualization in the facet.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.ReferenceFacet">
    <PropertyValue Property="Label" String="Items"/>
    <PropertyValue Property="ID" String="SalesOrderItems"/>
    <PropertyValue Property="Target" AnnotationPath="_Item/@UI.PresentationVariant"/>
    <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
</Record>

<Annotation Term="UI.PresentationVariant">
    <Record Type="UI.PresentationVariantType">
        <PropertyValue Property="SortOrder">
            <Collection>
                <Record Type="Common.SortOrderType">
                    <PropertyValue Property="Property" PropertyPath="SalesOrderItem"/>
                    <PropertyValue Property="Descending" Bool="true"/>
                </Record>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="Visualizations">
            <Collection>
                <AnnotationPath>@UI.Chart</AnnotationPath>
                <AnnotationPath>@UI.LineItem</AnnotationPath>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

STEP: 3 — ABAP CDS Annotation example (PresentationVariant reference and AS_CHART)
DESCRIPTION: Example ABAP CDS annotation to declare a UI.facet referencing a presentation variant and specifying visualizations including chart first (AS_CHART) and then line item. Use this in ABAP CDS view annotation sections for OData V4 stack.
LANGUAGE: ABAP
CODE:
```
@UI.facet: [
   {
      id:           'SalesOrderItems',
      label:        'Items',
      type:         #PRESENTATIONVARIANT_REFERENCE,
      purpose:      #STANDARD,
      targetElement: '_Item',
      importance:   #HIGH
    },
  ]
SalesOrder;

@UI.PresentationVariant: [
  {
    sortOrder: [
      {
        by: ' SALESORDERITEM',
        direction: #DESC
      }
    ],
    visualizations: [
      {
        type: #AS_CHART
      },
     {
        type: #AS_LINEITEM
      }
    ]
  }
]
annotate view VIEWNAME with {

}
```

STEP: 4 — CAP CDS Annotation example (UI.ReferenceFacet & UI.PresentationVariant)
DESCRIPTION: CAP CDS (JSON-like) representation showing the ReferenceFacet and PresentationVariant entries. Visualizations reference @UI.Chart first and @UI.LineItem second.
LANGUAGE: CAP CDS
CODE:
```
{
            $Type             : 'UI.ReferenceFacet',
            Label             : 'Items',
            ID                : 'SalesOrderItems',
            Target            : '_Item/@UI.PresentationVariant',
            ![@UI.Importance] : #High
 }

UI.PresentationVariant: {
    SortOrder : [
        {
            $Type : 'Common.SortOrderType',
            Property : SalesOrderItem,
            Descending : true
        }
    ],
    Visualizations : [
        '@UI.Chart',
        '@UI.LineItem'
    ]
}
```

STEP: 5 — OData V2 limitation (qualifier / navigation property)
DESCRIPTION: The object page in SAP Fiori Elements for OData V2 does not support UI.Chart annotations that use qualifiers on navigation properties. Avoid using qualified UI.Chart annotations on the object page; instead use supported patterns (e.g., PresentationVariant with visuals) or target a non-qualified chart annotation where available.
LANGUAGE: XML (example of a qualified chart annotation — avoid for OData V2 object page)
CODE:
```xml
<!-- Example of a qualified chart annotation (NOT supported on OData V2 object page):
     <Annotation Term="UI.Chart#MyQualifier"> ... </Annotation>
-->
```

Adding a Chart Facet to an Object Page

fiori-elements
object-page
chart
UI.Chart
UI.ReferenceFacet
UI.PresentationVariant
OData V4
OData V2
CDS
ABAP
CAP


**TITLE**: Adding a Contact Facet (UI.ReferenceFacet / Communication.Contact)

**INTRODUCTION**: Instructions and ready-to-use annotation snippets to add a Contact facet/card in SAP Fiori Elements applications. Includes OData V2 and V4 examples (XML annotations, ABAP CDS, CAP CDS). Use these to render contact lists, contact cards, and smart-link popovers that display contact details (name, photo, title, org, address, email, phone).

**TAGS**: fiori-elements-framework, annotations, Communication.Contact, UI.ReferenceFacet, DataFieldForAnnotation, Contact card, OData V2, OData V4, ABAP CDS, CAP CDS, XML

STEP: 1 — Add a Reference Facet (OData V2)

DESCRIPTION: Add a UI.ReferenceFacet that points to a contact annotation (Communication.Contact) via the navigation path. This renders the facet label and the contact fn property; clicking the contact name opens a quick view with details.

LANGUAGE: XML

CODE:
```xml
<Record Type="UI.ReferenceFacet">
   <PropertyValue Property="Label" String="Supplier"/>
   <PropertyValue AnnotationPath="to_Supplier/@Communication.Contact" Property="Target"/>
</Record>
```

LANGUAGE: ABAP CDS

CODE:
```abap
@UI.facet: [
 {
  label: 'Supplier',
  type:         #CONTACT_REFERENCE,
  targetElement: '_Supplier',
  purpose: #STANDARD
 }
]
product;
```

STEP: 2 — Define Contact Annotation (OData V2) — Contact Card Fields and Behavior

DESCRIPTION: Define Communication.Contact on the target EntityType. The contact card reads these properties; implement them as shown to control card content and behavior.

- Property mapping and behavior:
  - fn: full name; displayed as title (large font). Click name to open quick view.
  - title: job title; shown below title.
  - photo: URL for photo; shown in header. If absent, fallback icon is shown.
  - role / org: displayed in content.
  - adr: address must follow addressType; displayed as "street, code, locality, region, country" comma-separated. If label property used, only label shown (other address fields ignored).
  - mail / email: email addresses with type (supported: preferred, work). Displayed as mailto links; clicking opens mail client.
  - tel: telephone numbers with types (supported: preferred, cell, work, fax). Displayed as tel links; clicking opens phone application. For fax use type: #fax.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="SEPMRA_PROD_MAN.SEPMRA_I_EmployeeType">
	<Annotation Term="Communication.Contact">
		<Record>
			<PropertyValue Property="fn" Path="FormattedName"/>
			<PropertyValue Property="title" Path="JobTitle"/>
			<PropertyValue Property="org" Path="CompanyName"/>
			<PropertyValue Property="role" Path="OrganizationRole"/>
			<PropertyValue Property="n">
				<Record>
					<PropertyValue Property="given" Path="FirstName"/>
					<PropertyValue Property="additional" Path="MiddleName"/>
					<PropertyValue Property="surname" Path="LastName"/>
				</Record>

			</PropertyValue>
			<PropertyValue Property="photo" Path="EmployeePictureURL"/>
			<PropertyValue Property="tel">
				<Collection>
					<Record>
						<PropertyValue Property="type" EnumMember="Communication.PhoneType/fax"/>
						<PropertyValue Property="uri" Path="FaxNumber"/>
					</Record>
					<Record>
						<PropertyValue Property="type" EnumMember="Communication.PhoneType/cell"/>
						<PropertyValue Property="uri" Path="MobilePhoneNumber"/>
					</Record>
					<Record>
						<PropertyValue Property="type" EnumMember="Communication.PhoneType/work"/>
						<PropertyValue Property="uri" Path="PhoneNumber"/>
					</Record>
					<Record>
						<PropertyValue Property="type" EnumMember=""/>
						<PropertyValue Property="address" Path="FaxNumber"/>
					</Record>
				</Collection>
			</PropertyValue>
			<PropertyValue Property="email">
				<Collection>
					<Record>
						<PropertyValue Property="type" EnumMember="Communication.ContactInformationType/work"/>
						<PropertyValue Property="address" Path="EmailAddress"/>
					</Record>
				</Collection>
			</PropertyValue>
		</Record>
	</Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS

CODE:
```abap
define view VIEWNAME
{
  @Semantics.name.fullName: true
  FormattedName,

  @Semantics.eMail.address: true
  @Semantics.eMail.type:  [#WORK]
  EmailAddress,

  @Semantics.telephone.type:  [ #FAX ]
  FaxNumber,

  @Semantics.telephone.type:  [ #CELL ]
  MobilePhoneNumber,

  @Semantics.telephone.type:  [ #WORK]
  PhoneNumber,

  @Semantics.name: { jobTitle: true }
  JobTitle,

  @Semantics.organization: { name: true }
  CompanyName,

  @Semantics.organization: { role: true, unit: true }
  OrganizationRole

  @Semantics.name: { givenName: true }
  FirstName,

  @Semantics.name: { additionalName: true }
  MiddleName,

  @Semantics.name: { familyName: true }
  LastName,

  @Semantics.address : { city: true }
  City,

  @Semantics.contact.photo: true
  EmployeePictureURL
}
```

STEP: 3 — Add Contact Column / Smart Link (OData V4) — DataFieldForAnnotation

DESCRIPTION: For OData V4 use UI.DataFieldForAnnotation in LineItem to render a contact smart link column. Set Target to supplier/@Communication.Contact (navigation path). This creates a smart link that opens a contact popover with additional configured fields.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="clouds.products.CatalogService.Products">
    <Annotation Term="UI.LineItem">
        <Collection>
            <Record Type="UI.DataFieldForAnnotation">
                <PropertyValue Property="Label" String="Supplier"/>
                <PropertyValue Property="Target" AnnotationPath="supplier/@Communication.Contact"/>
            </Record>
        </Collection>
    </Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS

CODE:
```abap
annotate view PRODUCTS.CATALOGSERVICE.PRODUCTS with {

@UI.lineItem: [
  {
    label: 'Supplier',
    value: 'SUPPLIER',
    type: #AS_CONTACT,
    position: 1
  }
]

test;
}
```

LANGUAGE: CAP CDS

CODE:
```cds
LineItem                         : [
    {
        $Type  : 'UI.DataFieldForAnnotation',
        Target : 'supplier/@Communication.Contact',
        Label  : 'Supplier'
    }]
```

STEP: 4 — Define Communication.Contact on the EntitySet (OData V4) — Content of the Contact Card / Popover

DESCRIPTION: Add the Communication.Contact annotation to the EntitySet targeted by the navigation property (e.g., Suppliers). The snippet below defines email, fn, and tel entries used to populate the contact card/popover. If you require additional fields (adr, photo, role, org, etc.), add them similarly. Note: if no @Contact.photo annotation is provided, a fallback contact icon is displayed.

LANGUAGE: XML

CODE:
```xml
<Annotations Target="clouds.products.CatalogService.Suppliers">
    <Annotation Term="Communication.Contact">
        <Record Type="Communication.ContactType">
            <PropertyValue Property="email">
                <Collection>
                    <Record Type="Communication.EmailAddressType">
                        <PropertyValue Property="type">
                            <EnumMember>Communication.ContactInformationType/work</EnumMember>
                        </PropertyValue>
                        <PropertyValue Property="address">
                            <Path>emailAddress</Path>
                        </PropertyValue>
                    </Record>
                </Collection>
            </PropertyValue>
            <PropertyValue Property="fn">
                <Path>name</Path>
            </PropertyValue>
            <PropertyValue Property="tel">
                <Collection>
                    <Record Type="Communication.PhoneNumberType">
                        <PropertyValue Property="type">
                            <EnumMember>Communication.PhoneType/fax</EnumMember>
                        </PropertyValue>
                        <PropertyValue Property="uri">
                            <Path>faxNumber</Path>
                        </PropertyValue>
                    </Record>
                    <Record Type="Communication.PhoneNumberType">
                        <PropertyValue Property="type">
                            <EnumMember>Communication.PhoneType/work</EnumMember>
                        </PropertyValue>
                        <PropertyValue Property="uri">
                            <Path>phoneNumber</Path>
                        </PropertyValue>
                    </Record>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS

CODE:
```abap
define view Suppliers
{
  @Semantics.name.fullName: true
  name,

  @Semantics.eMail.address: true
  @Semantics.eMail.type:  [#WORK]
  emailAddress,

  @Semantics.telephone.type:  [ #FAX ]
  FaxNumber,

  @Semantics.telephone.type:  [ #WORK]
  PhoneNumber
}
```

LANGUAGE: CAP CDS

CODE:
```cds
FieldGroup #HeaderGeneralInformation            : {Data : [{
        $Type  : 'UI.DataFieldForAnnotation',
        Target : '_SoldToParty/@Communication.Contact',
        Label  : 'Contact Info'
    }, ]},

entity Customer                                        @(
    cds.autoexpose,
    title                  : 'Sold-to Party',
    Communication.Contact  : {
        email : [{
            type    : #work,
            address : EmailAddress
        }],
        fn    : CustomerName,
        tel   : [{
            type : #fax,
            uri  : InternationalPhoneNumber
        }],
        adr   : [{
            type     : #work,
            code     : PostalCode,
            country  : Country,
            locality : CityName
        }]
    },
    Common.IsNaturalPerson : true
)
```

STEP: 5 — Implementation Checklist & Tips

DESCRIPTION: Quick actionable checklist before deploying:

- Ensure the ReferenceFacet / DataFieldForAnnotation Target points to the correct navigation path and EntitySet annotation (e.g., supplier/@Communication.Contact).
- On the target EntitySet (Suppliers / EmployeeType / view), add Communication.Contact entries referencing property Paths used in your service/view.
- Provide @Semantics annotations (email, telephone, name, contact.photo, address) in CDS or mapping in XML so Fiori Elements can identify fields.
- Use supported email types (preferred, work) and phone types (preferred, cell, work, fax).
- Address formatting: street, code, locality, region, country (comma-separated); if address label used, it overrides other address fields.
- If no photo annotation present, a fallback icon is shown.

fiori-elements-framework
annotations
Communication.Contact
UI.ReferenceFacet
DataFieldForAnnotation
Contact card
OData V2
OData V4
ABAP CDS
CAP CDS
XML


**TITLE**: Adding a Contact Quick View to a Table

**INTRODUCTION**: Use the @Communication.Contact annotation to enable a contact quick view for a table column (available from list report and object page). Implementation requires two changes: (1) add a UI.LineItem entry for the entity displayed in the table (ProductType in the example) that references the contact annotation via a DataFieldForAnnotation Target (e.g. to_Supplier/@Communication.Contact), and (2) define the @Communication.Contact annotation on the related entity (SupplierType) mapping name, phone and email fields.

**TAGS**: fiori-elements-framework, annotations, UI.LineItem, Communication.Contact, Contact Quick View, ABAP CDS, CAP CDS, XML

**STEP**: 1 — Add UI.LineItem (XML Annotation)

**DESCRIPTION**: Insert this UI.LineItem annotation block under the ProductType entity annotation file (EDMX / annotation XML) or equivalent location. Ensure the DataFieldForAnnotation record uses Target AnnotationPath="to_Supplier/@Communication.Contact" to enable the contact quick view for the Supplier column.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="UI.LineItem">
    <Collection>
        <Record Type="UI.DataFieldForAction">
            <PropertyValue Property="Label" String="Activate" />
            <PropertyValue Property="Action"
                           String="STTA_PROD_MAN.STTA_PROD_MAN_Entities/STTA_C_MP_ProductActivation"/>
            <PropertyValue Property="InvocationGrouping"
                           EnumMember="UI.OperationGroupingType/ChangeSet" />
        </Record>
        <Record Type="UI.DataField">
            <PropertyValue Property="Value" Path="ProductPictureURL" />
            <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
        </Record>
        <Record Type="UI.DataField">
            <PropertyValue Property="Value" Path="ProductForEdit" />
            <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
        </Record>
        <Record Type="UI.DataField">
            <PropertyValue Property="Value" Path="ProductCategory" />
            <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
        </Record>
        <Record Type="UI.DataFieldWithIntentBasedNavigation">
            <PropertyValue Property="Label" String="Supplier (with IBN)" />
            <PropertyValue Property="Value" Path="Supplier" />
            <PropertyValue Property="SemanticObject" String="EPMProduct" />
            <PropertyValue Property="Action" String="manage" />
        </Record>
        <Record Type="UI.DataFieldForAnnotation">
            <PropertyValue Property="Label" String="{@i18n>Supplier}"/>
            <PropertyValue Property="Target"
                           AnnotationPath="to_Supplier/@Communication.Contact"/>
            <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
        </Record>
        <Record Type="UI.DataField">
            <PropertyValue Property="Criticality"
                           Path="to_StockAvailability/StockAvailability" />
            <PropertyValue Property="Value"
                           Path="to_StockAvailability/StockAvailability" />
            <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
        </Record>
        <Record Type="UI.DataFieldForAnnotation">
            <PropertyValue Property="Label" String="Rating" />
            <PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Rating" />
        </Record>
        <Record Type="UI.DataFieldForAnnotation">
            <PropertyValue Property="Label" String="Progress" />
            <PropertyValue Property="Criticality"
                           Path="to_StockAvailability/Quantity" />
            <PropertyValue Property="Target" AnnotationPath="@UI.DataPoint#Progress" />
        </Record>
        <Record Type="UI.DataField">
            <PropertyValue Property="Value" Path="Price" />
            <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High" />
        </Record>
        <Record Type="UI.DataFieldForAction">
            <PropertyValue Property="Label" String="Copy" />
            <PropertyValue Property="IconUrl" String="sap-icon://copy" />
            <PropertyValue Property="Action"
                           String="STTA_PROD_MAN.STTA_PROD_MAN_Entities/STTA_C_MP_ProductCopy" />
            <PropertyValue Property="Inline" Bool="true" />
            <PropertyValue Property="Determining" Bool="true" />
            <PropertyValue Property="InvocationGrouping"
                           EnumMember="UI.OperationGroupingType/Isolated" />
        </Record>
        <Record Type="UI.DataFieldForIntentBasedNavigation">
            <PropertyValue Property="Label" String="{@i18n>MANAGE_PRODUCTS_(ST)_2}" />
            <PropertyValue Property="SemanticObject" String="EPMProduct" />
            <PropertyValue Property="Action" String="manage_st" />
            <PropertyValue Property="Inline" Bool="false" />
            <PropertyValue Property="Determining" Bool="false" />
            <PropertyValue Property="RequiresContext" Bool="true" />
        </Record>
        <Record Type="UI.DataFieldForIntentBasedNavigation">
            <PropertyValue Property="Label" String="{@i18n>Inline_Nav_MasterDetail}" />
            <PropertyValue Property="SemanticObject" String="EPMProduct" />
            <PropertyValue Property="Action" String="manage" />
            <PropertyValue Property="Inline" Bool="true" />
            <PropertyValue Property="Determining" Bool="false" />
            <PropertyValue Property="RequiresContext" Bool="false" />
        </Record>
        <Record Type="UI.DataFieldForAnnotation">
            <PropertyValue Property="Label" String="Sales"/>
            <PropertyValue Property="Target" AnnotationPath="to_ProductSalesPrice/@UI.Chart#SalesPriceAreaChart"/>
        </Record>
        <Record Type="UI.DataFieldForAnnotation">
            <PropertyValue Property="Label" String="Revenue"/>
            <PropertyValue Property="Target" AnnotationPath="to_ProductSalesRevenue/@UI.Chart#GrossSalesRevenueBulletChart"/>
        </Record>
    </Collection>
</Annotation>
```

**STEP**: 2 — Add UI.LineItem (ABAP CDS Annotation)

**DESCRIPTION**: If using ABAP CDS, add the following @UI.lineItem entries in the CDS view for ProductType. Ensure the entry that represents the supplier uses type #AS_CONTACT or references TO_SUPPLIER accordingly so the contact quick view is enabled.

**LANGUAGE**: ABAP CDS

**CODE**:
```
@UI.lineItem: [
  {
    label: 'Activate',
    dataAction: 'PUSHDOWN:STTA_C_MP_ProductActivation',
    invocationGrouping: #CHANGE_SET,
    type: #FOR_ACTION,
    position: 1
  },
  {
    importance: #HIGH,
    value: 'PRODUCTPICTUREURL',
    type: #STANDARD,
    position: 2
  },
  {
    importance: #HIGH,
    label: '{@i18n>@Supplier}',
    value: 'TO_SUPPLIER',
    type: #AS_CONTACT,
    position: 6
  },
  {
    label: 'Rating',
    valueQualifier: 'Rating',
    type: #AS_DATAPOINT,
    position: 8
  },
  {
    label: 'Progress',
    criticality: 'TO_STOCKAVAILABILITY/QUANTITY',
    valueQualifier: 'Progress',
    type: #AS_DATAPOINT,
    position: 9
  },
  {
    label: 'Copy',
    iconUrl: 'sap-icon:,//copy'
    dataAction: 'PUSHDOWN:STTA_C_MP_ProductCopy',
    invocationGrouping: #ISOLATED,
    type: #FOR_ACTION,
    position: 11
  },
  {
    label: '{@i18n>@MANAGE_PRODUCTS_(ST)_2}',
    semanticObjectAction: 'manage_st',
    requiresContext: true,
    type: #FOR_INTENT_BASED_NAVIGATION,
    position: 12
  },
  {
    label: '{@i18n>@Inline_Nav_MasterDetail}',
    semanticObjectAction: 'manage',
    type: #FOR_INTENT_BASED_NAVIGATION,
    position: 13
  },
  {
    label: 'Sales',
    valueQualifier: 'SalesPriceAreaChart',
    value: 'TO_PRODUCTSALESPRICE',
    type: #AS_CHART,
    position: 14
  },
  {
    label: 'Revenue',
    valueQualifier: 'GrossSalesRevenueBulletChart',
    value: 'TO_PRODUCTSALESREVENUE',
    type: #AS_CHART,
    position: 15
  }
]
PRODUCTPICTUREURL;

@UI.lineItem: [
  {
    importance: #HIGH,
    value: 'PRODUCTFOREDIT',
    type: #STANDARD,
    position: 3
  }
]
PRODUCTFOREDIT;

@UI.lineItem: [
  {
    importance: #HIGH,
    value: 'PRODUCTCATEGORY',
    type: #STANDARD,
    position: 4
  }
]
PRODUCTCATEGORY;

@UI.lineItem: [
  {
    label: 'Supplier (with IBN)',
    value: 'SUPPLIER',
    semanticObjectAction: 'manage',
    type: #WITH_INTENT_BASED_NAVIGATION,
    position: 5
  }
]
SUPPLIER;

@UI.lineItem: [
  {
    importance: #HIGH,
    criticality: 'TO_STOCKAVAILABILITY/STOCKAVAILABILITY',
    value: 'TO_STOCKAVAILABILITY/STOCKAVAILABILITY',
    type: #STANDARD,
    position: 7
  }
]
TO_STOCKAVAILABILITY/STOCKAVAILABILITY;

@UI.lineItem: [
  {
    importance: #HIGH,
    value: 'PRICE',
    type: #STANDARD,
    position: 10
  }
]
PRICE;

@Consumption.semanticObject: 'EPMProduct'
SUPPLIER;
```

**STEP**: 3 — Add UI.LineItem (CAP CDS Annotation)

**DESCRIPTION**: If using CAP (CDS), add the following UI.LineItem array to the entity definition for ProductType. Note the DataFieldForAnnotation Target uses 'to_Supplier/@Communication.Contact' to reference the contact annotation defined on the supplier entity.

**LANGUAGE**: CAP CDS

**CODE**:
```
UI.LineItem : [
    {
        $Type : 'UI.DataFieldForAction',
        Label : 'Activate',
        Action : 'STTA_PROD_MAN.STTA_PROD_MAN_Entities/STTA_C_MP_ProductActivation',
        InvocationGrouping : #ChangeSet
    },
    {
        $Type : 'UI.DataField',
        Value : ProductPictureURL,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : ProductForEdit,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : ProductCategory,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataFieldWithIntentBasedNavigation',
        Label : 'Supplier (with IBN)',
        Value : Supplier,
        SemanticObject : 'EPMProduct',
        Action : 'manage'
    },
    {
        $Type : 'UI.DataFieldForAnnotation',
        Label : '{@i18n>@Supplier}',
        Target : 'to_Supplier/@Communication.Contact',
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Criticality : to_StockAvailability.StockAvailability,
        Value : to_StockAvailability.StockAvailability,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataFieldForAnnotation',
        Label : 'Rating',
        Target : '@UI.DataPoint#Rating'
    },
    {
        $Type : 'UI.DataFieldForAnnotation',
        Label : 'Progress',
        Criticality : to_StockAvailability.Quantity,
        Target : '@UI.DataPoint#Progress'
    },
    {
        $Type : 'UI.DataField',
        Value : Price,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataFieldForAction',
        Label : 'Copy',
        IconUrl : 'sap-icon://copy',
        Action : 'STTA_PROD_MAN.STTA_PROD_MAN_Entities/STTA_C_MP_ProductCopy',
        Inline : true,
        Determining : true,
        InvocationGrouping : #Isolated
    },
    {
        $Type : 'UI.DataFieldForIntentBasedNavigation',
        Label : '{@i18n>@MANAGE_PRODUCTS_(ST)_2}',
        SemanticObject : 'EPMProduct',
        Action : 'manage_st',
        Inline : false,
        Determining : false,
        RequiresContext : true
    },
    {
        $Type : 'UI.DataFieldForIntentBasedNavigation',
        Label : '{@i18n>@Inline_Nav_MasterDetail}',
        SemanticObject : 'EPMProduct',
        Action : 'manage',
        Inline : true,
        Determining : false,
        RequiresContext : false
    },
    {
        $Type : 'UI.DataFieldForAnnotation',
        Label : 'Sales',
        Target : 'to_ProductSalesPrice/@UI.Chart#SalesPriceAreaChart'
    },
    {
        $Type : 'UI.DataFieldForAnnotation',
        Label : 'Revenue',
        Target : 'to_ProductSalesRevenue/@UI.Chart#GrossSalesRevenueBulletChart'
    }
]
```

**STEP**: 4 — Define Communication.Contact on SupplierType (XML Annotation)

**DESCRIPTION**: Add the Communication.Contact annotation block to the SupplierType entity annotation file (EDMX / annotation XML). Map fn, tel, and email to entity properties (CompanyName, FaxNumber, PhoneNumber, EmailAddress). The example below shows multiple tel/email entries and types.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="Communication.Contact">
    <Record>
        <PropertyValue Property="fn" Path="CompanyName" />
        <PropertyValue Property="tel">
            <Collection>
                <Record>
                    <PropertyValue Property="type"
                                   EnumMember="Communication.PhoneType/fax" />
                    <PropertyValue Property="uri" Path="FaxNumber" />
                </Record>
                <Record>
                    <PropertyValue Property="type"
                                   EnumMember="Communication.PhoneType/preferred Communication.PhoneType/work" />
                    <PropertyValue Property="uri" Path="PhoneNumber" />
                </Record>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="email">
            <Collection>
                <Record>
                    <PropertyValue Property="type"
                                   EnumMember="Communication.ContactInformationType/work Communication.ContactInformationType/pref" />
                    <PropertyValue Property="address" Path="EmailAddress" />
                </Record>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

**STEP**: 5 — Define Communication.Contact (ABAP CDS / semantic mapping)

**DESCRIPTION**: For ABAP CDS, ensure the supplier CDS view marks the name, email and telephone fields with the appropriate Semantics annotations so the framework recognizes them as contact data. The sample below demonstrates @Semantics.name.fullName, @Semantics.eMail.address + type, and @Semantics.telephone.type annotations.

**LANGUAGE**: ABAP CDS

**CODE**:
```
define view VIEWNAME
{
  @Semantics.name.fullName: true
  CompanyName,

  @Semantics.eMail.address: true
  @Semantics.eMail.type:  [#WORK]
  EmailAddress,

  @Semantics.telephone.type:  [ #FAX ]
  FaxNumber,

  @Semantics.telephone.type:  [ #WORK]
  PhoneNumber
}
```

**STEP**: 6 — Define Communication.Contact (CAP CDS)

**DESCRIPTION**: For CAP CDS, declare a Communication.Contact structured annotation on the supplier entity mapping the name, phone and email properties. The following CAP CDS object shows mapping for fn, tel (multiple entries with types), and email.

**LANGUAGE**: CAP CDS

**CODE**:
```
Communication.Contact : {
    fn : CompanyName,
    tel : [
        {
            type : #fax,
            uri : FaxNumber
        },
        {
            type : [ #preferred, #work ],
            uri : PhoneNumber
        },
    ],
    email : [
        {
            type : [ #work, #pref ],
            address : EmailAddress
        }
    ]
}
```

Adding a Contact Quick View to a Table

fiori-elements-framework
annotations
UI.LineItem
Communication.Contact
Contact Quick View
ABAP CDS
CAP CDS
XML


**TITLE**: Add Custom Message Strip to List Report, Analytical List Page and Object Page Tables (OData V2 & V4)

**INTRODUCTION**: Provide actionable instructions and code examples to display custom message strips above tables in SAP Fiori Elements: for List Report, Analytical List Page and Object Page tables. Covers both OData V2 and OData V4 scenarios, tab-scoped messages, controller hooks, required table IDs, optional parameters and sample code to implement.

**TAGS**: fiori-elements-framework, OData V2, OData V4, extensionAPI, setCustomMessage, addMessage, message-strip, object-page, list-report, analytical-list-page

**STEP**: 1 — OData V2: Add a custom message to List Report / Analytical List Page tables

**DESCRIPTION**: In the List Report or Analytical List Page controller extension, call this.extensionAPI.setCustomMessage inside the onBeforeRebindTableExtension hook to display a custom message strip above the table. Provide a message object with `message` and `type`. Place code in your extension controller file (example file names shown).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
// ListReportExtension.controller.js / AnaliticalListPageExt.controller.js
onBeforeRebindTableExtension: function () {

  var oMessage = {
                message: "Custom message on table",
                type: sap.ui.core.MessageType.Success
            };

   this.extensionAPI.setCustomMessage(oMessage);
  }
```

**STEP**: 2 — OData V2: Display messages for specific tabs or all tabs

**DESCRIPTION**: When your page contains multiple tabs, pass a tab key (string) or an array of tab keys as the second argument to setCustomMessage to show the message only for targeted tabs. Omitting the tabKey displays the message on all tabs.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
this.extensionAPI.setCustomMessage(oMessage, "1");         	        // Displays message only on 1st tab

			or

this.extensionAPI.setCustomMessage(oMessage, ["1","2"]);        // Displays message only on 1st and 2nd tab

			or

this.extensionAPI.setCustomMessage(oMessage); 		        // Displays message on all the tabs
```

**STEP**: 3 — OData V2: Multiple tab messages on Object Page (example with explicit table IDs)

**DESCRIPTION**: For object pages with multiple tabs, call setCustomMessage for each tab. When targeting object page tables, include the full table ID as the second parameter and the tab key (if needed) as the third parameter. Use this pattern in onBeforeRebindTableExtension.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
onBeforeRebindTableExtension: function () {
            if (this.extensionAPI.setCustomMessage) {
                var oMsg1 = {
                    message: "Custom message on object page tab 1",
                    type: sap.ui.core.MessageType.Success
                };
                var oMsg2 = {
                    message: "Custom message on object page tab 2",
                    type: sap.ui.core.MessageType.Error
                };
this.extensionAPI.setCustomMessage(oMsg1,"STTASOMVLR::sap.suite.ui.generic.template.ObjectPage.view.Details::C_STTA_SalesOrder_WD_20--SalesOrderItemsID::Table", "_tab1");    //Displays message on 1st tab
                    this.extensionAPI.setCustomMessage(oMsg2,"STTASOMVLR::sap.suite.ui.generic.template.ObjectPage.view.Details::C_STTA_SalesOrder_WD_20--SalesOrderItemsID::Table", "_tab2");       //Displays message on 2nd tab
}
}
```

**STEP**: 4 — OData V2: Add custom message to object page table (single-table example)

**DESCRIPTION**: To add a custom message for an object page table, specify the exact table ID when calling setCustomMessage inside onBeforeRebindTableExtension. Use the controller file ObjectPageExtension.controller.js.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
// ObjectPageExtension.controller.js
onBeforeRebindTableExtension: function () {
            if (this.extensionAPI.setCustomMessage) {
                var oMsg = {
                    message: "Custom message on object page tab 1",
                    type: sap.ui.core.MessageType.Success
                };
this.extensionAPI.setCustomMessage(oMsg,"STTASOMVLR::sap.suite.ui.generic.template.ObjectPage.view.Details::C_STTA_SalesOrder_WD_20--SalesOrderItemsID::Table");
            }
        }
```

**STEP**: 5 — OData V2: Supported message types and API parameters

**DESCRIPTION**: The setCustomMessage API accepts:
- Message Object (optional): { message: string, type: sap.ui.core.MessageType.* }
- Tab Key (optional): string or array of strings identifying tabs OR the table ID for object page followed by tab key

Supported message types:
- sap.ui.core.MessageType.Success
- sap.ui.core.MessageType.Warning
- sap.ui.core.MessageType.Error
- sap.ui.core.MessageType.Information

Restriction: Do not use this extension API with multiple view scenarios. Not supported for smart charts and smart lists.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "messageObject": {
    "message": "string",
    "type": "sap.ui.core.MessageType.Success | Warning | Error | Information"
  },
  "tabKey": "string | [string]",
  "usageNote": "For object page table: pass tableId as second param, optionally a tab key as third param"
}
```

**STEP**: 6 — OData V4: Add custom message to List Report / Analytical List Page (ListReport extension)

**DESCRIPTION**: In OData V4 ListReport controller extension, call extensionAPI.setCustomMessage (obtained from this.base.getExtensionAPI()) in hooks like routing.onAfterBinding. The function supports three optional parameters: message object, tabKey, and an onClose callback. Omitting the message object removes existing messages. Use the sample routing:onAfterBinding code below.

**LANGUAGE**: JavaScript

**CODE**:
```xml
routing: {
    onAfterBinding: function (oBindingContext, mParameters) {
        var oMessage = {
                message: "onAfterBinding: Context bound. Have a nice day",
                type: sap.ui.core.MessageType.Information
            },
            extensionAPI = this.base.getExtensionAPI();

        function fnOnClose() {
            MessageToast.show("Custom message closed");
        }

        extensionAPI.setCustomMessage(oMessage, null, fnOnClose);

    }
}
```

**STEP**: 7 — OData V4: Add custom message to Object Page table (Table building block)

**DESCRIPTION**: For OData V4 object pages, use the Table building block API addMessage to add messages to tables. Prefer the Table building block's public APIs for object page tables. See the SAP Fiori Development portal for live examples and full Table building block API documentation.

**LANGUAGE**: N/A

**CODE**:
```text
Reference: Building Blocks - Table - Extensions - Table APIs
https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/table/tablePublicAPIs
```

**STEP**: 8 — Additional notes and links

**DESCRIPTION**: Useful references for extending list reports, analytical list pages and object pages. Follow the recommended extension points and avoid unsupported combinations.

**LANGUAGE**: N/A

**CODE**:
```text
Related:
- Extending List Reports and Object Pages Using App Extensions:
  extending-list-reports-and-object-pages-using-app-extensions-a892eb8.md

- Configuring Analytical List Page App Extensions:
  configuring-analytical-list-page-app-extensions-9504fb4.md
```

fiori-elements-framework
OData V2
OData V4
extensionAPI
setCustomMessage
addMessage
message-strip
object-page
list-report
analytical-list-page