**TITLE**: Modifying Startup Parameters with modifyStartupExtension (SAP Fiori elements, OData V2)

**INTRODUCTION**: Use the modifyStartupExtension extension method (overwrite in extension.controller.js) to modify incoming startup parameters (selectionVariant, semanticDates), choose a default tab in multi-view list reports, and adapt selection variants passed from source apps. Applicable only to SAP Fiori elements for OData V2 and invoked on initial navigation to the app.

**TAGS**: fiori-elements, OData V2, SAP Fiori, modifyStartupExtension, selectionVariant, SmartFilterBar, analytical-list-page, list-report, overview-page, extension.controller.js

**STEP**: 1 — Overview: signature and oStartupObject properties

**DESCRIPTION**: Where to implement: overwrite modifyStartupExtension in your application's extension.controller.js. Use this method to:
- Modify selectionVariant: add/remove parameters and select options (ranges or single values) so values from a source app map to your app's filter bar.
- Set semanticDates to override semantic date ranges (YESTERDAY, etc.).
- Inspect urlParameters to dynamically choose a tab in multi-view list reports.
- Set selectedQuickVariantSelectionKey to choose the default tab/key defined in manifest.
- Note: The extension is called only on initial app navigation to the analytical list page or list report (not on variant changes, filter changes, back navigation, or refresh with iAppState).

oStartupObject properties:
- selectionVariant: SelectionVariant object (modify in-place).
- urlParameters: navigation URL parameters (used to decide dynamic tab selection for list reports).
- selectedQuickVariantSelectionKey: optional manifest tab key to set default tab.
- semanticDates: semantic date-range object (modify to set semantic filters).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
modifyStartupExtension: function (oStartupObject) {
    // oStartupObject.selectionVariant      // SelectionVariant (add/remove parameters/selectOptions)
    // oStartupObject.urlParameters         // URL params used to decide which tab to load (list report)
    // oStartupObject.selectedQuickVariantSelectionKey // optional tab key to set default (manifest-defined)
    // oStartupObject.semanticDates         // semantic date ranges to override defaults
}
```

**STEP**: 2 — List Report: modify selectionVariant, semanticDates, and set default tab

**DESCRIPTION**: Overwrite modifyStartupExtension in extension.controller.js to:
- Modify incoming selectionVariant: removeParameter, addParameter, addSelectOption (including range values).
- Override or add semanticDates to set semantic date filters.
- Set selectedQuickVariantSelectionKey to choose a default tab in multi-view/multi-table list reports.

Place the exact code below into your extension.controller.js (keep code intact).

**LANGUAGE**: JavaScript

**CODE**:
```javascript

modifyStartupExtension: function(oStartupObject) {
       oSelectionVariant = oStartupObject.selectionVariant;
       if (oSelectionVariant) {
           oSelectionVariant.removeParameter("TaxAmount");
              oSelectionVariant.addParameter("Product", "EPM-2365436");
        // use        oSelectionVariant.addSelectOption("Price", "I", "BT", "1000","5000" ?)  To specify a range value

       }

       // to override the semanticDate object
       oStartupObject.selectionVariant.addParameter ("PickingDate","");
       oStartupObject.semanticDates = {
             "Dates":[
                    {
                           "PropertyName":"PickingDate",
                          "Data": {
                                 "operation":"YESTERDAY",
                                 "value1":null,
                                 "value2":null,
                                 "key":"filterPickingDate",
                                 "calendarType":"Gregorian"
                          }
                    }
             ]
       };
  oStartupObject.selectedQuickVariantSelectionKey = "_tab2";
}

```

**STEP**: 3 — Analytical List Page: conditionally modify selectionVariant and semanticDates

**DESCRIPTION**: For analytical list pages, overwrite modifyStartupExtension in extension.controller.js to:
- Inspect selectionVariant selectOptions with getSelectOption and addSelectOption to extend filters.
- Add or override semanticDates similarly to set semantic date ranges.

Place the exact code below into your extension.controller.js (keep code intact).

**LANGUAGE**: JavaScript

**CODE**:
```javascript

modifyStartupExtension: function (oStartupObject) {
	var oSelectionVariant = oStartupObject.selectionVariant;
	if (oSelectionVariant.getSelectOption("CustomerCountry") &oSelectionVariant.getSelectOption("CustomerCountry")["0"].Low === "AR") {
		oSelectionVariant.addSelectOption("WBSElement", "I", "EQ", "BLUE PRINT VALIDATION");
		oSelectionVariant.addSelectOption("CompanyCode", "I", "EQ", "EASI");
	}
	oStartupObject.selectionVariant.addSelectOption("c","I","EQ","");
	oStartupObject.semanticDates = {
		"Dates":[
			{
				"PropertyName":"SemanticCustomDate",
				"Data": {
					"operation":"YESTERDAY",
					"value1":null,
					"value2":null,
					"key":"SemanticCustomDate",
					"calendarType":"Gregorian"
				}
			}
		]
	};
}

```

**STEP**: 4 — Overview Page: modify selectionVariant passed from source app

**DESCRIPTION**: For overview pages, overwrite modifyStartupExtension in extension.controller.js to add or modify select options on the incoming selectionVariant (here named oCustomSelectionVariant). Use addSelectOption to add new filter criteria before the app applies them to the filter bar.

Place the exact code below into your extension.controller.js (keep code intact).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
modifyStartupExtension: function (oCustomSelectionVariant) {

    oCustomSelectionVariant.addSelectOption("SupplierName", "I", "EQ", "Talpa");
}
```

fiori-elements
OData V2
SAP Fiori
modifyStartupExtension
selectionVariant
SmartFilterBar
analytical-list-page
list-report
overview-page
extension.controller.js


**TITLE**: Multi-Selection for Intent-Based Navigation (SAP Fiori elements, OData V4)

**INTRODUCTION**: Explains how multi-selection is passed during intent-based navigation in SAP Fiori elements (OData V4). Describes default behavior, identification constraints when records lack unique key fields, how selection variants are composed, and shows the exact JSON structure passed for multi-selection. Use this when generating navigation or constructing selection variants programmatically.

**TAGS**: fiori-elements-framework, odata-v4, intent-based-navigation, selection-variant, multi-selection, sap

**STEP**: 1 — Behavior, applicability, and ambiguity risk

**DESCRIPTION**:
- Default: multi-selection for intent-based navigation is enabled by default.
- Applicability: This behavior applies only to SAP Fiori elements for OData V4.
- Identification constraint: Records that do not include a unique key field cannot be uniquely identified across properties. When multiple selected records are transformed into a selection variant, each property becomes a set of allowed values; the navigation target interprets each property as a conjunction (AND) of properties and a disjunction (OR) of values for each property.
- Resulting logic: The target app constructs (Property1 = v11 OR Property1 = v12 OR ...) AND (Property2 = v21 OR Property2 = v22 OR ...). This may produce extra records that were not part of the original row-wise selections.
- Actionable guidance for code generation:
  - Always include the entity key (or a composite key) properties in the selection variant to preserve row-level identity.
  - If row identity cannot be expressed as key properties, consider alternative approaches (e.g., pass explicit key predicates, use a dedicated navigation parameter containing unique record identifiers, or avoid multi-selection navigation).
  - When assembling selection variants programmatically, ensure SelectOptions contain the key fields to avoid accidental cross-combinations.

**LANGUAGE**: Text

**CODE**:
```text
Example of selected records (columns P1 and P2). Row-wise intent should pass contexts:
Record | P1 | P2
1      | A  | X
2      | B  | Y
3      | A  | Y

Navigation context passed becomes:
(P1 = A OR P1 = B) AND (P2 = X OR P2 = Y)
This can result in an extra record BX which was not in the original row selections.
```

**STEP**: 2 — Structure of the selection variant passed (sample JSON)

**DESCRIPTION**: Use this exact JSON structure as the selectionVariant payload when implementing or testing multi-selection intent-based navigation. When generating selection variants, populate SelectOptions arrays for each property with Ranges entries for each selected value. Ensure key properties are included in SelectOptions to preserve record identity.

**LANGUAGE**: JSON

**CODE**:
```json
{"selectionVariant":
    "SelectOptions":[
        {"PropertyName":"SalesOrder","Ranges":[
            {"Sign":"I","Option":"EQ","Low":"2919682","High":null}, // Context from 1st record for "SalesOrder"
            {"Sign":"I","Option":"EQ","Low":"2915717","High":null}  // Context from 2nd record for "SalesOrder"
        ]},
        {"PropertyName":"SalesOrderType","Ranges":[
            {"Sign":"I","Option":"EQ","Low":"OR","High":null}, // Context from 1st record for "SalesOrderType"
            {"Sign":"I","Option":"EQ","Low":"SE","High":null}  // Context from 2nd record for "SalesOrderType"
        ]},
        {"PropertyName":"TransactionCurrency","Ranges":[
            {"Sign":"I","Option":"EQ","Low":"EUR","High":null},
            {"Sign":"I","Option":"EQ","Low":"USD","High":null}
        ]},
.....
.....
```

fiori-elements-framework odata-v4 intent-based-navigation selection-variant multi-selection sap


**TITLE**: Multiple Views in the List Report (Fiori Elements)

**INTRODUCTION**: Practical, code-focused guide to configure multiple views (variants) on a Fiori Elements List Report. Covers single-table vs multiple-table modes, annotation choices, OData V2/V4 specifics, manifest configuration example, refresh APIs, and step-by-step UI actions using SAP Fiori Tools.

**TAGS**: fiori-elements-framework, list-report, views, variant-management, manifest.json, annotations, SelectionVariant, SelectionPresentationVariant, PresentationVariant, ODataV4, ODataV2

STEP: Modes and UI behavior

DESCRIPTION: Use one of two UI modes. Implementation details and behavior you must handle in code/config:
- Single table mode (one table instance):
  - Single table and toolbar, optional single variant management.
  - Switch between views via segmented button in toolbar; if > 3 views the control becomes a Select.
- Multiple table mode (one table instance per view):
  - N tables for N views; each table has its own toolbar and variant management.
  - Switching is via an icon tab bar; only the selected tab's table is visible.
- Multiple table mode can include charts on specific tabs.
- If a property used in multiple views is not listed in SelectionFields, remove it from the FilterBar so users cannot add it via Adapt Filter.
- Restriction: StandardList and ObjectList cannot be used in multiple view scenarios.

LANGUAGE: Text

CODE:
```text
Single table mode: segmented button (or Select if >3 views) in table toolbar.
Multiple table mode: icon tab bar above tables, one table instance per view.
Ensure properties used across views are in SelectionFields or removed from FilterBar.
Do not use StandardList/ObjectList in multiple view scenarios.
```

STEP: Annotations — which to use

DESCRIPTION: Choose annotation based on what you need to describe:
- SelectionVariant: describe which data to display (filter criteria). Use for both modes. (See: Defining Multiple Views on a List Report Table - Single Table Mode)
- PresentationVariant: describe only the visualization (e.g., different chart type).
- SelectionPresentationVariant: describe both which data AND how to present it (filters + presentation). Can be used only for multiple table mode and multiple table mode with charts.
- Multiple table mode supports charts on tabs in addition to tables.

LANGUAGE: Text

CODE:
```text
- Use SelectionVariant for filter-only view definitions.
- Use SelectionPresentationVariant when you need filters + presentation (only for multiple table mode).
- Use PresentationVariant for visualization-only changes.
```

STEP: OData V2 additional features

DESCRIPTION: V2-specific notes:
- Tables are displayed by default.
- Each tab can show a different entity set. To display a different entity set per tab, add the entity set to the corresponding tab in the manifest (see manifest example below).
- Restriction: StandardList and ObjectList cannot be used in multiple view scenarios.

LANGUAGE: Text

CODE:
```text
For V2: default behavior shows tables. Configure a tab's entity set in the manifest per-tab to show different entity sets.
```

STEP: OData V4 settings and manifest example

DESCRIPTION: V4-specific settings you can control in manifest.json:
- stickyMultiTabHeader: set to false to hide icon tab bar on scroll.
- views[].visible: controls visibility. Accepts:
  - Boolean
  - a path (to a singleton or record)
  - a binding expression (see Expression Binding)
- You can set view-specific contextPath and annotationPath per view.
- Use controller extensions for custom view behavior if needed.
- Use ListReport ExtensionAPI methods to control refresh behavior:
  - setTabContentToBeRefreshedOnNextOpening
  - refreshTabsCount

LANGUAGE: JSON

CODE:
```json
"targets": {
     "DraftList": {
          "type": "Component",
          "id": "DraftList",
          "name": "sap.fe.templates.ListReport",
          "options": {
               "settings": {
                    "contextPath": "/FirstDraft",
                    "variantManagement": "Control",
                    "initialLoad": "Enabled",
                    "stickyMultiTabHeader": false,
                    "views": {
                         "paths": [
                              {
                                   "key": "tab1",
                                   "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#One",
                                   "visible": "{= ${/MySingleton/IsViewAvailable} === true}"
                              },
                              {
                                   "key": "tab2",
                                   "contextPath": "/SecondDraft",
                                   "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#Two"
                              }
                         ]
                    }
               }
               …
          }
     }
}
…
```

STEP: Refresh control (APIs)

DESCRIPTION: Use the following ExtensionAPI methods (ListReport) to control view content and counts:
- setTabContentToBeRefreshedOnNextOpening — mark a tab's content to be refreshed the next time it is opened.
- refreshTabsCount — refresh counts for all views/tabs.
Include these via ListReport extension API in controller extensions.

LANGUAGE: Text

CODE:
```text
ListReport.ExtensionAPI methods:
- setTabContentToBeRefreshedOnNextOpening()
- refreshTabsCount()
Refer to UI5 docs for exact signatures:
https://ui5.sap.com/#/api/sap.fe.templates.ListReport.ExtensionAPI
```

STEP: Expression binding for view visibility

DESCRIPTION: visible property in views accepts binding expressions. Use Expression Binding syntax to evaluate visibility at runtime. See Expression Binding docs for syntax and examples.

LANGUAGE: Text

CODE:
```text
Example visible binding (in manifest.json):
"visible": "{= ${/MySingleton/IsViewAvailable} === true}"
Docs: ../04_Essentials/expression-binding-daf6852.md
```

STEP: Add multiple views using SAP Fiori Tools (UI steps)

DESCRIPTION: Use SAP Fiori Tools Page Map / Page Editor to add views without editing JSON manually. Actionable UI steps:
1. Open Page Map (e.g., right-click project folder → Show Page Map).
2. Open Page Editor for your List Report (click pencil/edit icon next to List Report).
3. Click Add (+) next to Views.
4. Click Add Table View.
5. Select an Entity.
6. Click Add.
7. Expand new table view node.
8. Click Add (+) next to Columns.
9. Click Add Basic Columns.
10. Select columns to include.
11. Click Add.
12. Click the new view node.
13. Set View Label to rename view.
14. Preview via Previewing an Application.

LANGUAGE: Text

CODE:
```text
UI Steps (Fiori Tools):
- Page Map -> Page Editor -> Views -> Add Table View -> select Entity -> Add
- Expand view -> Columns -> Add Basic Columns -> select columns -> Add
- Edit View Label -> Preview app
```

STEP: Controller extension for custom views

DESCRIPTION: To implement advanced/custom view behavior programmatically, implement a controller extension and use extension points for views. See the extension points documentation.

LANGUAGE: Text

CODE:
```text
Use Extension Points:
- Extension Points for Views in the List Report: extension-points-for-views-in-the-list-report-eb37203.md
Implement ListReport controller extension to inject custom view definitions or custom tab behavior.
```

STEP: Assets, images, and linked resources (paths)

DESCRIPTION: Preserve and reference the following resources in your project:
- CSS icons: ../css/sap-icons.css
- Image assets used in documentation (for design/reference):
  - images/Single_Table_Mode_8a3bdfd.jpg
  - images/Multiple_Table_Mode_1be5a97.png
  - images/Multiple_Table_Mode_with_Charts_a0ae409.png
  - images/Multiple_Views_with_Multiple_Entity_Sets_1f20511.png

LANGUAGE: HTML

CODE:
```html
<link rel="stylesheet" type="text/css" href="../css/sap-icons.css"/>
```

STEP: References and related docs

DESCRIPTION: Keep these links for exact implementation details and vocabulary:
- OData annotation vocabulary (UI): https://github.com/SAP/odata-vocabularies/blob/main/vocabularies/UI.md
- Expression Binding: ../04_Essentials/expression-binding-daf6852.md
- Defining Multiple Views — Single Table Mode: defining-multiple-views-on-a-list-report-table-single-table-mode-0d390fe.md
- Defining Multiple Views — Multiple Table Mode: defining-multiple-views-on-a-list-report-table-multiple-table-mode-37aeed7.md
- Different Entity Sets & Table Settings: defining-multiple-views-on-a-list-report-with-different-entity-sets-and-table-settings-b6b59e4.md
- Extension Points for Views: extension-points-for-views-in-the-list-report-eb37203.md

LANGUAGE: Text

CODE:
```text
Key docs:
- OData UI vocabulary: https://github.com/SAP/odata-vocabularies/blob/main/vocabularies/UI.md
- List Report views: see related md files listed above.
```

fiori-elements-framework list-report views variant-management manifest.json annotations SelectionVariant SelectionPresentationVariant PresentationVariant ODataV4 ODataV2


**TITLE**: Outbound Navigation for SAP Fiori Elements (URLs & Intent-Based Navigation)

**INTRODUCTION**: Practical, code-focused reference for configuring outbound navigation in SAP Fiori Elements (OData V2/V4). Covers using URLs, intent-based navigation (semantic objects) via links and buttons, semantic object mapping, control of navigation availability, exclusion of sensitive fields from navigation context, multi-entity-set/tab resolution, and SelectionVariant parameter passing. Use these snippets directly in XML annotations, ABAP CDS, CAP CDS, manifest.json, and extension controllers.

**TAGS**: fiori-elements, navigation, semantic-object, DataFieldWithUrl, DataFieldWithIntentBasedNavigation, DataFieldForIntentBasedNavigation, annotations, manifest.json, selectionvariant, CAP, ABAP, XML, JavaScript

STEP: Using a URL (path reference to a property)
DESCRIPTION: Use UI.DataFieldWithUrl to render a link where Url and Value are taken from a property path.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldWithUrl">
    <PropertyValue Property="Label" String="Column label" />
    <PropertyValue Property="Value" Path="URL"/>
    <PropertyValue Property="Url" Path="URL"/>
</Record>
```

STEP: Using a URL (ABAP CDS example - path reference)
DESCRIPTION: ABAP CDS annotation to define a line-item/fieldGroup entry using a URL property.
LANGUAGE: ABAP CDS
CODE:
```
@UI.<lineItem/fieldGroup>: [{ type: #WITH_URL, url: 'URL' }]
URL;
```

STEP: Using a URL (CAP CDS example - path reference)
DESCRIPTION: CAP CDS JSON-style annotation for UI.DataFieldWithUrl using a property reference.
LANGUAGE: CAP CDS
CODE:
```
{
    $Type :  'UI.DataFieldWithUrl',
    Value :  URL,
    Url :    URL,
    Label :  'Column label'
},
```

STEP: Using a URL (absolute URL in XML)
DESCRIPTION: Define an absolute link target via UI.DataFieldWithUrl (hard-coded URL).
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldWithUrl">
    <PropertyValue Property="Url" String="Your URL"/><!--For example: https://www.sap.com-->
    <PropertyValue Property="Value" Path="URL"/>
    <PropertyValue Property="Label" String="Company"/>
</Record>
```

STEP: Using a URL (absolute URL in ABAP CDS)
DESCRIPTION: ABAP CDS structure for an absolute URL.
LANGUAGE: ABAP CDS
CODE:
```
{
    label: 'Company',
    type: #WITH_URL,
    url: 'Your URL' //For example: https://sap.com
}
```

STEP: Using a URL (absolute URL in CAP CDS)
DESCRIPTION: CAP CDS JSON-style element for an absolute URL.
LANGUAGE: CAP CDS
CODE:
```
{
    $Type : 'UI.DataFieldWithUrl',
    Url :   'Your URL', //For example: https://www.sap.com
    Value : 'URL',
    Label : 'Company'
}
```

STEP: Link control rendering restriction (note)
DESCRIPTION: In SAP Fiori Elements for OData V2, link control is rendered only in display mode.

STEP: Intent-Based Navigation — Global Semantic Object (XML)
DESCRIPTION: Annotate a property globally with Common.SemanticObject so it is rendered as a semantic link wherever used.
LANGUAGE: XML
CODE:
```xml
<Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item/CostCenter">
    <Annotation Term="com.sap.vocabularies.Common.v1.SemanticObject" String="CostCenter"/>
</Annotations>
```

STEP: Intent-Based Navigation — Global Semantic Object (ABAP CDS)
DESCRIPTION: ABAP CDS annotate view property with Consumption.semanticObject.
LANGUAGE: ABAP CDS
CODE:
```
annotate view ITEM with {
    @Consumption.semanticObject: 'CostCenter'
    costcenter;
}
```

STEP: Intent-Based Navigation — Global Semantic Object (CAP CDS)
DESCRIPTION: CAP CDS annotate with Common.SemanticObject in a service/entity context.
LANGUAGE: CAP CDS
CODE:
```
annotate ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item with {
    @Common.SemanticObject : 'CostCenter'
    CostCenter
};
```

STEP: Dynamic semantic object (XML)
DESCRIPTION: Use a Path in Common.SemanticObject to resolve the semantic object name at runtime.
LANGUAGE: XML
CODE:
```xml
<Annotations Target="myService.SalesorderManage/SoldToParty">
   <Annotation Term="Common.SemanticObject" Path="solToPartySemanticObject"/>
</Annotations>
```

STEP: Dynamic semantic object (CAP CDS)
DESCRIPTION: CAP CDS example where a property contains the semantic object name at runtime.
LANGUAGE: CAP CDS
CODE:
```
SoldToParty: String(10) @(
 Common.SemanticObject: solToPartySemanticObject
);
```

STEP: Local association — DataFieldWithIntentBasedNavigation (XML)
DESCRIPTION: Use DataFieldWithIntentBasedNavigation in LineItem/FieldGroup to render a context-specific link. Specify SemanticObject + Action to create a unique target for direct navigation.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldWithIntentBasedNavigation">
    <PropertyValue Property="Label" String="My Link for navigation" />
    <PropertyValue Property="Value" Path="SomePath" />
    <PropertyValue Property="SemanticObject" String="MySemanticObject"/>
    <PropertyValue Property="Action" String="manage"/>
</Record>
```

STEP: Local association — DataFieldWithIntentBasedNavigation (ABAP CDS)
DESCRIPTION: ABAP CDS example for local intent-based link in a lineItem/fieldGroup.
LANGUAGE: ABAP CDS
CODE:
```
@UI.<lineItem/fieldGroup>: [
  {
    label: 'My Link for navigation',
    value: 'SOMEPATH',
    semanticObjectAction: 'manage',
    type: #WITH_INTENT_BASED_NAVIGATION
  }
]
@Consumption.semanticObject: 'MySemanticObject'
```

STEP: Local association — DataFieldWithIntentBasedNavigation (CAP CDS)
DESCRIPTION: CAP CDS representation for DataFieldWithIntentBasedNavigation.
LANGUAGE: CAP CDS
CODE:
```
    {
        $Type : 'UI.DataFieldWithIntentBasedNavigation',
        Label : 'My Link for navigation',
        Value : SomePath,
        SemanticObject : 'MySemanticObject',
        Action : 'manage',
    },
```

STEP: Button-based navigation — DataFieldForIntentBasedNavigation (XML)
DESCRIPTION: Annotate a property as DataFieldForIntentBasedNavigation to render a button that triggers intent-based navigation. Provide SemanticObject and Action.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldForIntentBasedNavigation">
    <PropertyValue Property="Label" String="My Button for navigation"/>
    <PropertyValue Property="SemanticObject" String="MySemanticObject"/>
    <PropertyValue Property="Action" String="manage"/>
</Record>
```

STEP: Button-based navigation — DataFieldForIntentBasedNavigation (ABAP CDS)
DESCRIPTION: ABAP CDS example for a header/table button.
LANGUAGE: ABAP CDS
CODE:
```
@UI.<lineItem/fieldGroup>: [
  {
    label: 'My Button for navigation',
    semanticObjectAction: 'manage',
    type: #FOR_INTENT_BASED_NAVIGATION
  }
]
@Consumption.semanticObject: 'MySemanticObject'
```

STEP: Button-based navigation — DataFieldForIntentBasedNavigation (CAP CDS)
DESCRIPTION: CAP CDS JSON-style definition for a navigation button.
LANGUAGE: CAP CDS
CODE:
```
{
    $Type : 'UI.DataFieldForIntentBasedNavigation',
    Label : 'My Button for navigation',
    SemanticObject : 'MySemanticObject',
    Action : 'manage',
},
```

STEP: Actions triggering external navigation — RequiresContext (XML)
DESCRIPTION: Use RequiresContext Bool="true" to make the button disabled until a selection is made. Default is false.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldForIntentBasedNavigation">
   <PropertyValue Property="SemanticObject" String="EPMProduct"/>
   <PropertyValue Property="Action" String="manage_st"/>
   <PropertyValue Property="Label" String="IBNWithContext"/>
   <PropertyValue Property="RequiresContext" Bool="true"/>
</Record>
```

STEP: Actions triggering external navigation — RequiresContext (ABAP CDS)
DESCRIPTION: ABAP CDS equivalent specifying requiresContext true.
LANGUAGE: ABAP CDS
CODE:
```
{
    semanticObject: 'EPMProduct',
    semanticObjectAction: 'manage_st',
    label: 'IBNWithContext',
    requiresContext: true,
    type: #FOR_INTENT_BASED_NAVIGATION
}
```

STEP: Actions triggering external navigation — RequiresContext (CAP CDS)
DESCRIPTION: CAP CDS example for DataFieldForIntentBasedNavigation with RequiresContext.
LANGUAGE: CAP CDS
CODE:
```
{
   $Type: 'UI.DataFieldForIntentBasedNavigation',
   SemanticObject: 'SalesOrder',
   Action: 'manageInline',
   Label: 'IBNwithcontext',
   RequiresContext: true
}
```

STEP: Display/hide context-independent buttons (note + prerequisites)
DESCRIPTION: Context-independent buttons (RequiresContext=false) can be displayed only if the FLP navigation target is supported on current device and mandatory parameters are consistent between FLP target configuration and RequiresContext. Maintain supported devices and mandatory parameters in SAP Fiori launchpad.

STEP: Hide intent-based navigation button with UI.Hidden
DESCRIPTION: Use UI.Hidden (true/false/path) on UI.DataFieldForIntentBasedNavigation to hide the button. UI.Hidden cannot be set for inline DataFieldForIntentBasedNavigation.

STEP: Semantic Object Mapping — semantic-link mapping (XML)
DESCRIPTION: Use Common.SemanticObjectMapping to translate source property names into SemanticObjectProperty names for link-based navigation.
LANGUAGE: XML
CODE:
```xml
<Annotations Target="com.c_salesordermanage_sd.defaultParamsForSalesOrderCreate/SoldToParty">
     <Annotation Term="Common.SemanticObject" String="Customer"/>
     <Annotation Term="Common.SemanticObjectMapping">
          <Collection>
               <Record Type="Common.SemanticObjectMappingType">
                    <PropertyValue Property="LocalProperty" PropertyPath="SoldToPartyID"/>
                    <PropertyValue Property="SemanticObjectProperty" String="CustomerID"/>
               </Record>
          </Collection>
     </Annotation>
</Annotations>
```

STEP: Semantic Object Mapping — CAP CDS (link-based)
DESCRIPTION: CAP CDS adaptation using Common.SemanticObjectMapping with LocalProperty -> SemanticObjectProperty.
LANGUAGE: CAP CDS
CODE:
```
SoldToParty : String(10) @(Common : {
    SemanticObject                : 'Customer',
    SemanticObjectMapping         : 'SoldToPartyID'[
        {
        LocalProperty           : SoldToPartyID,
        SemanticObjectProperty  : 'CustomerID'
        }
    ]
});
```

STEP: Excluding properties from navigation context (sensitive and explicit exclusion) (XML)
DESCRIPTION: Use PersonalData.IsPotentiallySensitive or UI.ExcludeFromNavigationContext in XML annotations to exclude properties from navigation context.
LANGUAGE: XML
CODE:
```xml
<Annotations Target="ZEPM_C_User.C_UserDetailsType/CreditCardNumber">
    <Annotation Term="com.sap.vocabularies.PersonalData.v1.IsPotentiallySensitive" />
</Annotations>

<Annotations Target="ZEPM_C_SALESORDERITEMQUERY_CDS.ZEPM_C_SALESORDERITEMKPIResult/BusinessPartner">
    <Annotation Term="UI.ExcludeFromNavigationContext />
</Annotations>
```

STEP: Excluding properties (ABAP CDS sensitive example)
DESCRIPTION: ABAP CDS annotate property as potentially sensitive to exclude it.
LANGUAGE: ABAP CDS
CODE:
```
annotate view C_UserDetails with {
  @Semantics.personalData.isPotentiallySensitive: true
  CreditCardNumber;
}
```

STEP: Excluding properties (CAP CDS)
DESCRIPTION: CAP CDS annotation for IsPotentiallySensitive and UI.ExcludeFromNavigationContext.
LANGUAGE: CAP CDS
CODE:
```
annotate com.c_salesordermanage_sd.SalesOrderManage {
    @PersonalData.IsPotentiallySensitive
    ID
};

annotate com.c_salesordermanage_sd.SalesOrderManage {
    @UI.ExcludeFromNavigationContext : true
    ID
};
```

STEP: Inapplicable properties — FieldControl (XML)
DESCRIPTION: Use FieldControl with a path reference. If the FieldControl resolves to Inapplicable at runtime, property is excluded.
LANGUAGE: XML
CODE:
```xml
<Annotations Target="SAP__self.ReviewsType/AvailabilityCode">
    <Annotation Term=" SAP__Common.FieldControl" Path="__FieldControl/AvailabilityCode_FC"/>
</Annotations>
```

STEP: Inapplicable properties — CAP CDS FieldControl
DESCRIPTION: CAP CDS mapping of FieldControl to property.
LANGUAGE: CAP CDS
CODE:
```
annotate SAP__self.ReviewsType {
    @Common.FieldControl : __FieldControl.AvailabilityCode_FC
    AvailabilityCode
};
```

STEP: Handling sensitive/inapplicable data (OData V4 note)
DESCRIPTION: Measures, PersonalData.IsPotentiallySensitive, UI.ExcludeFromNavigationContext, and FieldControl->Inapplicable values are removed from outbound navigation context. Sensitive properties beyond one level are not removed (caution).

STEP: Handling navigation entity set rules (summary)
DESCRIPTION: Rules for constructing merged navigation context:
- If a property name appears in only one entity set, pass as propertyName:value (no prefix).
- If property name exists in multiple entity sets (conflict), pass unprefixed property plus prefixed entitySet.propertyName entries.
- Page context vs selection context: more specific context values (e.g., selected row) take precedence; navigation entity sets’ properties are ignored for page-level context merging.
- Special handling for semantic link: when a semantic-link field is clicked, its value for that technical name is used and other values with same name are ignored.

STEP: Example scenarios for merged context (explanatory)
DESCRIPTION: See original scenarios showing how OrderType, Price, ItemNumber values are chosen and how prefixed versions are included in case of conflict. (Retain the described logic when implementing.)

STEP: Passing of parameters in an outbound context (SelectionVariant behavior)
DESCRIPTION: All parameters part of context are added into the xAppState SelectionVariant twice:
- SelectionVariant→SelectOptions with prefix "$Parameter.<ParamName>"
- SelectionVariant→SelectOptions with plain "<ParamName>"
This applies to both V2 and V4 outbound navigation.

STEP: Mapping Semantic Objects for DataFieldForIntentBasedNavigation (XML)
DESCRIPTION: Use Mapping property in DataFieldForIntentBasedNavigation to map source properties to semantic-object parameter names sent to target.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldForIntentBasedNavigation">
   ...
    <PropertyValue Property="Mapping">
        <Collection>
            <Record>
                <PropertyValue Property="LocalProperty" PropertyPath="nameOfSourceProperty"/>
                <PropertyValue Property="SemanticObjectProperty" String="nameOfTargetProperty"/>
            </Record>
            ...
        </Collection>
    </PropertyValue>
</Record>
```

STEP: Mapping Semantic Objects for DataFieldForIntentBasedNavigation (ABAP CDS)
DESCRIPTION: ABAP CDS representation of semantic object binding mapping for a navigation button.
LANGUAGE: ABAP CDS
CODE:
```
{
      type: #FOR_INTENT_BASED_NAVIGATION,
      semanticObject: 'nameOfSemanticObject',
      semanticObjectAction: 'nameOfSemanticObjectAction',
      semanticObjectBinding: [
       {
        localElement: 'nameOfSourceProperty',
        element: 'nameOfTargetProperty',
      }
   ]
}
```

STEP: Mapping Semantic Objects for DataFieldForIntentBasedNavigation (CAP CDS)
DESCRIPTION: CAP CDS Mapping array for DataFieldForIntentBasedNavigation.
LANGUAGE: CAP CDS
CODE:
```
{
     $Type : 'UI.DataFieldForIntentBasedNavigation',
     Mapping : [
         {
             LocalProperty : nameOfSourceProperty,
             SemanticObjectProperty : 'nameOfTargetProperty',
         },
     ],
},
```

STEP: Empty values handling
DESCRIPTION: Empty values are not passed to the target unless the filter bar Define Conditions sets them explicitly.

STEP: LinkTarget for DataFieldWithUrl (XML with edmx reference)
DESCRIPTION: Use com.sap.vocabularies.HTML5.v1.LinkTarget to specify _self/_blank/_parent/_top for opening window/tab/frame. Include edmx reference for HTML5 vocabulary.
LANGUAGE: XML
CODE:
```xml
<edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/HTML5.xml">
      <edmx:Include Namespace="com.sap.vocabularies.HTML5.v1" Alias="SAP__HTML5"/>
</edmx:Reference>

<Record Type="UI.DataFieldWithUrl">
  <PropertyValue Property="Label" String="FLP version 6"/>
  <PropertyValue Property="Url" String="http://www.example.com"/>
  <PropertyValue Property="Value" String="Link Target"/>
  <Annotation Term="HTML5.LinkTarget" String="_blank"/>
</Record>
```

STEP: LinkTarget for DataFieldWithUrl (CAP CDS)
DESCRIPTION: CAP CDS using HTML5.LinkTarget (note: local XML preferred for ABAP).
LANGUAGE: CAP CDS
CODE:
```
{
  $Type               : 'UI.DataFieldWithUrl',
  Label               : 'FLP version 6',
  Url                 : 'http://www.example.com',
  Value               : 'Link Target',
  ![@HTML5.LinkTarget]: '_blank',
}
```

STEP: NavigationAvailable property for DataFieldForIntentBasedNavigation (XML)
DESCRIPTION: Use NavigationAvailable (true/false/path) to enable/disable a navigation button. Path can point to parent, same-level property, or 1:1 nav property. For table toolbar with path, button enabled only if at least one selected context has path evaluating to true.
LANGUAGE: XML
CODE:
```xml
<Record Type="UI.DataFieldForIntentBasedNavigation">
    <PropertyValue Property="SemanticObject" String="v4Freestyle"/>
    <PropertyValue Property="Action" String="Inbound"/>
    <PropertyValue Property="Label" String="IBN with context"/>
    <PropertyValue Property="RequiresContext" Bool="true"/>
    <PropertyValue Property="NavigationAvailable" Path="isDeletable"/>
</Record>
```

STEP: NavigationAvailable property for DataFieldForIntentBasedNavigation (CAP CDS)
DESCRIPTION: CAP CDS example using a path property for NavigationAvailable.
LANGUAGE: CAP CDS
CODE:
```
{
        $Type           : 'UI.DataFieldForIntentBasedNavigation',
        SemanticObject  : 'v4Freestyle',
        Action          : 'Inbound',
        Label           : 'IBN',
        NavigationAvailable : isDeletable,
        RequiresContext : false
}
```

STEP: Hiding unwanted actions from a semantic object (XML)
DESCRIPTION: Use Common.SemanticObjectUnavailableActions (with optional qualifier) to hide specific actions from the semantic link popover.
LANGUAGE: XML
CODE:
```xml
<Annotations Target="MyService.SalesOrderManage/SoldToParty">
    <Annotation Term="Common.SemanticObject" Qualifier="SalesOrder" String="SalesOrder"/>
    <Annotation Term="Common.SemanticObjectMapping" Qualifier="SalesOrder">
        <Collection>
            <Record Type="Common.SemanticObjectMappingType">
                <PropertyValue Property="LocalProperty" PropertyPath="SoldToParty"/>
                    <PropertyValue Property="SemanticObjectProperty" String="SoldToParty"/>
            </Record>
        </Collection>
    </Annotation>
    ...
    <Annotation Term="Common.SemanticObjectUnavailableActions" Qualifier="SalesOrder">
        <Collection>
            <String>manageVM</String>
        </Collection>
    </Annotation>
    <Annotation Term="Common.SemanticObjectUnavailableActions">
        <Collection>
            <String>manage</String>
        </Collection>
    </Annotation>
    ...
</Annotations>
```

STEP: Hiding unwanted actions (CAP CDS)
DESCRIPTION: CAP CDS notation to hide actions with and without qualifier.
LANGUAGE: CAP CDS
CODE:
```
annotate myService.SalesorderManage {
    @Common.SemanticObject : 'SalesOrder'
    @Common.SemanticObject #SalesOrder : 'SalesOrder'
    @Common.SemanticObjectUnavailableActions #SalesOrder : ['analyze']
    @Common.SemanticObjectUnavailableActions : ['manage']
    OrderID
};
```

STEP: Additional context during outbound navigation — SemanticKey & SecondaryKey (XML)
DESCRIPTION: Add Common.SemanticKey and Common.SecondaryKey annotations to include semantic/secondary keys into the navigation context. Example shows SecondaryKey on an EntityType.
LANGUAGE: XML
CODE:
```xml
<edmx:Reference Uri="https://sap.github.io/odata-vocabularies/vocabularies/Common.xml">
	<edmx:Include Alias="Common" Namespace="com.sap.vocabularies.Common.v1" />
</edmx:Reference>
...
<EntityType Name="Product">
   <Key>
       <PropertyRef Name="ProductId"/>
   </Key>
   <Property Name="ProductId" Type="Edm.Int32" Nullable="false"/>
   <Property Name="ProductCode" Type="Edm.String" Nullable="false"/>
   <Property Name="ProductName" Type="Edm.String" Nullable="false"/>

   <!-- Secondary key annotation -->
   <Annotations>
       <Annotation Term="Common.SecondaryKey">
           <Collection>
                 <PropertyPath>ProductCode</PropertyPath>
           </Collection>
       </Annotation>
   </Annotations>
</EntityType>
```

STEP: Additional context — SemanticKey (snippet)
DESCRIPTION: Example fragment defining SemanticKey in JSON-like notation.
LANGUAGE: JSON
CODE:
```
Common: {
        SemanticKey   : [SalesOrder]
    }
```

STEP: Additional context — CAP CDS for SecondaryKey
DESCRIPTION: CAP CDS example adding Common.SecondaryKey.
LANGUAGE: CAP CDS
CODE:
```
annotate c_salesordermanage_sd.Product with @(
  Common.SecondaryKey: ['ProductCode']
){}
```

STEP: Multi-Entity Set / Tabs navigation (SAP Fiori Elements V2) — source extensions
DESCRIPTION: For multi-entity target apps, add a distinguishing parameter in the source app using adaptNavigationParameterExtension in the ListReport and ObjectPage extension controllers. This parameter is consumed in the target manifest.json via useForTargetResolution.
LANGUAGE: JavaScript
CODE:
```javascript
// ListReportExtension.controller.js
adaptNavigationParameterExtension: function(oSelectionVariant, oObjectInfo) {
    if (oObjectInfo.semanticObject === "EPMSalesOrder" && oObjectInfo.action === "manage_sttasomv") {
        oSelectionVariant.addParameter("<Key>", "<Value1>");
    }
}
```

```javascript
// ObjectPageExtension.controller.js
adaptNavigationParameterExtension: function(oSelectionVariant, oObjectInfo) {
    if (oObjectInfo.semanticObject === "EPMSalesOrder" && oObjectInfo.action === "manage_sttasomv") {
        oSelectionVariant.addParameter("<Key>", "<Value2>");
    }
}
```

STEP: Multi-Entity Set / Tabs navigation (V2) — manifest.json target resolution
DESCRIPTION: In the target app manifest.json for V2, mark the inbound parameter with useForTargetResolution under sap.ui.generic.app settings to drive page selection.
LANGUAGE: JSON
CODE:
```json
"sap.ui.generic.app": {
        "settings": {
            "inboundParameters": {
                "<Key>": {
                    "useForTargetResolution": true
                }
            }
        }
}
```

STEP: Multi-Entity Set / Tabs navigation (V2) — pages example
DESCRIPTION: Use page hierarchy to map Key->Value to entitySet object pages. Use targetResolution settings per page to match incoming parameter value to the desired object page.
LANGUAGE: JSON
CODE:
```
"sap.ui.generic.app": {
        "pages": {
            "ListReport|<EntitySet1>": {
                "entitySet": "<EntitySet1>",
                "component": {
                    "name": "sap.suite.ui.generic.template.ListReport",
                    "settings": {
                        "quickVariantSelectionX": {
                            "variants": {
                                "1": {
                                    "key": "1",
                                    "entitySet": "<EntitySet1>",
                                    "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#VAR1"
                                },
                                "2": {
                                    "key": "2",
                                    "entitySet": "<EntitySet2>",
                                    "annotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#VAR2"
                                }
                            }
                        }
                    }
                },
                "pages": {
                    "ObjectPage|<EntitySet1>": {
                        "entitySet": "<EntitySet1>",
                        "component": {
                            "name": "sap.suite.ui.generic.template.ObjectPage",
                            "settings": {
                                "targetResolution": {
                                    "<Key>": "<Value1>"
                                }
                            }
                        }
                    },
                    "ObjectPage|<EntitySet2>": {
                        "entitySet": "<EntitySet2>",
                        "component": {
                            "name": "sap.suite.ui.generic.template.ObjectPage",
                            "settings": {
                                "targetResolution": {
                                    "<Key>": "<Value2>"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
```

STEP: Multi-Entity Set / Tabs navigation (SAP Fiori Elements V4) — source adaptNavigationContext
DESCRIPTION: For V4, use adaptNavigationContext in extension controllers to add parameter(s) used as target resolution keys.
LANGUAGE: JavaScript
CODE:
```javascript
// ListReportExtension.controller.js
adaptNavigationContext: function (selectionVariant, targetInfo) {
    if (targetInfo.semanticObject === "SalesOrder" && targetInfo.action === "manage") {
        selectionVariant.addParameter("<Key>", "<Value1>");
    }
}
```

```javascript
// ObjectPageExtension.controller.js
adaptNavigationContext: function (selectionVariant, targetInfo) {
    if (targetInfo.semanticObject === "SalesOrder" && targetInfo.action === "manage") {
        selectionVariant.addParameter("<Key>", "<Value2>");
    }
}
```

STEP: Multi-Entity Set / Tabs navigation (V4) — manifest inboundParameterForTargetResolution
DESCRIPTION: For V4 target app, declare inboundParameterForTargetResolution in sap.fe.app settings in manifest.json.
LANGUAGE: JSON
CODE:
```json
"sap.fe": {
    "app": {
        "inboundParameterForTargetResolution": "<Key>"
    }
}
```

STEP: Multi-Entity Set / Tabs navigation (V4) — routing targetResolutionValue
DESCRIPTION: Use targetResolutionValue in UI5 routing targets to map incoming Key->Value to the right ObjectPage component.
LANGUAGE: JSON
CODE:
```json
"sap.ui5": {
    "routing": {
        "targets": {
            "ObjectPage|<EntitySet1>": {
                "type": "Component",
                "id": "ObjectPage1",
                "name": "sap.fe.templates.ObjectPage",
                "options": {
                    "settings": {
                        "targetResolutionValue": "<Value1>",
                        "entitySet": "<EntitySet1>"
                    }
                }
            },
            "ObjectPage|<EntitySet2>": {
                "type": "Component",
                "id": "ObjectPage2",
                "name": "sap.fe.templates.ObjectPage",
                "options": {
                    "settings": {
                        "targetResolutionValue": "<Value2>",
                        "entitySet": "<EntitySet2>"
                    }
                }
            }
```

STEP: Notes & precedence for multi-entity mapping
DESCRIPTION: creationEntitySet settings take priority over manifest target resolution. If navigation context cannot uniquely identify the target object page, list report opens with first tab selected.

fiori-elements navigation semantic-object DataFieldWithUrl DataFieldWithIntentBasedNavigation DataFieldForIntentBasedNavigation annotations manifest.json selectionvariant CAP ABAP XML JavaScript


**TITLE**: Navigation from Header Facet Title (SAP Fiori elements, OData V4)

**INTRODUCTION**: Configure header facet titles (data points, rating/progress indicators, micro charts) to navigate within the same page (in-page) or to external applications (external navigation) by adding controlConfiguration entries to manifest.json and defining crossNavigation outbounds. Applicable only to SAP Fiori elements for OData V4.

**TAGS**: fiori-elements-framework, OData V4, manifest.json, controlConfiguration, in-page navigation, external navigation, crossNavigation, micro chart, data point

STEP: 1 — Enable In-Page Navigation from Header Item

DESCRIPTION: Add a controlConfiguration entry for the header item in manifest.json to render the header item's title as a link that navigates to a section or subsection in the same page. Provide sectionId and/or subSectionId under navigation.targetSections. If only sectionId is provided, the first subsection is shown. Supported header controls: data point, rating indicator, progress indicator, micro chart. An incorrect configuration shows an error that the specified section could not be found.

LANGUAGE: JSON (manifest.json)

CODE:
```json
"SalesOrderManageObjectPage":{
    "type": "Component",
    "id": "SalesOrderManageObjectPage",
    "name": "sap.fe.templates.ObjectPage",
    "options":{
        "settings":{
            "controlConfiguration":{
                "@com.sap.vocabularies.UI.v1.DataPoint#NetValue":{ // path to the header item
                    "navigation":{
                        "targetSections":{
                            "sectionId": "SalesOrder::SalesOrderManageObjectPage--fe::FacetSection::HeaderInfo", // section ID
                            "subSectionId": "SalesOrder::SalesOrderManageObjectPage--fe::FacetSubSection::SalesOrderHeaderPartner" // subsection ID
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 2 — Enable External Navigation from a Header Data Point (manifest controlConfiguration)

DESCRIPTION: Configure targetOutbound in the header data point's controlConfiguration to navigate externally. The qualifier name given in targetOutbound.outbound must match the outbound key defined under crossNavigation.outbounds. When configured correctly, the data point title is rendered as a link; clicking it launches the external app with a merged page+data-point context.

LANGUAGE: JSON (manifest.json)

CODE:
```
"SalesOrderManageObjectPage" : {
    ....
    ....
    ....
    "options": {
        "settings": {
            "controlConfiguration": {
                "@com.sap.vocabularies.UI.v1.DataPoint#NetValue": {
                    "navigation": {
                        "targetOutbound": {
                            "outbound": "ExternalNavigation"
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 3 — Define the Outbound in crossNavigation (target application and parameter mappings)

DESCRIPTION: Add an outbound entry in the manifest's crossNavigation.outbounds section that matches the qualifier used in targetOutbound. Configure semanticObject, action, and parameter mappings. Use "format": "binding" and "value": {"value": "<field>", "format": "binding"} to pass fields from the current context. The example maps CustomerName to SoldToParty.

LANGUAGE: JSON (manifest.json)

CODE:
```
"crossNavigation": {
    "outbounds": {
        "ExternalNavigation": {
            "semanticObject": "SalesOrder",
            "action": "display",
            "parameters": {
                "SoldToParty": {
                    "value": {
                        "value": "CustomerName",
                        "format": "binding"
                    }
                }
            }
        }
    }
}
```

STEP: 4 — Enable External Navigation from a Micro Chart

DESCRIPTION: Configure the micro chart in controlConfiguration with targetOutbound similar to the data point example. Navigation uses the x-app state: the page context is merged with the chart context and passed to the target application. For 1:n micro charts (multiple records), multiple technical IDs are passed using OR semantics. If the external app is misconfigured or lacks authorization, the chart title is rendered as plain text. Note: if both external and in-page navigation are configured for the same header data point, external navigation takes precedence. Only a single external target is supported.

LANGUAGE: JSON (manifest.json)

CODE:
```
"SalesOrderManageObjectPage" : {
    ....
    ....
    ....
    "options": {
        "settings": {
            "controlConfiguration": {
                "@com.sap.vocabularies.UI.v1.Chart#CreditLimitDetails": {
                    "navigation": {
                        "targetOutbound": {
                            "outbound": "ExternalNavigation"
                        }
                    }
                }
            }
        }
    }
}
```

fiori-elements-framework
OData V4
manifest.json
controlConfiguration
in-page navigation
external navigation
crossNavigation
micro chart
data point


**TITLE**: Inbound Navigation and Deep Linking for SAP Fiori Elements (OData V2 & V4)

**INTRODUCTION**: Action-oriented reference for implementing inbound navigation, deep linking, and incoming filter handling in SAP Fiori elements apps. Includes manifest settings, annotation samples, and special FLP behaviors to enable object- and subobject-level deep links, handle incoming filter values (including navigation entity properties), configure layout behavior for Flexible Column Layout, and apply incoming sort orders.

**TAGS**: fiori-elements-framework, inbound-navigation, deep-linking, manifest.json, ODataV2, ODataV4, semantic-keys, FLP, filters, sort-order, flexible-column-layout

STEP: Handle incoming filters and FLP default values

DESCRIPTION: When a Fiori elements list report or analytical list page receives inbound navigation (except overview pages), incoming context values are applied to matching filter fields and these filter fields are made visible in the filter bar (overriding default or saved variants). FLP target mapping defaults and user default values influence incoming values as follows:
- FLP intent-based navigation: only standard FLP target mapping parameter values are considered.
- Static FLP tile with no nav context: if no user default variant exists, FLP target mapping defaults are applied.
- Dynamic tiles (e.g., SAP Smart Business) with navigation context: special handling for DisplayCurrency:
  - If a mandatory filter or parameter named DisplayCurrency or P_DisplayCurrency is not provided by the incoming context, it is set from the user's FLP default DisplayCurrency.
  - All other FLP default values (from user defaults) are ignored except those provided via standard target mapping.
Note: Applying FLP user default values marks the standard variant as dirty.

LANGUAGE: text

CODE:
```text
Behavior summary:
- Incoming context values -> applied to filter fields (become visible).
- FLP target mapping defaults -> applied depending on tile/navigation type.
- DisplayCurrency special-case for dynamic tiles.
- Applying user default values marks standard variant as dirty.
```

STEP: Deep linking overview (object page vs. list report)

DESCRIPTION: Deep linking opens an object page when the URL supplies all technical keys that uniquely identify an entity record; otherwise the list report/analytical list page opens. Object page selection between draft/active depends on the IsActiveEntity key and user access to drafts.

LANGUAGE: xml

CODE:
```xml
<EntityType Name="SalesOrderManage">
   <Key>
      <PropertyRef Name="ID"/>
      <PropertyRef Name="IsActiveEntity"/>
   </Key>
</EntityType>
```

LANGUAGE: text

CODE:
```text
Example deep link URL (technical keys):
...?ID=11111111-aaaa-bbbb-cccc-ddddeeeeffff&IsActiveEntity=true
```

STEP: Deep linking to subobject pages (OData V2) — manifest allowDeepLinking

DESCRIPTION: To enable direct deep linking to a subobject page in OData V2 apps, set allowDeepLinking: true in the target subobject page manifest entry. To deep link to the n-th level, allowDeepLinking must be true for all levels from object page through the n-th subobject page. If multiple pages on the same level have allowDeepLinking:true, the first entry in the manifest is used. Applications configured with parameters or mandatory filters do not support deep linking.

LANGUAGE: json

CODE:
```json
"pages": {
     "navigationProperty": "to_ProductText",
     "entitySet": "STTA_C_MP_ProductText",
     "component": {
          "name": "sap.suite.ui.generic.template.ObjectPage",
          "settings": {
               "allowDeepLinking": true
          }
     }
}
```

LANGUAGE: text

CODE:
```text
Nested example (conceptual):
Object Page1: {
     allowDeepLinking:true,
     SubObjectPage1:{
          allowDeepLinking:true
          SubObjectPage2:{
               allowDeepLinking:true
               SubObjectPage3:{
                    allowDeepLinking:true
               }
          }
     }
}
```

STEP: Configure inbound sort order from xapp-state

DESCRIPTION: If the xapp-state carries sort orders during inbound navigation, the target framework:
- Reads sort parameters from xapp-state and applies them to the table.
- Merges incoming sorters with existing sort criteria; incoming sorters take priority.
Priority merging examples:
- If a default user variant exists with sorter(s): navigation sorter (priority) then variant sorter.
- Else, if PresentationVariant annotation exists: navigation sorter then PresentationVariant sorter.
- Else: only navigation sorter(s) applied.

LANGUAGE: text

CODE:
```text
Sort priority: incoming xapp-state -> user variant sorters -> PresentationVariant -> none.
```

STEP: Flexible Column Layout (FCL) — enable fullscreen on inbound navigation

DESCRIPTION: For FCL apps, to open an object in fullscreen when inbound navigation resolves to a unique object, set defaultLayoutTypeIfExternalNavigation to appropriate values for main and subobjects (e.g., MidColumnFullScreen / EndColumnFullScreen). If navigation is external and FCL is enabled, defaultLayoutTypeIfExternalNavigation is used; if launched from FLP, defaultLayout is considered.

LANGUAGE: json

CODE:
```json
"pages": {
    "ObjectPage|C_STTA_BusinessPartner": {
        "entitySet": "C_STTA_BusinessPartner",
        "defaultLayoutType": "TwoColumnsMidExpanded",
        "defaultLayoutTypeIfExternalNavigation": "MidColumnFullScreen",
        "component": {
            "name": "sap.suite.ui.generic.template.ObjectPage"
             "settings':{"allowDeepLinking": true
        }
    },
    "pages": {
.....
```

STEP: OData V4 — semantic keys for deep linking to object pages

DESCRIPTION: For OData V4, deep linking can be triggered by passing semantic keys (defined by annotations or CDS) for the list report entity set. If a draft exists for the user, the draft instance is loaded; otherwise the active object is loaded. When both semantic and technical keys are present, semantic keys take priority. Ensure manifest routing contains the key pattern for the desired level.

LANGUAGE: xml

CODE:
```xml
<Annotation Term="Common.SemanticKey">
   <Collection>
      <PropertyPath>SalesOrder</PropertyPath>
   </Collection>
</Annotation>
```

LANGUAGE: text

CODE:
```text
ABAP CDS sample:
@ObjectModel: {
  semanticKey: [ 'SalesOrder' ]
}

define view SALESORDERMANAGE {

}
```

LANGUAGE: text

CODE:
```text
CAP CDS sample:
Common.SemanticKey : [
    SalesOrder
]
```

STEP: OData V4 — manifest routing sample for object deep link

DESCRIPTION: Manifest route pattern must expose the key placeholder for object-level deep linking. Example route with pattern /yourEntity({key}) and a target component configured for ObjectPage.

LANGUAGE: json

CODE:
```json
{
...
        "routing": {
            "routes": [
                {
                    "pattern": "/yourEntity({key}):?query:",
                    "name": "default",
                    "target": "sample"
                }
            ],
            "targets": {
                "sample": {
                    "type": "Component",
                    "id": "Default",
                    "name": "sap.fe.templates.ObjectPage",
                    "level": 1,
                    "options": {
                        "settings": {
                            "contextPath": "/yourEntity"
                        }
                    }
                }
            }
        },
...
}
```

LANGUAGE: text

CODE:
```text
Example semantic key URL:
...?SalesOrder=10025
```

STEP: OData V4 — inbound deep linking to subobject pages (manifest)

DESCRIPTION: To enable deep linking to a subobject page in OData V4, set allowDeepLinking:true in the component entry for the subobject page in manifest.json. To load the n-th-level subobject page directly, include the object page semantic/technical keys plus all semantic keys for each subobject level up to n in the URL. Ensure semantic key names are unique across different entity sets to avoid ambiguity.

LANGUAGE: json

CODE:
```json
"SalesOrderManageObjectPage":{
     "type":"Component",
     "id":"SalesOrderManageObjectPage",
     "name":"sap.fe.templates.ObjectPage",
     "options":{
          "settings":{
               "contextPath":"/SalesOrderManage",
               "allowDeepLinking":true,
               ....
               ...
          }
     }
}
```

STEP: Handling incoming filters for navigation entity set properties (qualified names & P_ prefix)

DESCRIPTION: Incoming filter values with fully qualified names like "EntityNav._SubNav.Prop" are applied to the corresponding filter fields in the target app. Matching rules:
- Exact match against fully qualified property name in the target.
- Or match after discarding the leading entity set name from the incoming context.
- Also consider P_ prefix: if incoming field is "X" and target filter is "P_X", apply accordingly (prefix added or removed).
Follow this matching order when multiple possible matches exist.

LANGUAGE: text

CODE:
```text
Example incoming context: "SO._PO.Status"

Matching order applied by Fiori elements:
1) Target main entity set "SO" with navigation entity "_PO" that has "Status" filter field.
2) Target has first-level navigation entity "SO" that has a further navigation entity "_PO" with "Status" filter field.

Prefix handling:
- Incoming "Status" may match target "P_Status" (or vice versa).
```

STEP: Restrictions and notes

DESCRIPTION: Key constraints and behavior summary for implementers:
- Deep linking unsupported for apps configured with parameters or mandatory filters.
- allowDeepLinking is only required for subobject pages; object pages always deep link when URL contains all required keys.
- For FLP deep linking, ensure intent-based navigation configuration (FLP target mapping) is set up.
- When using tiles or dynamic navigation that provide context, account for special DisplayCurrency handling.

LANGUAGE: text

CODE:
```text
Restrictions:
- No deep linking for apps with mandatory filters or parameters.
- allowDeepLinking: required for each subobject level to deep link directly to that level.
- FLP configuration (target mapping) influences inbound defaults.
```

fiori-elements-framework inbound-navigation deep-linking manifest.json ODataV2 ODataV4 semantic-keys FLP filters sort-order flexible-column-layout


**TITLE**: Configure Navigation to an Object Page in Edit Mode (SAP Fiori Elements)

**INTRODUCTION**: This document shows manifest.json settings to make object pages open directly in edit mode for SAP Fiori Elements apps. It covers OData V2 (editFlow + navToListOnSave) and OData V4 (openInEditMode). Use these settings in the app manifest to control navigation and post-save behavior.

**TAGS**: fiori-elements-framework, sap, odata-v2, odata-v4, manifest.json, edit mode, editFlow, openInEditMode, navToListOnSave

STEP: 1 — OData V2 — Enable direct edit navigation from List Report

DESCRIPTION: Set editFlow to "direct" in the manifest.json for the ListReport page to open the target Object Page directly in edit mode when navigating from the list report. Place this under your ListReport page entry in sap.ui.generic.app -> pages.

LANGUAGE: JSON

CODE:
```json
"ListReport|STTA_C_MP_Product": {
                "entitySet": "STTA_C_MP_Product",
                "component": {
                    "name": "sap.suite.ui.generic.template.ListReport",
                    "settings": {
                        "editFlow":"direct"
		….
	               }
                }
}
```

STEP: 2 — OData V2 — Control post-save navigation on the Object Page

DESCRIPTION: Prevent navigation back to the list after Save by setting navToListOnSave to false on the ObjectPage page entry in manifest.json. When set to false, after the user saves, the object page stays visible and switches to display mode instead of navigating to the list.

LANGUAGE: JSON

CODE:
```json
"pages": {
        "ObjectPage|STTA_C_MP_Product": {
            "entitySet": "STTA_C_MP_Product",
            "component": {
                "name": "sap.suite.ui.generic.template.ObjectPage",
                "settings": {
                    "navToListOnSave": false

                            }
                        }
                    }….
```

STEP: 3 — OData V2 — UI behavior when direct edit is enabled

DESCRIPTION: When editFlow = "direct" is configured, the Object Page footer adds a "Save and Next" button alongside "Save" and "Cancel". "Save and Next" saves current changes then opens the next object in edit mode. "Save" behavior depends on navToListOnSave (true by default navigates to list; false keeps the page and switches to display mode).

LANGUAGE: Text

CODE:
```text
UI behavior summary:
- editFlow: "direct"  => Object Page opens in edit mode and footer includes: Save, Cancel, Save and Next
- "Save and Next"    => saves current changes and opens next object in edit mode
- "Save" with navToListOnSave: true (default) => navigates back to the list report
- "Save" with navToListOnSave: false => stays on the object page and switches to display mode
```

STEP: 4 — OData V4 — Open object page directly in edit mode

DESCRIPTION: For OData V4-based Fiori Elements apps, set openInEditMode to true under the page/table options -> settings in manifest.json to open the target Object Page in edit mode on navigation. Note: when openInEditMode is true, the "Open in New Tab" option is removed from the table's context menu.

LANGUAGE: JSON

CODE:
```json
"options": {
     "settings": {
        "entitySet": "LineItems",
           ...
			"openInEditMode": true
      }
}
```

fiori-elements-framework
sap
odata-v2
odata-v4
manifest.json
edit mode
editFlow
openInEditMode
navToListOnSave


**TITLE**: Navigation to the Next Level (List Report → Object and Subobject Pages)

**INTRODUCTION**: Configure table chevron navigation so users can navigate from a List Report (table of entity set entries) to an Object Page and from an Object Page to a Subobject Page. This document shows the manifest.json target and navigation mappings required for SAP Fiori Elements (OData V4). For OData V2 guidance, see the referenced internal navigation doc.

**TAGS**: fiori-elements-framework, navigation, manifest.json, OData V4, list-report, object-page, subobject-page, chevron

**STEP**: Configure navigation targets and mappings in manifest.json (OData V4)

**DESCRIPTION**: Add targets for the List Report and Object Page components under the manifest.json "targets" section. Define the navigation mapping so the List Report routes to the Object Page (detail) and the Object Page routes to a Subobject Page (detail). Place the mapping under each target's "options" -> "navigation" (for the List Report) and under "options" -> "settings" -> "navigation" (for the Object Page) as shown. Keep route names consistent with your routing configuration.

**LANGUAGE**: JSON

**CODE**:
```json
{
   "targets":{
      "SalesOrderManageList":{
         "type":"Component",
         "id":"SalesOrderManageList",
         "name":"sap.fe.templates.ListReport",
         "options":{
            "settings":{
               "contextPath":"/SalesOrderManage",
               "variantManagement":"Page",
               ...
               ...
            },
            "navigation":{
               "SalesOrderManage":{
                  "detail":{
                     "route":"SalesOrderManageObjectPage"
                  }
               }
            }
         }
      },
      "SalesOrderManageObjectPage":{
         "type":"Component",
         "id":"SalesOrderManageObjectPage",
         "name":"sap.fe.templates.ObjectPage",
         "options":{
            "settings":{
               "contextPath":"/SalesOrderManage",
               "navigation":{
                  "_Item":{
                     "detail":{
                        "route":"SalesOrderItemObjectPage" // For sub object page navigation
                     }
                  }
               },
               "variantManagement":"Control",
               ...
               ...
            }
         }
      }
   }
}
```

**STEP**: Use SAP Fiori Elements OData V2 internal navigation guidance

**DESCRIPTION**: If your app uses OData V2, follow the "Configuring Internal Navigation" guidance specific to OData V2 to enable table chevron navigation from list reports to object pages. This document contains the required annotations and configuration steps for OData V2.

**LANGUAGE**: Text

**CODE**:
```
See: configuring-internal-navigation-2c65f07.md (Configuring Internal Navigation) - follow OData V2 specific steps and annotations for internal navigation.
```

fiori-elements-framework
navigation
manifest.json
OData V4
list-report
object-page
subobject-page
chevron


**TITLE**: Non-Draft Apps (SAP Fiori elements — OData V2)

**INTRODUCTION**: Guidance and actionable code patterns for implementing SAP Fiori elements applications that do not use draft handling (OData V2). Covers when to use non-draft apps, required explicit save behavior, navigation and locking implications, extension-point input parameters and a reusable secured-execution pattern for extension implementations.

**TAGS**: fiori-elements-framework, odata-v2, non-draft, draft-handling, dataloss, navigation, locking, extension-points

**STEP**: 1 — Applicability and basic rules

**DESCRIPTION**: Use non-draft apps only for simple scenarios (no complex multi-object creation flows). Do not mix draft and non-draft entity sets in a single application. Exception: a draft-enabled entity set may contain a non-draft child strictly for display; do not perform actions or external navigation from the non-draft child. Examples: complex flow (creating items and subitems in a single step) — use draft apps; simple flow (occasional edits to specific fields) — non-draft acceptable. Note: This topic applies only to SAP Fiori elements for OData V2.

**LANGUAGE**: PlainText

**CODE**:
```PlainText
Rules:
- Use non-draft apps only for simple, isolated update scenarios.
- Do NOT mix draft and non-draft entity sets in one app.
- Allowed exception: draft parent -> non-draft child only for display (no actions/navigation).
- For combined value/text fields (e.g., currency + amount, text arrangement + unit),
  define a dedicated side-effect so changed values display correctly after save.
```

**STEP**: 2 — Save behavior (explicit save required)

**DESCRIPTION**: Non-draft apps do not auto-save. End users must explicitly save new or modified data before leaving a page. The UI must expose a Save action (e.g., Save button). Before performing navigation that discards changes, check the model for pending changes and show a data-loss confirmation. Use OData V2 model APIs: hasPendingChanges(), submitChanges(), resetChanges(). Provide explicit handlers for Save, Cancel, and navigation to prevent silent data loss.

**LANGUAGE**: JavaScript

**CODE**:
```JavaScript
// Example: Save handler using sap.ui.model.odata.v2.ODataModel
onSavePress: function () {
  const oModel = this.getView().getModel();
  if (oModel.hasPendingChanges()) {
    // submitChanges returns a promise in many implementations; adapt for callback style if needed
    oModel.submitChanges({
      success: function (oData, response) {
        // handle successful save (refresh UI, navigate, show toast)
      },
      error: function (oError) {
        // handle save failure
      }
    });
  }
},

// Example: Before navigation (intercept route/back) — check pending changes and confirm
onBeforeNavigate: function (fnNavigate) {
  const oModel = this.getView().getModel();
  if (oModel.hasPendingChanges()) {
    // Use sap.m.MessageBox or custom dialog to confirm
    sap.m.MessageBox.confirm("You have unsaved changes. Discard changes and continue?", {
      onClose: function (sAction) {
        if (sAction === sap.m.MessageBox.Action.OK) {
          oModel.resetChanges(); // discard
          fnNavigate(); // perform navigation
        } else {
          // keep editing
        }
      }
    });
  } else {
    fnNavigate();
  }
}
```

**STEP**: 3 — Locking and concurrency behavior

**DESCRIPTION**: Non-draft apps do not lock objects during editing. Concurrent edits can lead to lost updates (last save wins). To reduce collisions, consider explicitly refreshing data before entering edit mode to get the latest server state. Decide on a conflict resolution strategy (optimistic concurrency via ETag checking on save is recommended if back end supports it).

**LANGUAGE**: JavaScript

**CODE**:
```JavaScript
// Example: Refresh current entity before starting edit to fetch latest data
onStartEdit: function () {
  const oModel = this.getView().getModel();
  // force a read/refresh from server
  oModel.refresh(true); // true => force update of bindings from server
  // then open edit UI
},

// Example: Submit with ETag concurrency handling (backend must support ETag/If-Match)
// oModel.submitChanges will fail if ETag mismatch; handle error and prompt user to reload/merge
```

**STEP**: 4 — Navigation considerations and user actions that cause data loss

**DESCRIPTION**: In non-draft apps, several system and user actions discard entered but unsaved data. Some actions display a data-loss dialog, others do not. Implement interception where possible and warn users:

- Actions that display a data-loss message: SAP Fiori actions like Back or Home (the framework shows a data-loss message).
- Actions that do NOT display a data-loss message and cause silent data loss: SAP Fiori launchpad sign out, browser back/forward, bookmark, URL change, refresh, close tab/window.

Implement checks on route changes, window.onbeforeunload, and application-specific navigation to warn about unsaved changes. Be aware that some flows (e.g., sign out or browser close) may not allow a friendly confirmation dialog in all environments.

**LANGUAGE**: JavaScript

**CODE**:
```JavaScript
// Example: Intercept browser unload to warn about unsaved changes
window.addEventListener("beforeunload", function (e) {
  const oModel = sap.ui.getCore().getModel(); // or view controller model
  if (oModel && oModel.hasPendingChanges()) {
    // Most browsers show a generic confirmation dialog; setReturnValue for compatibility
    const confirmationMessage = "You have unsaved changes that will be lost.";
    (e || window.event).returnValue = confirmationMessage;
    return confirmationMessage;
  }
  return undefined;
});

// Example: Router attachBeforeRouteMatched or custom nav interceptor
this.getRouter().attachBeforeRouteMatched((oEvent) => {
  this.onBeforeNavigate(() => {
    this.getRouter().navTo(oEvent.getParameter("name"), oEvent.getParameter("arguments"));
  });
});
```

**STEP**: 5 — Extension points and secured execution parameters

**DESCRIPTION**: When adding extension logic (handlers or commands), use a secured-execution pattern that accepts input parameters to control busy state and data-loss handling. The common input parameters are:
- busy.set=true: show busy indicator while function executes; set false for immediate completion.
- busy.check=true: execute function only if app is not already busy. Set false when function is invoked by another function that already set busy.
- dataloss.popup=true: show data-loss confirmation before executing when model has pending changes.
- dataloss.navigation=false: indicate that the function will navigate away (changes the data-loss message wording).

Provide a reusable function to enforce these rules and call the extension logic safely.

**LANGUAGE**: JavaScript

**CODE**:
```JavaScript
// Reusable securedExecution function for extension handlers
securedExecution: function (oParams, fnAction) {
  const oModel = this.getView().getModel();
  const oBusyHelper = this._busyHelper || { setBusy: () => {}, clearBusy: () => {}, isBusy: () => false };

  // busy.check: skip if already busy
  if (oParams.busy && oParams.busy.check === true && oBusyHelper.isBusy()) {
    return; // do not execute while busy
  }

  // dataloss.popup: confirm if pending changes exist
  if (oParams.dataloss && oParams.dataloss.popup === true && oModel.hasPendingChanges()) {
    const sText = oParams.dataloss.navigation === true
      ? "You have unsaved changes. Leaving will discard them. Continue?"
      : "You have unsaved changes. Continue?";
    sap.m.MessageBox.confirm(sText, {
      onClose: (sAction) => {
        if (sAction === sap.m.MessageBox.Action.OK) {
          this._executeWithBusy(oParams, fnAction, oBusyHelper);
        }
      }
    });
    return;
  }

  // No data-loss or no pending changes -> execute immediately
  this._executeWithBusy(oParams, fnAction, oBusyHelper);
},

_executeWithBusy: function (oParams, fnAction, oBusyHelper) {
  try {
    if (oParams.busy && oParams.busy.set === true) {
      oBusyHelper.setBusy(true);
    }
    // Execute the extension logic; allow async/Promise return
    const vResult = fnAction();
    if (vResult && typeof vResult.then === "function") {
      vResult.finally(() => {
        if (oParams.busy && oParams.busy.set === true) {
          oBusyHelper.setBusy(false);
        }
      });
    } else {
      if (oParams.busy && oParams.busy.set === true) {
        oBusyHelper.setBusy(false);
      }
    }
  } catch (e) {
    if (oParams.busy && oParams.busy.set === true) {
      oBusyHelper.setBusy(false);
    }
    throw e;
  }
}
```

**STEP**: 6 — Draft features unavailable in non-draft apps

**DESCRIPTION**: The following capabilities provided by draft apps are not available for non-draft apps. Plan alternatives or avoid scenarios that require these features:

- No automatic no-data-loss protection for connectivity disruption or session time-out.
- No device switch (start on one device and continue on another).
- No start-save-continue-later (save as incomplete).
- No automatic asynchronous saving during entry.
- No navigation within the app without saving in between.
- No action/field control adjustments during data entry.
- No checks during data entry and no actions on entered (unsaved) data.
- No calculations/defaulting while entering data (server-side defaulting only after save).
- No context-dependent value helps based on unsaved entered data.
- No sorting/filtering in editable tables for data entry.

**LANGUAGE**: PlainText

**CODE**:
```PlainText
Unavailable draft features (plan alternatives if needed):
- Offline/no-data-loss handling: implement manual retry/submit strategies.
- Device handover: not supported.
- Continue-later: not supported.
- Auto-save: not supported.
- In-app navigation without saves: avoid or require explicit saves.
- Entry-time actions/defaults/value-helps based on unsaved data: cannot rely on server-side features until saved.
```

fiori-elements-framework odata-v2 non-draft draft-handling dataloss navigation locking extension-points


**TITLE**: Object Page Elements — Implementation Checklist and Examples for Fiori Elements

**INTRODUCTION**: This document condenses the Object Page UI structure and implementation guidance into actionable steps and code examples for developers implementing SAP Fiori Elements object pages. It covers configuration points (manifest and annotations), header elements, header facets, anchor navigation, content sections, paginator visibility, and footer/draft behavior. Use the examples as starting points and adapt annotation paths and entitySet names to your project.

**TAGS**: fiori-elements-framework, object-page, annotations, manifest.json, header, facets, anchor-navigation, paginator, draft-handling, odata-v2

**STEP**: 1 — Register Object Page in manifest.json

**DESCRIPTION**: Define the object page in your app descriptor (manifest.json). Register a page using the generic Object Page template and point it at the entitySet for the object. This is the primary entry point for the Fiori Elements runtime to render an Object Page.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui5": {
    "models": {
      "": {
        "dataSource": "mainService",
        "settings": {
          "synchronizationMode": "None"
        }
      }
    }
  },
  "sap.ui.generic.app": {
    "pages": [
      {
        "entitySet": "SalesOrder",                     // <- set your entity set
        "component": {
          "name": "sap.suite.ui.generic.template.ObjectPage"
        }
      }
    ]
  }
}
```

**STEP**: 2 — Configure Header: Title, Description, and Image (Annotations)

**DESCRIPTION**: Use UI.HeaderInfo annotation to set the application title (TypeName), instance title (Title path), description and image URL. If an instance image is missing, the default object type image is used. These annotations typically belong to the EntityType annotations in your service metadata (EDMX) or in local annotation files.

**LANGUAGE**: XML (OData Annotations)

**CODE**:
```xml
<!-- Example OData V4 annotation for header info -->
<Annotation Term="UI.HeaderInfo">
  <Record>
    <PropertyValue Property="TypeName" String="Sales Order"/>
    <PropertyValue Property="Title" Path="OrderID"/>         <!-- display title -->
    <PropertyValue Property="Description" Path="ShortText"/> <!-- optional -->
    <PropertyValue Property="ImageUrl" Path="ImageURL"/>     <!-- optional -->
  </Record>
</Annotation>
```

**STEP**: 3 — Configure Header Toolbar Actions and Share Menu

**DESCRIPTION**: Configure header toolbar actions (Edit, Delete, related apps, share actions). Actions can be defined via annotations (Action or custom action annotations) or via manifest settings depending on project patterns. Ensure Edit/Delete actions are placed in the header toolbar for Display mode and that the generic Share menu is available (Send Email, Share in SAP Jam, Save as Tile, Share: Microsoft Teams, Share: Collaboration Manager).

**LANGUAGE**: JSON / Annotations (Example pattern)

**CODE**:
```json
// Example: declare an action in manifest (generic pattern, adapt to your project tooling)
{
  "sap.ui.generic.app": {
    "pages": [
      {
        "entitySet": "SalesOrder",
        "component": {
          "name": "sap.suite.ui.generic.template.ObjectPage",
          "settings": {
            "header": {
              "actions": [
                { "id": "Edit", "text": "Edit" },
                { "id": "Delete", "text": "Delete" }
              ]
            }
          }
        }
      }
    ]
  }
}
```

**STEP**: 4 — Define Header Facets (Key Info & Graphical Elements)

**DESCRIPTION**: Use the UI.HeaderFacets annotation to surface up to ~5 label-field pairs and graphical elements (charts, rating indicators) in the header area. Prefer concise key data — e.g., price, availability, credit limit. Header facets are distinct from content facets and are shown in the header area.

**LANGUAGE**: XML (OData Annotations)

**CODE**:
```xml
<!-- Example header facets -->
<Annotation Term="UI.HeaderFacets">
  <Collection>
    <Record Type="UI.HeaderFacet">
      <PropertyValue Property="Label" String="Price"/>
      <PropertyValue Property="Target">
        <PropertyPath>Price</PropertyPath>
      </PropertyValue>
    </Record>
    <Record Type="UI.HeaderFacet">
      <PropertyValue Property="Label" String="Credit Limit"/>
      <PropertyValue Property="Target">
        <PropertyPath>CreditLimit</PropertyPath>
      </PropertyValue>
    </Record>
    <!-- Add graphical elements as targets (e.g. Chart or Rating) -->
  </Collection>
</Annotation>
```

**STEP**: 5 — Implement Anchor Navigation and Content Sections (Facets)

**DESCRIPTION**: Organize the page content into sections using UI.Facets or ReferenceFacet annotations. Each facet becomes an anchor navigation entry that allows quick jumping to content sections. Inside sections use FieldGroups and/or DataFieldForAnnotation to define groups of fields or embed tables.

**LANGUAGE**: XML (OData Annotations)

**CODE**:
```xml
<!-- Example content facets with referenced field groups -->
<Annotation Term="UI.Facets">
  <Collection>
    <Record Type="UI.ReferenceFacet">
      <PropertyValue Property="Label" String="General Information"/>
      <PropertyValue Property="Target" AnnotationPath="@UI.FieldGroup#Main"/>
    </Record>
    <Record Type="UI.ReferenceFacet">
      <PropertyValue Property="Label" String="Items"/>
      <PropertyValue Property="Target" AnnotationPath="@UI.LineItem#Items"/>
    </Record>
  </Collection>
</Annotation>

<!-- Example field group referenced above -->
<Annotation Term="UI.FieldGroup" Qualifier="Main">
  <Record>
    <PropertyValue Property="Data" Path="..."/>
    <!-- Define fields inside the FieldGroup -->
  </Record>
</Annotation>
```

**STEP**: 6 — Content Area: Field Groups and Tables

**DESCRIPTION**: Populate section content with FieldGroups (for grouped fields) or LineItem (table) annotations. In Fiori Elements: use FieldGroup for form-like sections (create/edit/display); use LineItem or CollectionFacet to show tables and lists.

**LANGUAGE**: XML (OData Annotations)

**CODE**:
```xml
<!-- Example line item (table) annotation -->
<Annotation Term="UI.LineItem" Qualifier="Items">
  <Collection>
    <Record Type="UI.DataFieldForAction">
      <!-- or use UI.DataField for fields shown in table -->
    </Record>
  </Collection>
</Annotation>
```

**STEP**: 7 — Paginator Buttons: Visibility and OData V2 Considerations

**DESCRIPTION**: Paginator buttons allow navigation between subitems and appear only if:
- The user is on a subobject page,
- The user navigated from a list to the current page,
- The original list had at least two entries.

Note: In SAP Fiori elements for OData V2, paginator buttons are not available on the main object page by default — you can adapt the UI to enable them if required.

**LANGUAGE**: Plain Text / Configuration Note

**CODE**:
```text
Conditions for paginator visibility:
- onSubObjectPage = true
- navigatedFromList = true
- listEntryCount >= 2

OData V2: paginator buttons not available by default on main object page; client-side UI adaptation required.
```

**STEP**: 8 — Footer Bar and Draft Handling

**DESCRIPTION**: Footer bar hosts actions and Show Messages. In draft-enabled apps, subitem object pages in create/edit modes can include an Apply button that saves the draft, concludes the create/edit flow, navigates one step up, and shows a toast message. In flexible column layout with drafts, Apply closes the subobject and returns to the main object. See the Draft Handling documentation for full lifecycle and behavior.

**LANGUAGE**: Plain Text / Link reference

**CODE**:
```text
Draft handling reference: draft-handling-ed9aa41.md
Behavior summary:
- Apply: save draft, navigate up one level, show toast
- In flexible column layout: Apply closes subobject and returns to main object
```

**STEP**: 9 — Related Documentation and Files (References)

**DESCRIPTION**: Use these internal docs for implementing controls and annotations related to object pages. Keep these file paths and links handy for deeper configuration and annotation examples.

**LANGUAGE**: Plain Text / Links

**CODE**:
```text
Controls related to object pages:
- ../10_More_About_Controls/sap-uxap-de71337.md

Annotations and feature configuration:
- configuring-object-page-features-d26d3dd.md
- configuring-further-common-features-a4d3c46.md

Draft handling:
- draft-handling-ed9aa41.md
```

fiori-elements-framework object-page annotations manifest.json header facets anchor-navigation paginator draft-handling odata-v2


**TITLE**: Overriding the Horizontal Alignment of Annotation-Based Table Columns

**INTRODUCTION**: Override horizontal alignment for columns generated from UI annotations (LineItem) by adding controlConfiguration settings in manifest.json. Use this when you need column-level alignment control for annotation-based tables in SAP Fiori elements (OData V4).

**TAGS**: fiori-elements-framework, OData V4, manifest.json, controlConfiguration, horizontalAlign, LineItem, annotation, table-columns

**STEP**: 1 — Edit manifest.json to set column horizontal alignment

**DESCRIPTION**: In your app's manifest.json, add a controlConfiguration entry for the LineItem annotation of the target page/object. Map the column identifier (for example "DataField::Material") to the horizontalAlign property and set it to one of the supported values. Place this under the target page/section (example key shown: SalesOrderManageObjectPage). This snippet is the exact JSON to insert.

**LANGUAGE**: JSON

**CODE**:
```json
"SalesOrderManageObjectPage": {
    "options": {
        "settings": {
            "controlConfiguration": {
                "_Item/@com.sap.vocabularies.UI.v1.LineItem": {
                    "columns": {
                        "DataField::Material": {
                            "horizontalAlign": "Center"
                        }
                    }
                }
            }
        }
    }
}
```

**STEP**: 2 — Verify the result and reference image

**DESCRIPTION**: After updating manifest.json, deploy/run the app and confirm the column alignment is applied. Example result image file (included in repo/docs or project assets): images/Overriding_the_Horizontal_Alignment_of_Annotation-Based_Table_Columns_fc4e1b4.png

**LANGUAGE**: text

**CODE**:
```
Result image path: images/Overriding_the_Horizontal_Alignment_of_Annotation-Based_Table_Columns_fc4e1b4.png
```

**STEP**: 3 — Supported horizontalAlign values

**DESCRIPTION**: Use one of the supported alignment values for the horizontalAlign property.

**LANGUAGE**: JSON

**CODE**:
```json
[
  "Begin",
  "Center",
  "End"
]
```

fiori-elements-framework
OData V4
manifest.json
controlConfiguration
horizontalAlign
LineItem
annotation
table-columns


**TITLE**: Overview Page Card — sap.ovp manifest configuration, headers, KPI annotations, actions, and Insights

**INTRODUCTION**: Practical reference for configuring Overview Page (OVP) cards in the manifest.json (sap.ovp). Includes card registration, header rules, KPI annotation wiring, card actions availability, and how to disable adding cards to Insights. Use these snippets and rules when generating or validating application manifest entries for OVP cards.

**TAGS**: fiori-elements-framework, sap.ovp, overview-page, manifest.json, cards, KPI, Annotations, Insights, SAPUI5

STEP: 1 — Define cards in sap.ovp (manifest.json)

DESCRIPTION: Place the cards object under "sap.ovp" in the application descriptor. Each card entry uses the card ID as the property name; runtime ordering follows the descriptor order. Provide model, template, and settings per card. The sample shows global filter keys (note deprecation comment) and two sample cards (stack and table).

LANGUAGE: JSON

CODE:
```json
"sap.ovp": {
    "_version": "1.1.0",
    "globalFilterModel": "ZCD204_EPM_DEMO_SRV",
    "globalFilterEntityType": "SalesOrder", // Deprecated since SAPUI5 1.54.
    "globalFilterEntitySet": "SalesOrder", // Available from SAPUI5 1.54 onwards.
    "cards": {
        "card00": {
            "model": "ZCD204_EPM_DEMO_SRV",
            "template": "sap.ovp.cards.stack",
            "settings": {
                // Additional settings can be placed here
                "category": "{{card00_category}}",
                "title": "{{card00_title}}",
                "subTitle": "{{card00_subTitle}}"
                // More settings can be added here
            }
        },
        "card01": {
            "model": "ZCD204_EPM_DEMO_SRV",
            "template": "sap.ovp.cards.table",
            "settings": {
                "title": "{{card01_category}}"
                // Additional settings can be placed here
            }
        }
        // Additional cards can be added here
    }
}
```

STEP: 2 — Card header configuration rules

DESCRIPTION: Configure header properties inside each card's "settings": category, title (mandatory), subTitle (mandatory only for cards with data point annotations like KPI headers). Title and subtitle max two lines. Table and list cards show a counter (records shown / total) based on current filters; other card types do not show the counter.

LANGUAGE: JSON

CODE:
```json
{
    "settings": {
        "category": "{{card00_category}}",
        "title": "{{card00_title}}",
        "subTitle": "{{card00_subTitle}}"
    }
}
```

STEP: 3 — KPI header wiring using annotations

DESCRIPTION: For KPI headers use backend aggregation and OData annotation terms. Ensure the OData service supports aggregation and that KPI values come from the backend. Use these annotation terms in manifest settings: DataPoint (KPI value/title), PresentationVariant (grouping/sorting), SelectionVariant (filters). Wire annotation paths in the card settings using keys like identificationAnnotationPath, selectionAnnotationPath, chartAnnotationPath, presentationAnnotationPath, dataPointAnnotationPath.

LANGUAGE: JSON

CODE:
```json
"sap.ovp": {
    ...
    "cards": {
        ...
        "card02": {
            "model": "ZCD204_EPM_DEMO_SRV",
            "template": "sap.ovp.cards.charts.bubble",
            "settings": {
                "entitySet": "SalesOrders",
                "identificationAnnotationPath": "com.sap.vocabularies.UI.v1.Identification#bubble",
                "selectionAnnotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#bubble",
                "chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart#bubble",
                "presentationAnnotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#bubble",
                "dataPointAnnotationPath": "com.sap.vocabularies.UI.v1.DataPoint#bubble"
            }
        },
        ...
    }
}
```

STEP: 4 — Card actions (availability and behavior)

DESCRIPTION: Card actions (available from SAPUI5 1.110) are accessed from the card header menu. Supported actions:
- Refresh: reloads card data for the bound entity.
- Add Card to Insights: shows preview and allows adding the card to My Home Insights (only if Insights service enabled).
- Manage Cards: opens Manage Cards dialog to hide/show cards.
No manifest properties are required to enable these actions (aside from Insights-related flags shown in Step 5).

LANGUAGE: text

CODE:
```text
// Actions are UI-provided (SAPUI5 >= 1.110); no specific manifest snippet required.
// Supported actions:
// - Refresh
// - Add Card to Insights (requires Insights service enabled)
// - Manage Cards
```

STEP: 5 — Insights integration and disabling Add to Insights

DESCRIPTION: Users can add analytical, list, and table cards to My Home > Insights via the card menu (More > Add Card to Insights). Limit: up to eight cards displayed in Insights. If Insights already full, added cards appear in Edit Insights. If a card uses custom navigation, Insights navigation will go to the parent overview page app. To disable the Add Card to Insights option for a specific card, set enableAddToInsights to false in the card settings.

LANGUAGE: JSON

CODE:
```json
"card01": {
    "model": "MODEL",
    "template": "sap.ovp.cards.charts.analytical",
    "settings": {
        "title": "{{card01_title}}",
        "subTitle": "{{card01_subTitle}}",
        "entitySet": "C_EntitySet",
        "enableAddToInsights": false,
        "selectionAnnotationPath": "com.sap.vocabularies.UI.v1.SelectionVariant#SV",
        "chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart#Chart",
        "presentationAnnotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#PV",
        "dataPointAnnotationPath": "com.sap.vocabularies.UI.v1.DataPoint#DP",
        "identificationAnnotationPath": "com.sap.vocabularies.UI.v1.Identification"
    }
}
```

fiori-elements-framework sap.ovp overview-page manifest.json cards KPI Annotations Insights SAPUI5