**TITLE**: Object Page Header Facet Extensions (OData V2 & V4) — Manifest & Fragments Guide

**INTRODUCTION**: Practical, code-focused guide for adding custom header facets and header fields on SAP Fiori Elements Object Pages (OData V2 and V4). Includes manifest configuration formats, extension point keys, extensionAPI usage (setCustomMessage), XML fragment examples (display and editable), and metadata snippet for custom header fields.

**TAGS**: fiori-elements-framework, object-page, header-facet, header-field, extension, manifest.json, xmlfragment, odata-v2, odata-v4, extensionAPI, setCustomMessage

STEP: 1 — Add an Object Page Header Facet Extension (OData V2)

DESCRIPTION: Use a view-based extension inside the app manifest to insert/replace header facets on the Object Page. Use only the extensionAPI; do not manipulate Fiori elements internals. Specify the manifest key in the format:
<Different_Scenario>|<EntitySet_Name>|headerEditable::<Annotation_Information>
Include className, viewName, type, and optional bVisibleOnEdit (set to false only to hide the entire header extension in edit mode).

LANGUAGE: JSON

CODE:
```json
{
  "extends": {
    "extensions": {
      "sap.ui.viewExtensions": {
        "sap.suite.ui.generic.template.ObjectPage.view.Details": {
          "BeforeHeaderFacet|STTA_C_MP_Product|headerEditable::com.sap.vocabularies.UI.v1.Chart::SpecificationWidthBulletChart": {
            "className": "sap.ui.core.mvc.View",
            "viewName": "STTA_MP.ext.fragments.HeaderExtensionFacet",
            "type": "XML",
            "bVisibleOnEdit": true
          }
        }
      }
    }
  }
}
```

STEP: 2 — Extension Point Key Options (OData V2)

DESCRIPTION: Use one of these keys in the manifest to position your header extension. Replace <EntitySet Name> and <Annotation information> accordingly.

LANGUAGE: JSON

CODE:
```json
[
  "BeforeHeaderFacet|<EntitySet Name>|headerEditable::<Annotation information>",
  "ReplaceHeaderFacet|<EntitySet Name>|headerEditable::<Annotation information>",
  "AfterHeaderFacet|<EntitySet Name>|headerEditable::<Annotation information>",
  "BeforeSimpleHeaderFacet|<EntitySet Name>|headerEditable::<Annotation information>",
  "ReplaceSimpleHeaderFacet|<EntitySet Name>|headerEditable::<Annotation information>",
  "AfterSimpleHeaderFacet|<EntitySet Name>|headerEditable::<Annotation information>",
  "ReplaceHeaderExtensionFacet|<EntitySet Name>",
  "NoImageExtensionFacet|<EntitySet Name>",
  "AfterImageExtensionFacet|<EntitySet Name>",
  "BeforeHeaderDataPoint|<EntitySet Name>|<Annotation Information>",
  "ReplaceHeaderDataPoint|<EntitySet Name>|<Annotation Information>",
  "AfterHeaderDataPoint|<EntitySet Name>|<Annotation Information>"
]
```

STEP: 3 — Show Custom Status Message on Object Page Header (setCustomMessage)

DESCRIPTION: Use extensionAPI.attachPageDataLoaded to react to page data and call extensionAPI.setCustomMessage with an object { message, type }. This runs in your extension controller (e.g., View controller module).

LANGUAGE: JavaScript

CODE:
```javascript
sap.ui.define([
], function () {
    return {
        onInit: function () {
            this.extensionAPI.attachPageDataLoaded(this.onPageDataLoaded.bind(this));
        },
        onPageDataLoaded: function(oEvent) {
            var quantity = oEvent.context.getObject().quantity;
            var oMsg = {
                message: quantity == 0 ? "Product Not Available!" : "Product Available!",
                type: quantity == 0 ? sap.ui.core.MessageType.Error : sap.ui.core.MessageType.Success
            }
            this.extensionAPI.setCustomMessage(oMsg);
        }
        ....
    }
});
```

STEP: 4 — Add Custom Header Facets (OData V4) — Content-Based Configuration

DESCRIPTION: Define custom header facets inside target.options.settings.content.header.facets in the routing target settings. Content-based config has higher priority than annotation-based config. Provide template (module path for Fragment.load), optional templateEdit, title/subTitle, visible/stashed flags, position (placement + anchor), requestGroupId, and flexSettings.

LANGUAGE: JSON

CODE:
```json
{
    "sap.ui5": {
        "routing": {
            "targets": {
                "SalesOrderManageObjectPage": {
                    "options": {
                        "settings": {
                            "content": {
                                "header": {
                                    "facets": {
                                        "CustomHeaderFacet1": {
                                            "template": "SalesOrder.ext.CustomHeaderFacetColumnChart",
                                            "stashed": false,
                                            "visible": "{= %{OverallSDProcessStatus} === 'C'}",
                                            "position": {
                                                "placement": "After",
                                                "anchor": "NetValueDataHeader"
                                            },
                                            "flexSettings": {
                                                "designtime": "not-adaptable-visibility"
                                            }
                                        },
                                        "CustomHeaderFacet2": {
                                            "template": "SalesOrder.ext.CustomHeaderFacetDataPoint",
                                            "templateEdit": "SalesOrder.ext.CustomHeaderFacetDataPointEdit",
                                            "title": "{i18n>customHeaderFacet2-CustomDataPoint}",
                                            "subTitle": "{i18n>customHeaderFacet2-CarRental}",
                                            "requestGroupId": "LongRunners",
                                            "stashed": false,
                                            "position": {
                                                "placement": "After",
                                                "anchor": "CustomHeaderFacet1"
                                            }
                                        }
                                    }
                                }
                            },
                            "controlConfiguration": {
                                "@com.sap.vocabularies.UI.v1.HeaderFacets": {
                                   "...": "see annotation-based example below"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 5 — Add Custom Header Facets (OData V4) — Annotation-Based Configuration

DESCRIPTION: Provide overrides or additional facets in controlConfiguration."@com.sap.vocabularies.UI.v1.HeaderFacets". Keys here are lower priority than content-based keys.

LANGUAGE: JSON

CODE:
```json
{
    "sap.ui5": {
        "routing": {
            "targets": {
                "SalesOrderManageObjectPage": {
                    "options": {
                        "settings": {
                            "content": {
                               "...": "see content-based example above"
                            },
                            "controlConfiguration": {
                                "@com.sap.vocabularies.UI.v1.HeaderFacets": {
                                    "facets": {
                                        "CustomHeaderFacet2": {
                                            "template": "SalesOrder.ext.CustomHeaderFacetOverwritten",
                                            "title": "Custom Error",
                                            "subTitle": "Should never appear!",
                                            "stashed": false,
                                            "position": {
                                                "placement": "After",
                                                "anchor": "CustomHeaderFacet1"
                                            }
                                        },
                                        "CustomHeaderFacet3": {
                                            "template": "SalesOrder.ext.CustomHeaderFacetHarveyBall",
                                            "templateEdit": "SalesOrder.ext.CustomHeaderFacetHarveyBallEdit",
                                            "title": "{i18n>customHeaderFacet2-CustomProgress}",
                                            "stashed": false,
                                            "position": {
                                                "placement": "After",
                                                "anchor": "CustomHeaderFacet2"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 6 — Properties Schema for Custom Header Facets (Actionable Keys)

DESCRIPTION: Use these properties when authoring a custom header facet entry (content-based or annotation-based). Required/optional markers: *optional. Use template/module path matching Fragment.load syntax. Use position.anchor to point to a facet key (FacetKey for annotation-based facets).

LANGUAGE: JSON

CODE:
```json
{
  "template": "ModulePath.of.XMLFragment",
  "templateEdit": "ModulePath.of.EditableXMLFragment (optional)",
  "title": "{i18n>key} (optional)",
  "subTitle": "{i18n>key} (optional)",
  "stashed": false,
  "visible": true,
  "position": {
    "placement": "Before | After",
    "anchor": "FacetKey"
  },
  "requestGroupId": "Heroes | Decoration | Workers | LongRunners (optional)",
  "flexSettings": {
    "designtime": "Default | not-adaptable-visibility | not-adaptable | not-adaptable-tree | not-removable"
  }
}
```

STEP: 7 — Custom Header Fragment Example (Harvey Ball Micro Chart)

DESCRIPTION: XML fragment example to render a HarveyBallMicroChart inside a header facet. Use fraction binding expressions and standard UI5 namespaces.

LANGUAGE: XML

CODE:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:mc="sap.suite.ui.microchart">
    <VBox id="CustomHeaderFacetHarveyBall" displayInline="true">
        <mc:HarveyBallMicroChart size="S" total="100" totalScale="%" press="press">
            <mc:items>
                <mc:HarveyBallMicroChartItem
                    fraction="{= ((100 > 0) ? ((${Progress} > 100) ? 100 : ((${Progress} < 0) ? 0 : (${Progress} / 100 * 100))) : 0) }"
                    color="Good"
                    fractionScale="%"
                />
            </mc:items>
        </mc:HarveyBallMicroChart>
    </VBox>
</core:FragmentDefinition>
```

STEP: 8 — Editable Custom Header Facet Fragment (FormElement + macro:Field)

DESCRIPTION: In edit mode, the header facet appears as a Form; supply an editable fragment using sap.ui.layout.form FormElement and macro:Field. TemplateEdit should point to this fragment.

LANGUAGE: XML

CODE:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:f="sap.ui.layout.form" xmlns:macro="sap.fe.macros">
        <f:FormElement label="Number of Items">
            <f:fields>
                <macro:Field id="NumberItems" metaPath="fieldControlType_item" />
            </f:fields>
        </f:FormElement>
        <f:FormElement label="Classification">
            <f:fields>
                <macro:Field id="IncotermsClassification" metaPath="IncotermsClassification" />
            </f:fields>
        </f:FormElement>
</core:FragmentDefinition>
```

STEP: 9 — Add Custom Header Fields (Annotation-Based, OData V4)

DESCRIPTION: Define custom header fields by extending controlConfiguration for the FieldGroup qualifier of the header (e.g., @com.sap.vocabularies.UI.v1.FieldGroup#ObjectPageHeaderData). Provide fields with keys that reference XML fragments and position placement/anchor pointing to a property or existing field key.

LANGUAGE: JSON

CODE:
```json
{
   "sap.ui5": {
      "routing": {
         "targets": {
            "LineItemsObjectPage": {
               "options": {
                  "settings": {
                     "controlConfiguration": {
                        "@com.sap.vocabularies.UI.v1.FieldGroup#ObjectPageHeaderData": {
                           "fields": {
                              "CustomField1": {
                                 "label": "{i18n>ObjectPageHeaderFacetFieldLabel1}",
                                 "template": "ManageItems.ext.CustomHeaderFacetFieldGroupForm",
                                 "position": {
                                    "placement": "Before",
                                    "anchor": "DataField::headerDate"
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}
```

STEP: 10 — Metadata: FieldGroup Qualifier Reference (Find the anchor key)

DESCRIPTION: The anchor key is the FieldGroup qualifier in metadata. Use the annotation target qualifier to identify the correct field group for extension.

LANGUAGE: XML

CODE:
```xml
<Schema>
    <Annotations Target="<PageName>">
        <Annotation Term="UI.FieldGroup" Qualifier="ObjectPageHeaderData">
            ... records
        </Annotation>
    </Annotations>
</Schema>
```

fiori-elements-framework object-page header-facet header-field extension manifest.json xmlfragment odata-v2 odata-v4 extensionAPI setCustomMessage


**TITLE**: Extension Points — Implementing Custom Pages in SAP Fiori elements (OData V4)

**INTRODUCTION**: This guide provides actionable steps and exact code examples to implement custom pages in SAP Fiori elements apps (OData V4). It covers manifest routing configuration, required target properties, an XML view with binding context, controller navigation using the routing controller extension, and usage of the Table building block from the flexible programming model.

**TAGS**: fiori-elements-framework, sapui5, odata-v4, custom-pages, routing, xml-view, controller, building-blocks

**STEP**: 1 — Add routing targets to the manifest

**DESCRIPTION**: Extend your app manifest (sap.ui5 > routing) to add routes and targets for custom pages and for the standard object page. Add a routing target with type "Component" and name "sap.fe.core.fpm" for custom pages to enable features of the flexible programming model. Insert the following JSON into your manifest (webapp/manifest.json) under "sap.ui5". This sample defines a custom entry page, an object page, and a custom detail page.

**LANGUAGE**: JSON

**CODE**:
```json
{
   "sap.ui5": {
        "routing": {
            "routes": [
                {
                    "pattern": ":?query:",
                    "name": "customPage",
                    "target": "customPage"
                },
                {
                    "pattern": "/RootEntity({key}):?query:",
                    "name": "objectPage",
                    "target": "objectPage"
                },
                {
                    "pattern": "/RootEntity({key})/items({key2}):?query:",
                    "name": "customDetailPage",
                    "target": "customDetailPage"
                }
            ],
            "targets": {
                "customPage": {
                    "type": "Component",
                    "id": "customPage",
                    "name": "sap.fe.core.fpm",
                    "options": {
                        "settings": {
                            "viewName": "sap.fe.core.fpmExplorer.customPageContent.CustomPage",
                            "contextPath": "/RootEntity",
                            "navigation": {
                                "RootEntity": {
                                    "detail": {
                                        "route": "objectPage"
                                    }
                                }
                            }
                        }
                    }
                },
                "objectPage": {
                    "type": "Component",
                    "id": "objectPage",
                    "name": "sap.fe.templates.ObjectPage",
                    "options": {
                        "settings": {
                            "contextPath": "/RootEntity",
                            "editableHeaderContent": false,
                            "navigation": {
                                "items": {
                                    "detail": {
                                        "route": "customDetailPage"
                                    }
                                }
                            }
                        }
                    }
                },
                "customDetailPage": {
                    "type": "Component",
                    "id": "customDetailPage",
                    "name": "sap.fe.core.fpm",
                    "options": {
                        "settings": {
                            "viewName": "sap.fe.core.fpmExplorer.customPageContent.CustomDetailPage",
                            "contextPath": "/ChildEntity",
                            "navigation": {}
                        }
                    }
                }
            }
        }
   }
}
```

**STEP**: 2 — Required properties for a custom page target

**DESCRIPTION**: Ensure your target object includes these properties under "targets.<yourTarget>". Use "Component" + "sap.fe.core.fpm" to enable flexible programming model features. The viewName must use your app namespace (sap.app.id) as prefix and map to an XML view under webapp. The contextPath should point to the entity set root for the custom page.

- type: "Component"
- id: "<unique_page_id>"
- name: "sap.fe.core.fpm"
- viewName: "<sap.app.id>.<path>.ViewName"
- contextPath: "/<EntitySetName>"

Include the target configuration similar to the snippet below (taken from the manifest example) to align properties and settings.

**LANGUAGE**: JSON

**CODE**:
```json
"customPage": {
    "type": "Component",
    "id": "customPage",
    "name": "sap.fe.core.fpm",
    "options": {
        "settings": {
            "viewName": "sap.fe.core.fpmExplorer.customPageContent.CustomPage",
            "contextPath": "/RootEntity",
            "navigation": {
                "RootEntity": {
                    "detail": {
                        "route": "objectPage"
                    }
                }
            }
        }
    }
}
```

**STEP**: 3 — Create the custom XML view with available binding context

**DESCRIPTION**: Implement an XML view whose binding context is automatically available (contextPath set in manifest target). Place the view under the namespace path used in viewName. Use standard UI5 controls; bind content to the entity set path (e.g., {/RootEntity}). The example below uses sap.m.GenericTile inside a HorizontalLayout, binding tile properties to OData properties. Save at the namespace path referenced by viewName (for example: webapp/sap/fe/core/fpmExplorer/customPageContent/CustomPage.view.xml based on the viewName).

**LANGUAGE**: XML

**CODE**:
```xml
<mvc:View
    id="application-product"
    height="100%"
    controllerName="sap.fe.core.fpmExplorer.customPageContent.CustomPage"
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:l="sap.ui.layout"
    xmlns:macros="sap.fe.macros"
>
    <Page>
        <content>
                <l:HorizontalLayout id="TileContainerExpanded" allowWrapping="true" content="{/RootEntity}" class="sapUiTinyMarginTopBottom">
                    <GenericTile header="{TitleProperty}" subheader="{DescriptionProperty}" press="onPressed" class="sapUiTinyMarginEnd">
                        <TileContent unit="{unit}" footer="{footer}">
                            <NumericContent withMargin="false" value="{kpivalue}" valueColor="{color}" indicator="{trend}" scale="{scale}" />
                        </TileContent>
                    </GenericTile>
                </l:HorizontalLayout>
        </content>
    </Page>
</mvc:View>
```

**STEP**: 4 — Implement controller for context-based navigation using routing extension

**DESCRIPTION**: Implement the custom page controller module referenced by controllerName in the XML view. Use the PageController base and the routing controller extension (this.routing) to perform context-based navigation. The binding context obtained from the event source can be passed directly to this.routing.navigate(oContext). Save the controller at the corresponding module path (for example: webapp/controller/CustomPage.controller.js matching the namespace).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
sap.ui.define(["sap/fe/core/PageController", "sap/ui/core/UIComponent"], function(PageController, UIComponent) {
    "use strict";

    return PageController.extend("sap.fe.core.fpmExplorer.customPageContent.CustomPage", {
        onPressed: function(oEvent) {
            var oContext = oEvent.getSource().getBindingContext();
            this.routing.navigate(oContext);
        }
    });
});
```

**STEP**: 5 — Use flexible programming model building blocks (Table) inside custom pages

**DESCRIPTION**: Use SAP Fiori elements building blocks (macros) in custom pages to reuse UI annotations, standard routing, and draft edit flow. When using macros:Table with metaPath pointing to @com.sap.vocabularies.UI.v1.LineItem the table behaves like a standard table including automatic in-app navigation. Place this view in the same view/controller structure as above.

**LANGUAGE**: XML

**CODE**:
```xml
<mvc:View
    id="application-product"
    height="100%"
    controllerName="sap.fe.core.fpmExplorer.customPageContent.CustomPage"
    xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns:l="sap.ui.layout"
    xmlns:macros="sap.fe.macros"
>
    <Page>
        <content>
            <macros:Table contextPath="/RootEntity" metaPath="@com.sap.vocabularies.UI.v1.LineItem" id="macroTable" />
        </content>
    </Page>
</mvc:View>
```

**STEP**: 6 — Quick verification and live example

**DESCRIPTION**: Run the app and navigate to the configured route (e.g., the app root for the customPage pattern). Verify that:
- The XML view receives the binding context from contextPath.
- Press handlers using this.routing.navigate navigate to the object page.
- macros:Table supports automatic in-app navigation without explicit press handlers.

Use the live example to inspect behavior and code: https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/customPage

fiori-elements-framework sapui5 odata-v4 custom-pages routing xml-view controller building-blocks


**TITLE**: Extension Points for Object Page Sections (SAP Fiori elements)

**INTRODUCTION**: Action-oriented guide for adding custom sections to an Object Page in SAP Fiori elements. Covers both OData V2 extension points (view/fragments via sap.ui.viewExtensions) and OData V4 custom sections (content->body->sections in manifest.json). Includes required manifest entries, supported properties, fragment/form alignment, and UI model binding examples.

**TAGS**: fiori-elements-framework, object-page, extension, manifest, ODataV2, ODataV4, custom-section, extensionAPI, xmlfragment, fragment, i18n

**STEP**: V2 — Add an extension point for an Object Page section in manifest.json

**DESCRIPTION**: For OData V2 object pages you add section extensions under "extends" -> "extensions" -> "sap.ui.viewExtensions" in manifest.json. Each extension key encodes placement, the entitySet name, and the annotation path. Specify either a view or an XML fragment with className, fragmentName, and type. Always provide the entitySet because the same annotation path can appear for multiple entity sets. Use the SAP Fiori elements extensionAPI only and keep integration responsibilities (model/binding/busy handling) within the app code.

- Placement values: BeforeFacet, ReplaceFacet, AfterFacet
- Key format example: "BeforeFacet|<EntitySet>|<AnnotationPath>" (optionally suffix with "|<index>" to disambiguate)
- className: "sap.ui.core.Fragment" or view class
- fragmentName: module path to the fragment

Keep the following manifest block (preserve and adapt keys/fragment names and titles to your app):

**LANGUAGE**: JSON

**CODE**:
```json
"extends": {
    "extensions": {
        "sap.ui.viewExtensions": {
	   "sap.suite.ui.generic.template.ObjectPage.view.Details":
      "BeforeFacet|SEPMRA_C_PD_Product|to_ProductText::com.sap.vocabularies.UI.v1.LineItem": {
      "className": "sap.ui.core.Fragment",
      "fragmentName": "nw.epm.refapps.st.prod.manage.ext.BeforeFacetTest",
      "type": "XML",
      "sap.ui.generic.app": {
         "title": "Facet Breakout before Product Text LineItem"
      }
     },
     "BeforeFacet|SEPMRA_C_PD_Product|to_ProductText::com.sap.vocabularies.UI.v1.LineItem|1": {
      "className": "sap.ui.core.Fragment",
      "fragmentName": "nw.epm.refapps.st.prod.manage.ext.BeforeFacetTestNew",
      "type": "XML",
      "sap.ui.generic.app": {
         "title": "Facet Breakout before Product Text LineItem",
          "key" : "1"
      }
     }
     "AfterFacet|SEPMRA_C_PD_Product|to_Supplier::com.sap.vocabularies.UI.v1.Identification": {
      "className": "sap.ui.core.Fragment",
      "fragmentName": "nw.epm.refapps.st.prod.manage.ext.AfterFacetTest",
      "type": "XML",
      "sap.ui.generic.app": {
         "title": "Facet Breakout after Supplier Identification"
      }
     },
     "AfterFacet|SEPMRA_C_PD_Product|to_Supplier::com.sap.vocabularies.UI.v1.Identification|1": {
      "className": "sap.ui.core.Fragment",
      "fragmentName": "nw.epm.refapps.st.prod.manage.ext.AfterFacetTest",
      "type": "XML",
      "sap.ui.generic.app": {
         "title": "Facet Breakout after Supplier Identification",
         "key": 1
      }
}
}
```

**STEP**: V4 — Define custom sections using the manifest "content" block

**DESCRIPTION**: For OData V4, add custom sections under sap.ui5.routing.targets.<ObjectPageTarget>.options.settings.content.body.sections in manifest.json. Use custom keys to reference the section. Provide:
- template: module path to your XML fragment (Fragment.load syntax)
- title: localized text or binding expression (typically i18n)
- position: placement ("Before" | "After") and anchor (key of another section or a FacetId)
- subSections support: define nested subSections with their own templates, titles, and positions

Ensure translations exist for i18n keys and that the referenced template module paths resolve to your fragment files.

Use the following sample manifest snippet as a starting point (preserve and adapt keys, template names, and titles):

**LANGUAGE**: JSON

**CODE**:
```json
{
   "sap.ui5": {
      "routing": {
         "targets": {
            "SalesOrderManageObjectPage": {
               "options": {
                  "settings": {
                     "content": {
                        "body": {
                           "sections": {
                              "customSection": {
                                 "template": "SalesOrder.ext.CustomSection",
                                 "title": "{i18n>customSection}",
                                 "position": {
                                    "placement": "Before",
                                    "anchor": "SalesOrderItems"
                                 }
                              },
                              "anotherCustomSection": {
                                 "title": "Multiple Subsections",
                                 "subSections": {
                                     "firstSubSectionKey": {
                                         "title": "First Subsection",
                                         "template": "SalesOrder.ext.CustomFieldForm"
                                     },
                                     "secondSubSectionKey": {
                                         "title": "Second Subsection",
                                         "template": "SalesOrder.ext.CustomFieldForm2",
                                         "position": {
                                             "placement": "After",
                                             "anchor": "firstSubSectionKey"
                                         }
                                     }
                                 }
                                 "position": {
                                    "placement": "After",
                                    "anchor": "customSection"
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }
}
```

**STEP**: Custom section properties and usage rules

**DESCRIPTION**: Implement these properties when defining a custom section key under content.body.sections. The asterisk (*) marks mandatory properties.

- template (required for content): module path to an XML fragment; matches Fragment.load syntax
- title* (mandatory): text or binding expression (typically "{i18n>key}")
- position:
  - placement: "Before" | "After" (default is After)
  - anchor*: key of another section or a FacetId (for annotation-defined facets)
- visible: Boolean or binding expression (default: true)
- actions: actions object (same format as Adding Custom Actions Using Extension Points)
- subSections: object with keys for subsections having their own title/template/position

Use these rules:
- Reference annotation-defined facets by their FacetId in position.anchor.
- Provide i18n translations for titles.
- If you need actions on custom sections, declare an "actions" object matching framework expectations.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "yourSectionKey": {
    "template": "your.module.path.ToFragment",
    "title": "{i18n>yourSectionTitle}",
    "position": {
      "placement": "Before",
      "anchor": "ExistingFacetIdOrSectionKey"
    },
    "visible": true,
    "actions": {
      // actions object as per framework
    },
    "subSections": {
      "subKey1": {
        "title": "{i18n>subTitle1}",
        "template": "your.module.path.SubFragment"
      }
    }
  }
}
```

**STEP**: Fragment form alignment (ensure proper layout inside custom sections)

**DESCRIPTION**: When using UI5 Form in a custom section, add the CSS class sapUxAPObjectPageSubSectionAlignContent on the Form to align content correctly inside Object Page subsections.

**LANGUAGE**: XML

**CODE**:
```xml
<core:FragmentDefinition xmlns="sap.m"
    xmlns:core="sap.ui.core"
    xmlns:layout="sap.ui.layout">
  <layout:Form class="sapUxAPObjectPageSubSectionAlignContent">
    <!-- form content -->
  </layout:Form>
</core:FragmentDefinition>
```

**STEP**: Use the UI model to react to editMode inside fragments

**DESCRIPTION**: Bind control properties inside your fragment to the UI model to respond to editMode. Example below shows enabling a control only when editMode equals 'Editable'.

**LANGUAGE**: XML

**CODE**:
```xml
enabled="{= ${ui>/editMode} === 'Editable'}"
```

**STEP**: Operational notes, examples and links

**DESCRIPTION**: Implementation checklist and references:
- Use app extensions only if manifest settings or annotations cannot achieve the UI/behavior.
- Use only the SAP Fiori elements extensionAPI for interactions with the framework.
- You can specify either a view or an XML fragment for additional sections; you do not need to declare ObjectPageSection/subSections in the object page view—the template provides those.
- For working examples and live playground: Standard Floorplans - Extensions - Custom Section at https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/floorplanObjectPage/customSection
- Ensure a defined LineItem service is available in examples (e.g., service.cds) and add translations for all i18n keys.
- For extensionAPI usage details, consult Using the extensionAPI documentation and Extension Points docs in the SAP Fiori elements documentation.

**LANGUAGE**: PlainText

**CODE**:
```text
References:
- Using the extensionAPI: using-the-extensionapi-bd2994b.md
- Adding a custom section example: adding-a-custom-section-to-an-object-page-a357047.md
- Extension Points: ../08_Extending_SAPUI5_Applications/extension-points-403c050.md
- Live example: https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/floorplanObjectPage/customSection
```

fiori-elements-framework object-page extension manifest ODataV2 ODataV4 custom-section extensionAPI xmlfragment fragment i18n


**TITLE**: Extension Points for Object Page Subsections (OData V2 & V4)

**INTRODUCTION**: This guide explains how to add custom subsections to the Object Page in SAP Fiori elements. It covers OData V2 (sap.ui.viewExtensions) and OData V4 (manifest content sections). Use these patterns to insert a custom view or XML fragment before, after, or replacing existing subsections, or to add fully custom subsections with positioning and localized titles.

**TAGS**: fiori-elements-framework, object-page, extension-points, odata-v2, odata-v4, manifest.json, sap.ui.viewExtensions, xmlfragment, lazy-loading

**STEP**: 1 — Overview and best practices

**DESCRIPTION**:
- Prefer manifest settings and annotations over app extensions. Use app extensions only when necessary.
- When implementing extensions, interact with Fiori elements only through the official extensionAPI. Do not directly access or manipulate internal framework controls, properties, models, or bindings.
- Terminology:
  - OData V2: use the term "facet" and extension keys like BeforeSubSection, AfterSubSection, ReplaceSubSection inside sap.ui.viewExtensions.
  - OData V4: use the term "section" and define custom subsections inside routing.targets.options.settings.content.body.sections.
- For V2 extension points, you must specify the subsection as an annotation path and include the entitySet name (annotation paths can repeat across entity sets).

**LANGUAGE**: text

**CODE**:
```text
Best practices:
- Use extensionAPI only.
- Prefer manifest settings/annotations over app extensions.
- Specify entitySet + annotation path for V2 extension points.
```

**STEP**: 2 — OData V2: Insert subsections using sap.ui.viewExtensions (Before/After/Replace)

**DESCRIPTION**: Add additional subsections into existing facets by registering view extensions under sap.ui.viewExtensions for the ObjectPage Details view. Use keys of the form:
- "BeforeSubSection|<EntitySet>|<AnnotationPath>::<AnnotationTerm>"
- "AfterSubSection|<EntitySet>|<AnnotationPath>::<AnnotationTerm>"
- "ReplaceSubSection|<EntitySet>|<AnnotationPath>::<AnnotationTerm>"
Each extension entry must reference either a view or fragment (className/viewName/type or fragment reference). You can enable lazy loading using sap.ui.generic.app.enableLazyLoading.

Include the extension entries in the application's manifest.json under sap.ui.viewExtensions -> sap.suite.ui.generic.template.ObjectPage.view.Details.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.ui.viewExtensions": {
   "sap.suite.ui.generic.template.ObjectPage.view.Details": {
      "BeforeSubSection|STTA_C_MP_Product|to_ProductSalesData::com.sap.vocabularies.UI.v1.Chart":{
         "className": "sap.ui.core.mvc.View",
         "viewName": "STTA_MP.ext.view.ProductSalesPrice",
         "type": "XML",
         "sap.ui.generic.app": {
            "title": "Target Sales Prices",
            "enableLazyLoading": true
         }
      },
      "AfterSubSection|STTA_C_MP_Product|to_ProductSalesData::com.sap.vocabularies.UI.v1.LineItem":{
         "className": "sap.ui.core.mvc.View",
         "viewName": "STTA_MP.ext.view.ProductSalesPrice",
         "type": "XML",
         "sap.ui.generic.app": {
            "title": "Target Sales Prices",
            "enableLazyLoading": true
         }
     "ReplaceSubSection|STTA_C_MP_Product|to_ProductTextType::com.sap.vocabularies.UI.v1.LineItem":{
         "className": "sap.ui.core.mvc.View",
         "viewName": "STTA_MP.ext.view.ProductSalesPrice",
         "type": "XML",
         "sap.ui.generic.app": {
            "title": "Target Sales Prices",
            "enableLazyLoading": true
         }
      },
    .....
```

**STEP**: 3 — OData V4: Define custom subsections via manifest content (XMLFragment, positioning, localization)

**DESCRIPTION**: For OData V4, add custom subsections by extending the target's settings.content.body.sections in manifest.json. Define a custom section key and add subSections entries that reference an XMLFragment, provide a localized title, and specify placement relative to an anchor subsection using position. This pattern supports custom UI, controls not supported by default, and localized titles.

Place the JSON block under sap.ui5.routing.targets.<TargetName>.options.settings.content.body.sections.

**LANGUAGE**: JSON

**CODE**:
```json
{
	"sap.ui5": {
		"routing": {
			"targets": {
				"SalesOrderManageObjectPage": {
					"options": {
						"settings": {
							"content": {
								"body": {
									"sections": {
										"myObjectPageSection": {
											"subSections": {
												"customSubSection": {
													"type": "XMLFragment",
													"name": "SalesOrder.ext.CustomSubSection",
													"title": "{i18n>customSubSection}",
													"position": {
														"placement": "After",
														"anchor": "someSubSection"
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
```

**STEP**: 4 — Notes, lazy loading, view vs fragment, and live examples

**DESCRIPTION**:
- You may supply either a view or a fragment for the additional subsection. Do not add uxap tags (ObjectPageSection/subSections/ObjectPageSubSection) — the Object Page template already contains these.
- Lazy loading can be enabled via sap.ui.generic.app.enableLazyLoading for V2 view extensions.
- After adding extensions, display/layout/behavior and model usage for that content is your application's responsibility; avoid interacting with internal FE controls outside the extensionAPI.
- Live example and testing: see SAP Fiori development portal demo "Standard Floorplans - Extensions - Extensions for Object Pages - Custom Subsection".
- Ensure required services are available for examples (e.g., a defined LineItem service such as service.cds in the referenced example).

**LANGUAGE**: text

**CODE**:
```text
Live example: https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/floorplanObjectPage/customSubSection
Note: Ensure a LineItem service exists (e.g., service.cds in the example).
```


**TITLE**: Extension Points for Tables (SAP Fiori elements)

**INTRODUCTION**: Instructions and code examples to add or customize table columns in SAP Fiori elements apps (OData V2 and V4). Includes recommended extension points, fragment and manifest examples, controller extension example, configuration property reference, and sorting/filtering configuration. Use only the SAP Fiori elements extensionAPI when implementing app extensions.

**TAGS**: fiori-elements-framework, tables, extensions, OData V2, OData V4, manifest.json, fragment, controller-extension, custom-columns, responsive-table, grid-table, analytical-table, tree-table

STEP: 1 - Caution and integration guidelines

DESCRIPTION: Use app extensions only when manifest settings or annotations cannot produce the required behavior. Integrate using only the SAP Fiori elements extensionAPI. After creating an extension, display and system behavior (control placement, layout, models, busy handling) are the app's responsibility. Do not access internal objects of the framework.

LANGUAGE: Text

CODE:
```
Caution:
Use app extensions with caution and only if you cannot produce the required behavior by other means, such as manifest settings or annotations. To correctly integrate your app extension coding with SAP Fiori elements, use only the `extensionAPI` of SAP Fiori elements. After you've created an app extension, its display (control placement and layout) and system behavior (model and binding usage, busy handling) lies within the application's responsibility.
```

STEP: 2 - OData V2: Available extension points for adding columns (mapping table)

DESCRIPTION: Use these extension-points to add columns to tables in SAP Fiori elements (OData V2). `<Name of the EntitySet>` = current page entity set. `<Name of the table EntitySet>` = table entity set (use for object page table column extensions).

LANGUAGE: Text

CODE:
```
Table Type         | Floorplan     | Extension Point(s)

fiori-elements-framework
tables
extensions
OData V2
OData V4
manifest.json
fragment
controller-extension
custom-columns
responsive-table
grid-table
analytical-table
tree-table


----------------------------
All                | Object page   | onBeforeRebindTableExtension
Responsive table   | List report   | ResponsiveTableColumnsExtension|<Name of the EntitySet>
                   |               | ResponsiveTableCellsExtension|<Name of the EntitySet>
Responsive table   | Object page   | ResponsiveTableColumnsExtension|<Name of the table EntitySet>|<Facet ID/Annotation Path>
                   |               | ResponsiveTableCellsExtension|<Name of the table EntitySet>|<Facet ID/Annotation Path>
Grid table         | List report   | GridTableColumnsExtension|<Name of the EntitySet>
Grid table         | Object page   | GridTableColumnsExtension|<Name of the EntitySet>|<Facet ID/Annotation Path>
Analytical table   | List report   | AnalyticalTableColumnsExtension|<Name of the EntitySet>
Analytical table   | Object page   | GridTableColumnsExtension|AnalyticalTableColumnsExtension|<Name of the table EntitySet>|<Facet ID/Annotation Path>
Tree table         | List report   | TreeTableColumnsExtension|<Name of the EntitySet>

Notes:
- To replace default navigation in a responsive table (List Report) use ListReportExtension.
- To replace default navigation in a responsive table (Object Page) use DetailsExtension.
```

STEP: 3 - OData V4: Custom column key rules and ID patterns

DESCRIPTION: Keys for custom columns must use allowed characters. Understand how UI.DataField column keys and custom column IDs are formed.

LANGUAGE: Text

CODE:
```
Allowed characters for custom column keys: colon (:), underscore (_), dash (-), alphanumeric (aA-zZ,0-9)

UI.DataField column keys:
- All columns start with ...::C:: followed by the annotation type (e.g., UI.DataField), ::, and the corresponding property.
Example ID:
<sap.m.Label id="SalesOrder::SalesOrderManageList--fe::table::SalesOrderManage::LineItem::C::FieldGroup::multipleActionFields-innerColumnHeader">

Custom columns:
- ID concatenation: ...C::CustomColumn::<key>
```

STEP: 4 - Procedure: Define a fragment for the view extension (fragment XML)

DESCRIPTION: Create a fragment defining the custom column content (first define column metadata in manifest, then implement fragment for the cell UI). Example fragment contains a vertical layout with a button that calls a controller extension handler.

LANGUAGE: XML

CODE:
```xml
<!-- File: CustomColumnLRButton.fragment.xml -->
<core:FragmentDefinition xmlns:core="sap.ui.core" xmlns="sap.m" xmlns:l="sap.ui.layout">
	<l:VerticalLayout id="myVL">
		<Button id="myButtonId" text="Custom Button" press="SalesOrder.ext.controller.LRExtend.buttonPressed" />
	</l:VerticalLayout>
</core:FragmentDefinition>
```

STEP: 5 - Procedure: Include view extensions in manifest.json (example controlConfiguration to add custom columns)

DESCRIPTION: Extend controllers and declare custom columns under controlConfiguration for list report and object page targets. Use "template" to reference the fragment path. Use "properties" to enable sorting/filtering/export behaviors. Use "availability" to control default/adaptation/hidden visibility.

LANGUAGE: JSON

CODE:
```json
{
    "sap.ui5": {
         "extends": {
               "extensions": {
                      "sap.ui.controllerExtensions": {
                            "sap.fe.templates.ListReport.ListReportController": {
                                    "controllerName": "SalesOrder.ext.controller.LRExtend"
                            },
                       "sap.fe.templates.ListReport.ObjectPageController": {
                                    "controllerName": "SalesOrder.ext.controller.OPExtend"
                            }
                      }
               }
        },
        "routing": {
            "targets": {
                "SalesOrderManageList": {
                    "options": {
                        "settings": {
                            "controlConfiguration": {
                                "@com.sap.vocabularies.UI.v1.LineItem": {
                                    "columns": {
                                        "CustomColumnRating": {
                                            "header": "{i18n>LR.Custom_Column|Button}",
                                            "width": "10em",
                                            "importance": "High",
                                            "horizontalAlign": "Center",
                                            "position": {
                                                "placement": "After",
                                                "anchor": "DataFieldForAnnotation::FieldGroup::multipleActionFields"
                                            },
                                            "template": "SalesOrder.ext.fragment.CustomColumnLRButton",
                                            "availability": "Default",
                                            "properties": [
                                                "ID",
                                                "TotalNetAmount",
                                                "_CustomerPaymentTerms/CustomerPaymentTerms",
                                                "_ShipToParty/BusinessPartner"
                                            ]
                                        },
                                        "CustomColumnWithHeaderFromMetaData": {
                                            "header": "{metaModel>/SalesOrderManage/SoldToParty@com.sap.vocabularies.Common.v1.Label}",
                                            "template": "SalesOrder.custom.CustomColumnButton",
                                            "availability": "Default",
                                            "position": {
                                                "placement": "After",
                                                "anchor": "DataFieldForAnnotation::FieldGroup::multipleActionFields"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "SalesOrderManageObjectPage": {
                    "options": {
                        "settings": {
                            "controlConfiguration": {
                                "_Item/@com.sap.vocabularies.UI.v1.LineItem": {
                                    "columns": {
                                        "CustomColumnOnObjectPage": {
                                            "header": "AnotherColumnLabel",
                                            "template": "SalesOrder.ext.fragment.CustomColumnOPButton",
                                            "availability": "Adaptation"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

STEP: 6 - Controller extension: implement handlers (example LRExtend.controller.js)

DESCRIPTION: Implement fragment event handlers (e.g., press) in controller extensions. Include lifecycle overrides if needed.

LANGUAGE: JavaScript

CODE:
```javascript
// File: LRExtend.controller.js
sap.ui.define(
	[
		"sap/ui/core/mvc/ControllerExtension",
		"sap/m/MessageBox"
	],
	function (ControllerExtension, MessageToast, Messaging, Message, MessageType, Log, MessageBox) {
		"use strict";
		return ControllerExtension.extend("SalesOrder.ext.controler.LRExtend", {

			buttonPressed: function() {
				MessageBox.show("Button pressed!");
			},

			// This section allows to extend lifecycle hooks or override public methods of the base controller
			override: {
				routing: {
					onBeforeNavigation: function (oContextInfo) {
						//Custom code
					}
				},
				editFlow: {
					onBeforeDelete: function (oParameters) {
						//Custom code
					}
				}
			}
		});
	}
);
```

STEP: 7 - Custom column configuration properties (reference)

DESCRIPTION: Use these properties under controlConfiguration -> ... -> columns to configure custom columns. This reference preserves supported values and behavior.

LANGUAGE: Text

CODE:
```
Property: key
Supported values: aA-zZ, 0-9, :, _, -
Description: Identifier for the custom column; used as reference by other columns.

Property: header
Supported values: Any Unicode string, i18n text, metadata path (i18n recommended)
Description: Header text shown on table and add/remove dialog.

Property: tooltip
Supported values: Any Unicode string, i18n text
Description: Tooltip shown on column header; defaults to header text if not provided.

Property: width*
Supported values: auto | value | inherit
Description:
- auto: browser calculates width
- length: px, cm etc.
- %: percent of containing block
- inherit: inherit from parent
If omitted, SAP Fiori elements sets default values.

Property: importance
Supported values: "High" | "Medium" | "Low"
Description:
Controls responsive pop-in order: Low hidden first, then Medium, High always displayed.

Property: horizontalAlign*
Supported values: "Begin" | "Center" | "End"
Description: Aligns header and content horizontally.

Property: position
Supported values: column ID of anchor
Description: Defines placement relative to other columns. Use anchor key for "position.anchor".

Property: position.placement
Supported values: "After" | "Before"
Description: Placement relative to anchor.

Property: position.anchor
Supported values: "<key_of_referenced_column>"
Description: Key of the referenced column used as anchor. Annotation columns can be referenced by FieldId.

Property: template
Supported values: relative path to template file
Description: Path to fragment, using Fragment.load syntax.

Property: availability*
Supported values: "Default" | "Adaptation" | "Hidden"
Description:
- Default: shown in table
- Adaptation: not shown initially; available through key user adaptation
- Hidden: not available in table or adaptation

Property: properties*
Supported values: string or array of strings (annotation properties and navigation properties)
Description:
- Used by framework to enable sorting, filtering, message handling, export, copy.
- Sorting: properties appear in header sorting list; backend must support sorting (navigation properties may not be supported).
- Export: properties exported into spreadsheet or PDF. If multiple values, can split into separate columns.
- Messages: link messages to column based on properties.
- Copying: listed properties are copied during row/range copy.

Property: required
Supported values: true | false
Description: Visual indicator (asterisk) if required. No additional validation performed by framework.

(*) = optional value.
Bold formatting in original source indicated default or fallback behavior.
```

STEP: 8 - UI model binding example (editMode binding in fragment)

DESCRIPTION: Use UI model bindings inside fragments to react to UI state (e.g., edit mode). Example: enable control only when editMode is 'Editable'.

LANGUAGE: XML

CODE:
```
enabled="{= ${ui>/editMode} === 'Editable'}"
```

STEP: 9 - Sorting and filtering: properties example

DESCRIPTION: To enable sorting and filtering on a custom column, declare the "properties" array with the properties that map to annotation properties. These are used by header sort and the sorting/filtering dialog.

LANGUAGE: JSON

CODE:
```json
"properties": [
    "TotalNetAmount",
    "_CustomerPaymentTerms/CustomerPaymentTerms"
]
```

STEP: 10 - Notes, anchors, Table building block and live example link

DESCRIPTION: Important notes and links to additional resources. When using the Table building block, custom columns defined in manifest.json are not supported. Find anchors to correctly position custom elements. Live examples available.

LANGUAGE: Text

CODE:
```
Notes:
- For anchor keys: see "Finding the Right Key for the Anchor" (Finding the Right Key for the Anchor).
- When using the Table building block, defining custom columns in the manifest.json file isn't supported. See "The Table Building Block" for details.
- Live examples: SAP Fiori dev portal - Building Blocks - Table - Extensions - Custom Column
  https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/buildingBlocks/table/customColumn
```

sapui5.md - Chunk 218


**TITLE**: Extension Points for Custom Views in Fiori Elements List Report (OData V4)

**INTRODUCTION**: This guide explains how to add custom views (custom tabs) to a Fiori elements List Report (OData V4). It shows how to configure custom tabs in the manifest, create XML fragments for custom content (table or button), attach a fragment-level handler, register a controller extension, and apply filter conditions from the filter bar to custom tabs.

**TAGS**: sapui5, fiori-elements, list-report, odata-v4, extension, manifest, xmlfragment, controller-extension, filterConditions

STEP: 1 — Add custom view entries to the List Report configuration in manifest.json

DESCRIPTION: Declare custom tabs (views) for the List Report in the app manifest. Each view in "paths" must include a unique key. For custom view fragments provide the "template" (name includes sap.app.id prefix), and optionally a localized "label". Ensure you have at least one annotation view in the list; custom views co-exist with annotation-based tabs.

LANGUAGE: JSON

CODE:
```json
"BusinessPartnersList": {
    "type": "Component",
    "id": "BusinessPartnersList",
    "name": "sap.fe.templates.ListReport",
    "options": {
        "settings": {
            "contextPath": "/BusinessPartners",
            "views": {
                "paths": [
                    {
                        "key": "tab1",
                        "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#All"
                    },
                    {
                        "key": "tab2",
                        "label": "Custom View with Table",
                        "template": "BusinessPartners.ext.CustomViewTable"
                    },
                    {
                        "key": "tab3",
                        "label": "{i18n>LRCustomViewWithButton}",
                        "template": "BusinessPartners.ext.CustomViewWithButton"
                    }
                ],
                "showCounts": true
            }
        }
    }
}
```

STEP: 2 — Custom view properties

DESCRIPTION: Supported properties for each custom view entry in manifest "views.paths":
- key: "<unique_tab_id>" — Unique tab identifier.
- label: "<tab_title>" — Tab title; supports localization via i18n.
- template: "<name_of_custom_xml_view>" — Fully qualified view name (sap.app.id + path in app/webapp + XML view name).

LANGUAGE: JSON

CODE:
```json
// Example structure (conceptual)
{
  "key": "<unique_tab_id>",
  "label": "<tab_title>",
  "template": "<sap.app.id>.<path>.<ViewName>"
}
```

STEP: 3 — Create custom XML fragment: table example

DESCRIPTION: Add an XML fragment (xmlfragment) that defines the content of the custom tab. This example adds a sap.m.Table bound to /BusinessPartners. Use the fragment name referenced by the manifest.template (e.g., BusinessPartners.ext.CustomViewTable).

LANGUAGE: XML

CODE:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core" xmlns:u="sap.ui.unified">
    <Table id="customViewWithTable" items="{
        path: '/BusinessPartners',
        sorter: {
            path: 'Name'
        }
    }">
        <headerToolbar>
            <OverflowToolbar>
                <content>
                    <Title text="Business partners" level="H2" />
                    <ToolbarSpacer />
                </content>
            </OverflowToolbar>
        </headerToolbar>
        <infoToolbar>
            <OverflowToolbar>
                <Label text="List of business partners" />
            </OverflowToolbar>
        </infoToolbar>
        <columns>
            <Column width="15em">
                <Text text="Partner Name" />
            </Column>
            <Column minScreenWidth="Tablet" demandPopin="true">
                <Text text="Country" />
            </Column>
            <Column minScreenWidth="Desktop" demandPopin="true" hAlign="End">
                <Text text="Region" />
            </Column>
            <Column minScreenWidth="Desktop" demandPopin="true" hAlign="Center">
                <Text text="Segment" />
            </Column>
            <Column minScreenWidth="Desktop" demandPopin="true" hAlign="Center">
                <Text text="Sales Amount" />
            </Column>
            <Column minScreenWidth="Desktop" demandPopin="true" hAlign="Center">
                <Text text="Sales Amount (local currency)" />
            </Column>
        </columns>
        <items>
            <ColumnListItem type="Active">
                <cells>
                    <ObjectIdentifier text="{Name}" />
                    <Text text="{Country}" />
                    <Text text="{Region}" />
                    <Text text="{Segment}" />
                    <u:Currency value="{SalesAmount}" currency="{Currency}" />
                    <u:Currency value="{SalesAmountLocalCurrency}" currency="{LocalCurrency}" />
                </cells>
            </ColumnListItem>
        </items>
    </Table>
</core:FragmentDefinition>
```

STEP: 4 — Create custom XML fragment: button with fragment-level handler

DESCRIPTION: Use core:require in the fragment to attach a handler/controller for fragment-level event handling (e.g., button press). The core:require points to a module path inside your app (e.g., BusinessPartners/ext/CustomButton). Ensure the module implements the handler functions you use (e.g., onPress).

LANGUAGE: XML

CODE:
```xml
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
    <Panel
        headerText="Business Partners"
        class="sapUiResponsiveMargin"
        width="auto"
        core:require="{handler: 'BusinessPartners/ext/CustomButton'}"
    >
        <content>
            <Button text="IBN" id="customButton1" class="sapUiSmallMarginEnd" press="handler.onPress" />
        </content>
    </Panel>
</core:FragmentDefinition>
```

STEP: 5 — Implement fragment handler module (custom controller for fragment)

DESCRIPTION: Implement the fragment-level handler module referenced by core:require. Export functions used by the fragment (e.g., onPress). Keep logic minimal and reference UI5 modules as needed (MessageBox in example).

LANGUAGE: JavaScript

CODE:
```javascript
sap.ui.define(["sap/ui/core/Component"], function(Component) {
    "use strict";

    return {
        someHandler: function(oEvent) {
            // Do something here
        },
        onPress: function(oEvent) {
            MessageBox.show("You pressed the custom action");
        }
    };
});
```

STEP: 6 — Register a controller extension for the List Report in manifest.json

DESCRIPTION: To customize behavior when filter bar values change or when a custom tab needs refresh, register a controller extension that overrides methods on the List Report controller. Add the controller extension entry under sap.ui5.extends.extensions.sap.ui.controllerExtensions.

LANGUAGE: JSON

CODE:
```json
"sap.ui5": {
    "extends": {
        "extensions": {
            "sap.ui.controllerExtensions": {
                "sap.fe.templates.ListReport.ListReportController": {
                    "controllerName": "SalesOrder.ext.LRExtend"
                }
            }
        }
    }
}
```

STEP: 7 — Implement controller extension to apply filterConditions and handle pending filters

DESCRIPTION: Override onViewNeedsRefresh and onPendingFilters in a ControllerExtension to apply filter conditions from the filter bar onto custom tab bindings. Use base.getExtensionAPI().createFiltersFromFilterConditions to convert filterConditions into OData filters/search. Example shows deleting a specific Region filter value and applying combined filters and $search to a table binding. Also set overlay while filters are pending.

LANGUAGE: JavaScript

CODE:
```javascript
sap.ui.define(["sap/ui/core/mvc/ControllerExtension", "sap/ui/model/Filter"], function(ControllerExtension, Filter) {
    "use strict";
    return ControllerExtension.extend("BusinessPartners.ext.LRExtend", {
        override: {
            onViewNeedsRefresh: function(mParameters) {
                var oFilterInfo = mParameters.filterConditions;
                if (oFilterInfo) {
                    var duplicateFilterInfo = Object.assign({}, oFilterInfo);
                    if (
                        duplicateFilterInfo.Region &&
                        duplicateFilterInfo.Region.map(item => item.values).findIndex(i => i.includes("Bavaria")) !== -1
                    ) {
                        delete duplicateFilterInfo.Region;
                    }
                    var oTable = this.getView().byId("BusinessPartners::BusinessPartnersList--fe::CustomTab::tab2--customViewWithTable"),
                        oBinding = oTable.getBinding("items"),
                        oConvertedFilter = this.base.getExtensionAPI().createFiltersFromFilterConditions(duplicateFilterInfo);
                    oTable.setShowOverlay(false);
                    var oFilter = new Filter({ filters: oConvertedFilter.filters, and: true });
                    oBinding.filter(oFilter);
                    oBinding.changeParameters({$search: oConvertedFilter.search});
                }
            },
            onPendingFilters: function() {
                var oTable = this.getView().byId("BusinessPartners::BusinessPartnersList--fe::CustomTab::tab2--customViewWithTable");
                if (oTable) {
                    oTable.setShowOverlay(true);
                }
            }
        }
    });
});
```

sapui5 fiori-elements list-report odata-v4 extension manifest xmlfragment controller-extension filterConditions


**TITLE**: SAP Fiori elements — FAQs Condensed for Code Integration

**INTRODUCTION**: Action-oriented FAQ reference for developers building SAP Fiori elements applications. Use this as a quick, code-focused checklist for setup, manifest configuration, annotations, navigation, actions, filter bar behavior, value help, tables, charts, object page behavior, extensions, and automated testing guidance.

**TAGS**: fiori-elements-framework, sapui5, annotations, odata-v4, manifest.json, navigation, actions, filter-bar, value-help, object-page, tables, charts, drafts, extensions, opa-testing

STEP: 1 — Recommended IDE and Tools
DESCRIPTION: Use SAP Fiori tools (extensions for SAP Business Application Studio and Visual Studio Code) for scaffolding, annotations, and local testing. Open the Tools tile in the Developing Apps with SAP Fiori Elements documentation for guided setup.
LANGUAGE: text
CODE:
```text
Recommended:
- SAP Business Application Studio + SAP Fiori tools extensions
- Visual Studio Code + SAP Fiori tools extension pack
```

STEP: 2 — Declare required libraries in manifest.json
DESCRIPTION: Add the Fiori elements libs to the sap.ui5.dependencies.libs section to enable floorplans or custom apps. Use sap.fe.templates for standard floorplans (list report/object page). For custom apps add sap.fe.core, and use sap.fe.macros when using building blocks.
LANGUAGE: JSON
CODE:
```json
{
  "sap.ui5": {
    "dependencies": {
      "libs": {
        "sap.fe.templates": {},
        "sap.fe.core": {},
        "sap.fe.macros": {}
      }
    }
  }
}
```

STEP: 3 — Draft handling rule
DESCRIPTION: For edit-based create/edit/delete scenarios in OData V4, ensure the back end exposes a draft-enabled service. Non-draft services are only supported for read-only UIs. Annotate and configure draft support in the service and app.
LANGUAGE: text
CODE:
```text
Note: OData V4 edit scenarios require a draft-enabled service. Use draft annotations and implement server-side draft handling.
Reference: Draft Handling documentation
```

STEP: 4 — Locate common annotations and UI elements
DESCRIPTION: Refer to the targeted docs for annotation patterns for tables, charts, filter bars, object page headers/sections, actions, field help, and navigation. Use these docs as sources for exact annotation names and example XML/EDMX/CDS fragments.
LANGUAGE: text
CODE:
```text
Key topics:
- Configuring Tables
- Configuring Charts
- Configuring Filter Bars
- Setting Up Object Page Header
- Defining and Adapting Sections
- Actions, Field Help, Navigation
```

STEP: 5 — Control visibility and enablement via annotations
DESCRIPTION: Use UI.Hidden, CreateHidden, UpdateHidden, DeleteHidden to hide standard buttons or parts of the UI. Use OperationAvailable to control whether action buttons are enabled. Apply these annotations in your annotation file (XML/EDMX) or CDS metadata.
LANGUAGE: XML
CODE:
```xml
<!-- Example UI.Hidden on a property -->
<Annotations Target="YourService.YourEntity/YourProperty">
  <Annotation Term="UI.Hidden" Bool="true"/>
</Annotations>

<!-- Example OperationAvailable on an action -->
<Annotations Target="YourService.YourEntity/Default.ActionName">
  <Annotation Term="UI.OperationAvailable" Bool="false"/>
</Annotations>
```

STEP: 6 — Implement side-effect annotations to refresh dependent fields
DESCRIPTION: Annotate server-side side effects so the front end knows which fields to refresh when a change occurs. This prevents stale UI data by letting the client request updates for influenced properties after backend operations.
LANGUAGE: XML
CODE:
```xml
<!-- Side effect annotation example -->
<Annotations Target="YourService.YourEntity">
  <Annotation Term="Org.OData.Capabilities.V1.SideEffects">
    <!-- Define SourceProperties and EffectedProperties -->
  </Annotation>
</Annotations>
```

STEP: 7 — Message handling: popover vs dialog
DESCRIPTION: Message display location (footer popover vs modal dialog) depends on message state, template (list/object page), and page mode. Ensure backend messages include types/states and review Using Messages docs for behavior.
LANGUAGE: text
CODE:
```text
Behavior depends on:
- Message type (Error/Warning/Info)
- Message state (Transient/Persistent)
- Page template and display/edit mode
```

STEP: 8 — Configure chevron (next-level) navigation and deep linking
DESCRIPTION: Use navigation annotations to configure chevron behavior for table rows. To navigate externally instead of an object page, update navigation annotations. Use Deep Linking (Inbound Navigation) to open object/subobject pages directly.
LANGUAGE: XML
CODE:
```xml
<!-- Example: Navigation to next level (semantic object/action) -->
<Annotations Target="YourService.YourEntity">
  <!-- Navigation annotations linking to semantic objects or target app -->
</Annotations>
```

STEP: 9 — Control outbound navigation and sensitive data
DESCRIPTION: Use Common.SemanticObjectUnavailableActions and semantic object mapping to hide unwanted intents and to map source/target field names. Use handling-sensitive-data guidance to avoid leaking inapplicable or confidential info in navigation contexts.
LANGUAGE: XML
CODE:
```xml
<!-- Example: Hiding actions for a semantic object -->
<Annotations Target="YourService.YourEntity">
  <Annotation Term="Common.SemanticObjectUnavailableActions">
    <!-- List of actions to exclude -->
  </Annotation>
</Annotations>
```

STEP: 10 — Define and secure actions (bound/unbound), parameters, grouping
DESCRIPTION: Use action annotations to declare bound/unbound OData V4 actions or function imports, define parameters (with default values), group actions under menu buttons, and use OperationAvailable to control enablement based on conditions.
LANGUAGE: XML
CODE:
```xml
<!-- Example: Action with parameters -->
<Annotations Target="YourService.YourEntity/ActionName">
  <Annotation Term="Org.OData.Core.V1.Action">
    <!-- Define parameters and defaults -->
  </Annotation>
</Annotations>

<!-- Grouping under menu: define action group annotations in the manifest or annotation file -->
```

STEP: 11 — Filter bar: semantic date operators, defaults, parameterized entities
DESCRIPTION: Enable semantic date/datetime operators (TODAY, TOMORROW), provide default filter values via annotations, and support parameterized entities (e.g., DisplayCurrency) to send parameters (not filters) to the back end.
LANGUAGE: text
CODE:
```text
- Enable semantic operators: annotate filterable date/datetime properties appropriately.
- Default filters: annotate default values for filter bar properties.
- Parameterized entities: declare entity parameters in service and configure filter bar binding to parameters.
```

STEP: 12 — Field value help: ensure text annotations in both field and value help entity
DESCRIPTION: Maintain text annotations on both the property used in the field and on the corresponding property in the value help entity. Avoid pointing text annotation in value help to the same property as the key — use a separate description property.
LANGUAGE: XML
CODE:
```xml
<!-- Wrong Sample Code -->
<Annotations Target="TestService.CategoryType/CatergoryId"><Annotation Term="Common.Text" Path="CategoryId"/></Annotations>

<!-- Correct Sample Code -->
<Annotations Target="TestService.CategoryType/CatergoryId"><Annotation Term="Common.Text" Path="CategoryDescription"/></Annotations>
```

STEP: 13 — Value help validation rules
DESCRIPTION: Value help does not validate arbitrary entries unless specific conditions are met: property type Edm.Guid, Common.IsUnit, Common.IsCurrency, Common.ValueHelpWithFixedValues, or Common.ValueListForValidation are present.
LANGUAGE: text
CODE:
```text
Validation enabled when:
- Edm.Guid OR
- Common.IsUnit OR
- Common.IsCurrency OR
- Common.ValueHelpWithFixedValues OR
- Common.ValueListForValidation
```

STEP: 14 — Tables: default column widths and responsive hiding
DESCRIPTION: From SAPUI5 1.87, default column width calculation and responsive resizing are enabled. Use manifest annotations to set explicit column widths. Use UI.Importance on fields to control which columns hide/move when screen size is reduced.
LANGUAGE: JSON
CODE:
```json
{
  "sap.ui5": {
    "models": { "...": "..." },
    "resources": { "...": "..." },
    "someConfig": {
      "tableColumnWidths": {
        "PropertyA": "200px",
        "PropertyB": "150px"
      }
    }
  }
}
```

STEP: 15 — Charts: OData V4 aggregation behavior
DESCRIPTION: For OData V4, the client must explicitly pass properties as dimensions or measures in chart requests. Ensure backend aggregation capability is enabled and the client sends the required measure/dimension parameters.
LANGUAGE: text
CODE:
```text
OData V2: server infers aggregations.
OData V4: client must declare dimensions/measures explicitly (enable backend aggregation support).
```

STEP: 16 — Object page: facets, dynamic hiding, lazy loading (LongRunners)
DESCRIPTION: Use annotations to add header facets, and to show/hide content. For performance, group long-loading elements under the LongRunners group to defer or separate backend calls.
LANGUAGE: XML
CODE:
```xml
<!-- Example: Add header facet annotation placeholder -->
<Annotations Target="YourService.YourEntity">
  <!-- Facet definitions for object page header -->
</Annotations>

<!-- Example: Mark a request group as LongRunners (pseudo-annotation representation) -->
<Annotations Target="YourService.YourEntity">
  <!-- Loading behavior: group certain requests under 'LongRunners' -->
</Annotations>
```

STEP: 17 — Extensions, building blocks, and key-user adaptation
DESCRIPTION: Use app extensions to inject custom logic while retaining standard behavior. Use building blocks to implement custom sections or free-style apps. Enable key-user adaptation to allow runtime UI customizations.
LANGUAGE: text
CODE:
```text
- Implement app extensions via SAP Fiori elements extension points.
- Use building blocks (sap.fe.macros) for custom-reusable UI fragments.
- Enable key-user adaptation as per Enabling an App for Key User Adaptation docs.
```

STEP: 18 — Automated testing (MockServer + OPA)
DESCRIPTION: Use the MockServer and OPA test library to create OPA tests for OData V4 apps. Mock backend responses, simulate user interactions, and validate flows in list report, object page, and custom extensions.
LANGUAGE: JavaScript
CODE:
```javascript
// Skeleton: start MockServer and OPA tests
// 1) Start mock server with recorded metadata and responses
// 2) Boot the app with mock server endpoint
// 3) Write OPA tests using opaTest, Arrangement, Action, Assertion
```

fiori-elements-framework sapui5 annotations odata-v4 manifest.json navigation actions filter-bar value-help object-page tables charts drafts extensions opa-testing


**TITLE**: Feature Showcase Apps and Samples (SAP Fiori elements for OData V4)

**INTRODUCTION**: Action-oriented reference for obtaining, inspecting, and using SAP Fiori elements feature showcase apps and sample applications (CAP and RAP based). Contains exact repository links and shell commands to clone and inspect repositories. Use these steps to fetch examples, identify relevant files (CDS, annotations, manifest.json, service definitions), and open the SAP Fiori development portal for live examples.

**TAGS**: fiori-elements, OData V4, CAP, RAP, SFLIGHT, samples, feature-showcase, SAPUI5

**STEP**: 1 — Overview: Available repositories and live portal

**DESCRIPTION**: Quick list of the feature showcase and sample repositories provided by SAP-samples and the SAP Fiori development portal URL for live examples. Use these links to fetch source and documentation.

**LANGUAGE**: Shell

**CODE**:
```bash
# Feature showcase (CAP)
https://github.com/SAP-samples/fiori-elements-feature-showcase#readme

# Feature showcase (RAP)
https://github.com/SAP-samples/abap-platform-fiori-feature-showcase#readme

# Sample apps
https://github.com/SAP-samples/cap-sflight#readme
https://github.com/SAP-samples/abap-platform-refscen-flight

# Live examples and documentation
https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/introduction/portal
```

**STEP**: 2 — Clone: Feature showcase based on CAP

**DESCRIPTION**: Clone the CAP-based feature showcase repository locally. After cloning, open the repository README.md for run instructions and examples. Use the following commands to clone and then list top-level files.

**LANGUAGE**: Shell

**CODE**:
```bash
git clone https://github.com/SAP-samples/fiori-elements-feature-showcase.git
cd fiori-elements-feature-showcase
# Inspect README and top-level structure
ls -la
less README.md
```

**STEP**: 3 — Clone: Feature showcase based on RAP

**DESCRIPTION**: Clone the RAP-based feature showcase repository (ABAP platform examples). Open the repository README.md to find platform-specific setup and instructions for ABAP/RAP scenarios.

**LANGUAGE**: Shell

**CODE**:
```bash
git clone https://github.com/SAP-samples/abap-platform-fiori-feature-showcase.git
cd abap-platform-fiori-feature-showcase
ls -la
less README.md
```

**STEP**: 4 — Clone: CAP SFLIGHT sample app

**DESCRIPTION**: Clone the CAP SFLIGHT sample repository. Use the README to follow local setup (CAP tooling, Node, etc.). After cloning, identify CDS models and annotation artifacts.

**LANGUAGE**: Shell

**CODE**:
```bash
git clone https://github.com/SAP-samples/cap-sflight.git
cd cap-sflight
ls -la
less README.md
```

**STEP**: 5 — Clone: RAP SFLIGHT sample app

**DESCRIPTION**: Clone the RAP SFLIGHT repository (ABAP platform reference scenario). Use the repository README for ABAP system setup or transport/import instructions.

**LANGUAGE**: Shell

**CODE**:
```bash
git clone https://github.com/SAP-samples/abap-platform-refscen-flight.git
cd abap-platform-refscen-flight
ls -la
less README.md
```

**STEP**: 6 — Inspect repositories for Fiori elements artifacts

**DESCRIPTION**: Locate key artifacts used by Fiori elements and OData V4 apps: CDS model files (*.cds), annotation files (*.annotations.xml, *.xml), manifest.json files, OData service definitions, and UI app folders. Use these commands to find and preview relevant files in any cloned repo.

**LANGUAGE**: Shell

**CODE**:
```bash
# Run from repository root
# Find CDS models, annotation xml files and manifest.json
find . -type f \( -name "*.cds" -o -name "*.annotations.xml" -o -name "manifest.json" -o -name "*.yaml" -o -name "*.yml" \) -print

# Preview manifest.json (if present)
jq . manifest.json || sed -n '1,200p' manifest.json

# Search for UI annotation or @UI usage in code
grep -R --include="*.cds" --include="*.xml" --include="*.json" -n "@UI\|sap.ui" .

# Inspect local OData service definitions (annotations or metadata)
grep -R --include="*.xml" --include="*.json" -n "<Annotation" "annotations" || true
```

**STEP**: 7 — Open SAP Fiori development portal (live examples)

**DESCRIPTION**: Use the SAP Fiori development portal to view live feature examples and documentation. Open the portal URL in a browser to explore demonstrations and interactive docs for Fiori elements.

**LANGUAGE**: URL

**CODE**:
```text
https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/introduction/portal
```

fiori-elements
OData V4
CAP
RAP
SFLIGHT
samples
feature-showcase
SAPUI5


**TITLE**: Field Help (SAP Fiori elements for OData V4) — Code & Annotation Patterns

**INTRODUCTION**: This reference shows how to configure field help behaviors in SAP Fiori elements (OData V4): value help, dropdown lists, date picker, date/time picker, timezone handling, history of recently entered values, and type-ahead. Use the provided XML/CDS/ABAP snippets to generate correct metadata and UI behavior.

**TAGS**: fiori-elements-framework, odata-v4, annotations, value-help, dropdown, date, datetime, timezone, CAP, ABAP, XML, CDS, UI.Importance, Common.Timezone

STEP: Applicability / Quick summary
DESCRIPTION: Field help features described here apply only to SAP Fiori elements for OData V4. Fields can be associated with value help, fixed-value dropdowns, date pickers, or date/time pickers depending on type and annotations.
LANGUAGE: N/A
CODE:
```text
Applicable scenario: SAP Fiori elements for OData V4
Field help types: value help, dropdown (fixed values), date picker, date/time picker, dynamic semantic date options
```

STEP: Value Help
DESCRIPTION: Value help allows users to select a value from a value-help entity or define a condition to fetch a value. Configure value help entities and annotations to control dialog and type-ahead columns (see UI.Importance). See linked documentation for full configuration of value help entities and dialogs.
LANGUAGE: N/A
CODE:
```text
See "Value Help" topic (value-help-fccb255.md) for entity configuration, dialog layout, and usage.
```

STEP: Dropdown-Based Fields (fixed values)
DESCRIPTION: Use a dropdown list for fields with fixed values. Configure fixed-value value help in metadata so the UI renders a dropdown instead of a full value-help dialog.
LANGUAGE: N/A
CODE:
```text
Behavior: If the value help entity provides only fixed values, the field is rendered as a dropdown list.
See "Value Help as a Dropdown List" (value-help-as-a-dropdown-list-2a0a630.md) for configuration details.
```

STEP: Date Picker — Edm.Date fields
DESCRIPTION: For properties of type Edm.Date used outside a filter context, the UI renders a date picker. In filter contexts the field help depends on filter restrictions and may render a date picker, value help, or dynamic semantic date options.
LANGUAGE: XML
CODE:
```xml
<EntityType Name="SalesOrderManage">
   <Property Name="SalesOrderDate" Type="Edm.Date"/>
</EntityType>
```

LANGUAGE: CDS
CODE:
```cds
entity SalesOrderManage {
     SalesOrderDate : Date;
}
```

LANGUAGE: ABAP CDS
CODE:
```text
No ABAP CDS sample provided. Use DATS data type in CDS view or DB table to generate Edm.Date metadata.
```

STEP: Date/Time Picker — Edm.DateTimeOffset fields
DESCRIPTION: For Edm.DateTimeOffset fields used outside filter contexts, the UI renders a date/time picker. In filter contexts behavior depends on filter restrictions (date/time picker, value help, or semantic date options). The UI displays and converts DateTimeOffset values to the UI timezone (SAPUI5 behavior). You can also specify fixed or property-based timezone annotations to display the timezone in edit and display modes.
LANGUAGE: XML
CODE:
```xml
<EntityType Name="SalesOrderManage">
    <Property Name="LastChangedDateTime" Type="Edm.DateTimeOffset"/>
</EntityType>
```

LANGUAGE: CDS
CODE:
```cds
entity SalesOrderManage {
       SalesOrderDate : DateTime;
}
```

LANGUAGE: ABAP CDS
CODE:
```text
No ABAP CDS sample provided for Edm.DateTimeOffset. Use TIMESTAMP data type in CDS view or DB table.
```

STEP: Timezone — Fixed Timezone (Common.Timezone)
DESCRIPTION: To show a fixed IANA timezone for a DateTime field, set the Common.Timezone annotation to a fixed string. This displays the timezone in the input (edit) and text (display) fields.
LANGUAGE: XML
CODE:
```xml
<EntityType Name="SalesOrderManage">
    ...
    <Property Name="testTimeFixed" Type="Edm.DateTimeOffset"/>
    ...
</EntityType>

<Annotations Target="com.c_salesordermanage_sd.SalesOrderManagerManage/testTimeFixed">
    <Annotation Term="Common.Timezone" String="Asia/Riyadh"/>
    <Annotation Term="Common.Label" String="Timestamp with fixed timezone"/>
</Annotations>
```

LANGUAGE: CDS
CODE:
```cds
entity SalesOrderManage {
…
testTimeFixed  : DateTime @Common : { Timezone : 'Asia/Riyadh' };
…
}
```

STEP: Timezone — Timezone Based on Another Property
DESCRIPTION: To derive the timezone value dynamically from another property, set Common.Timezone to the Path of that property. In ABAP CDS use semantics annotations to link timezone reference and timezone properties.
LANGUAGE: XML
CODE:
```xml
<Annotations Target="com.c_salesordermanage_sd.SalesOrderManage/testTime">
   <Annotation Term="Common.Timezone" Path="testTimezone"/>
   <Annotation Term="Common.Label" String="Datetime Stamp with Timezone based on Property"/>
</Annotations>

<Annotations Target="com.c_salesordermanage_sd.SalesOrderManager/testTimezone">
   <Annotation Term="Common.Label" String="Timezone Property"/>
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
@Semantics.timeZoneReference: 'MySAPTimezone'
MyDateTime,

@Semantics.timeZone
MySAPTimezone,
```

LANGUAGE: CDS
CODE:
```cds
entity SalesOrderManage {
    testTime : DateTime @Common : { Timezone : testTimezone };
}
```

STEP: History of Recently Entered Values
DESCRIPTION: Enable "history of recently entered values" (saves previous entries and shows them when the field is focused). The list filters on typing and is not shown when empty. Not supported for value help based on fixed values. Enable by setting the INPUTFIELD_HISTORY parameter in the SAP Fiori launchpad configuration.
LANGUAGE: N/A
CODE:
```text
Enable in Fiori launchpad:
- Parameter name: INPUTFIELD_HISTORY
- Behavior: Stores/returns recently entered values per user; displayed on focus; filtered while typing.
- Limitation: Not available for value help based on fixed values.
```

STEP: Type-Ahead Support ($search and UI.Importance)
DESCRIPTION: Value-help-enabled fields provide type-ahead suggestions fetched from the backend using the $search parameter. Control which columns appear in the type-ahead list with UI.Importance: only properties annotated with UI.Importance = High are shown. If UI.Importance is not defined, the type-ahead list shows the same columns as the value help dialog. Type-ahead is disabled if the value help entity is configured as non-searchable.
LANGUAGE: N/A
CODE:
```text
Type-ahead mechanics:
- Client uses OData $search on the value help entity.
- Use UI.Importance annotation:
    - UI.Importance = High -> shown in type-ahead
    - No UI.Importance -> same columns as value help dialog
- Disabled if the value help entity is non-searchable (see service/entity configuration).
```

fiori-elements-framework odata-v4 annotations value-help dropdown date datetime timezone CAP ABAP XML CDS UI.Importance Common.Timezone


**TITLE**: Finding the Right Anchor Key for SAP Fiori elements (OData V4)

**INTRODUCTION**: Identify DOM anchor keys using the browser developer tools so you can set manifest position.anchor values to place custom UI (header facets, header fields, table columns, sections/subsections) correctly in SAP Fiori elements (OData V4). Use the DOM element inspector and $metadata response to derive the exact anchor strings.

**TAGS**: fiori-elements-framework, sap, odata-v4, anchor, manifest.json, developer-tools, DOM, table, header, facet, column

**STEP**: 1 — Open browser developer tools

**DESCRIPTION**: Open the browser DevTools to inspect DOM elements and network $metadata responses.

**LANGUAGE**: Text

**CODE**:
```text
Windows:  CTRL + SHIFT + I
macOS:    CMD + OPT + I
```

**STEP**: 2 — Find anchors for the Header Facet

**DESCRIPTION**: In the DOM inspector search for the string "fe::HeaderFacetContainer" (for standard header facets) or "fe::HeaderFacetCustomContainer" (for custom header facets). The name shown immediately after that string is the facet key to use as position.anchor.

Example: derive anchor "AnchorHeaderFacetName" from the element ID.

**LANGUAGE**: HTML

**CODE**:
```html
AppName::AppNameObjectPage--fe::HeaderFacetContainer::AnchorHeaderFacetName
// position.anchor to use: "AnchorHeaderFacetName"
```

**STEP**: 3 — Find anchors for a Header Facet Field

**DESCRIPTION**: To place a custom header field inside a specific header facet, search the DOM for "fe::HeaderFacet::Form". Fields use key pattern "DataFieldAbstractType::PropertyName". Use that string as position.anchor. The key combines the field type and the property name (commonly "DataField::PropertyName").

**LANGUAGE**: HTML

**CODE**:
```html
AppName::AppNameObjectPage--fe::HeaderFacet::Form::HeaderFacetName::DataField::PropertyName::Field
// position.anchor to use: "DataField::PropertyName"
```

**STEP**: 4 — Find anchors for a Table Column (custom or standard)

**DESCRIPTION**: Two tasks: (A) locate the column element ID prefix in the DOM; (B) find the column record type in the $metadata response (UI.LineItem) to compose the key as DataFieldAbstractType::ColumnName.

- (A) DOM: search for the prefix "fe::table::AppName::LineItem::C::" (replace AppName). The full element ID appends the column name or annotation path.
- (B) Metadata: inspect the $metadata XML response and find the <Annotation Term="UI.LineItem"> section to determine the Record Type (DataField, DataFieldForAction, DataFieldForAnnotation, etc.) and property/path.

The final position.anchor pattern: DataFieldAbstractType::ColumnName (or include annotation path segments like DataFieldForAnnotation::FieldGroup::multipleFields). For custom columns defined in manifest.json columns collection, use the custom column key directly.

**LANGUAGE**: HTML

**CODE**:
```html
// DOM examples (replace AppName):
fe::table::AppName::LineItem::C::PersonName
fe::table::AppName::LineItem::C::FieldGroup::multipleFields
```

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="UI.LineItem">
    <Collection>
        <Record Type="UI.DataField">
            <PropertyValue Property="Value" Path="PersonName"/>
        </Record>
        <Record Type="UI.DataFieldForAction">
            <PropertyValue Property="Action" String="ChangePresence"/>
        </Record>
        <Record Type="UI.DataFieldForAnnotation">
            <PropertyValue Property="Target" AnnotationPath="@UI.FieldGroup#multipleFields"/>
        </Record>
        ...
    </Collection>
</Annotation>
```

**LANGUAGE**: Text

**CODE**:
```text
// Example composed anchor keys:
DataField::PersonName
DataFieldForAction::ChangePresence
DataFieldForAnnotation::FieldGroup::multipleFields

// For custom columns: use the custom column key defined in manifest.json -> columns collection.
```

**STEP**: 5 — Find anchors for Section or Subsection

**DESCRIPTION**: In the DOM inspector search for "fe::FacetSection" (section) or "fe::FacetSubSection" (subsection). The name immediately after that string is the facet key to use as position.anchor.

**LANGUAGE**: HTML

**CODE**:
```html
AppName::AppNameObjectPage--fe::FacetSection::AnchorSectionFacetName
// position.anchor to use: "AnchorSectionFacetName"
```

fiori-elements-framework sap odata-v4 anchor manifest.json developer-tools DOM table header facet column


**TITLE**: Flexible Programming Model for SAP Fiori elements (OData V4)

**INTRODUCTION**: Practical guide for extending SAP Fiori elements OData V4 apps using the Flexible Programming Model. Covers where to place extension code, how to implement extension points, how to register controller extensions in the manifest, and how to treat pages as custom pages on the Fiori elements framework. Use these patterns when you need custom UI5 controls, controller logic, or full custom pages while retaining Fiori elements capabilities.

**TAGS**: fiori-elements, sapui5, flexible-programming-model, extension-points, controller-extensions, custom-pages, odata-v4

**STEP**: 1 — Where to add extensions

**DESCRIPTION**: Place extension fragments, controllers, and manifest changes inside your app's webapp directory. Common locations:
- webapp/manifest.json — manifest changes and controller extension registration
- webapp/ext/ — extension fragments and views
- webapp/ext/controller/ — controller extension implementations

This keeps customizations separate from generated Fiori elements artifacts and makes upgrades simpler.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "webapp/manifest.json": {
    "description": "Place manifest modifications here to register controller extensions and custom targets. Keep path webapp/ext/... for extension artifacts."
  }
}
```

**STEP**: 2 — Add an XML extension point (UI fragment)

**DESCRIPTION**: Use sap.ui.core.ExtensionPoint in the host view where Fiori elements exposes an extension point. Provide the fragment implementing UI additions in webapp/ext/. Example fragment file and how the host view will include it via an ExtensionPoint (the host view is typically provided by the framework; you supply the fragment named by the extension point).

- Create fragment at: webapp/ext/fragments/CustomActions.fragment.xml
- Use the ExtensionPoint name defined by the template (example name used below)

**LANGUAGE**: XML

**CODE**:
```xml
<!-- webapp/ext/fragments/CustomActions.fragment.xml -->
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
  <Button text="Custom Action" press=".onCustomAction"/>
</core:FragmentDefinition>

<!-- Example usage in a host view (framework provides the ExtensionPoint location) -->
<!-- Host view contains something like:
<core:ExtensionPoint name="HeaderActionButtons" />
-->
```

**STEP**: 3 — Register a controller extension in manifest.json

**DESCRIPTION**: Map the Fiori elements controller you want to extend to your extension controller implementation using sap.ui.controllerExtensions. Place this mapping inside webapp/manifest.json under sap.ui5 → extends → extensions → sap.ui.controllerExtensions. This tells the framework to call your controller methods in addition to the base controller.

- Add mapping in: webapp/manifest.json
- Implement controller at: webapp/ext/controller/ObjectPageExt.controller.js (or a matching name)

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui5": {
    "extends": {
      "extensions": {
        "sap.ui.controllerExtensions": {
          "sap.fe.templates.ObjectPage.controller.ObjectPageController": {
            "controllerName": "my.app.ext.controller.ObjectPageExt"
          }
        }
      }
    }
  }
}
```

**STEP**: 4 — Implement the controller extension

**DESCRIPTION**: Implement the extension controller methods referenced by UI fragments or used to hook into lifecycle events. Export a standard UI5 controller module with your logic. Keep file under webapp/ext/controller/ and match the controllerName specified in the manifest mapping.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
// webapp/ext/controller/ObjectPageExt.controller.js
sap.ui.define(["sap/ui/core/mvc/Controller"], function(Controller) {
  "use strict";
  return Controller.extend("my.app.ext.controller.ObjectPageExt", {
    onInit: function() {
      // initialization logic for your extension controller
    },

    onCustomAction: function(oEvent) {
      // handler invoked by extension fragment button press
      // implement custom navigation, data modification, or dialog opening here
    }
  });
});
```

**STEP**: 5 — Treat pages as custom pages on the Fiori elements framework

**DESCRIPTION**: If you require a fully custom page while still running on the Fiori elements framework, implement the page as a custom target in your manifest routing/targets and register it as a Component or View. Keep routing and component names consistent and place the custom page under webapp/ext/custompages/. This lets you use any UI5 controls while still using the Fiori elements shell/bootstrapping.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui5": {
    "routing": {
      "targets": {
        "CustomPage": {
          "type": "View",           /* or "Component" if you build a component-based page */
          "name": "my.app.ext.custom.CustomPage", /* namespace of the view/component */
          "viewPath": "my.app.ext.custom",
          "viewName": "CustomPage"
        }
      }
    }
  }
}
```

**STEP**: 6 — Reference resources and building blocks

**DESCRIPTION**: Use the building blocks and examples to implement common UI patterns while using extension points or controller extensions for custom behavior. See the Fiori development portal for live examples and deeper guidance. Also review local documentation file references.

**LANGUAGE**: Markdown/Links

**CODE**:
```markdown
- Live examples and introduction: https://ui5.sap.com/test-resources/sap/fe/core/fpmExplorer/index.html#/topic/introduction
- Local related info: webapp/docs/building-blocks-24c1304.md (Building Blocks)
```

fiori-elements sapui5 flexible-programming-model extension-points controller-extensions custom-pages odata-v4


**TITLE**: Form Entry Object Page (SAP Fiori elements for OData V4)

**INTRODUCTION**: Configure a Form Entry Object Page to provide a page-only data-entry UI (no object page header or navigation bar). Includes manifest target settings, automatic startup-in-create-mode via Component.js, and single-draft-for-create behavior configuration both via manifest and via the EditFlow controller extension. Applicable only to SAP Fiori elements for OData V4.

**TAGS**: fiori-elements-framework, odata-v4, manifest.json, Component.js, singleDraftForCreate, EditFlow, object-page, form-entry

**STEP**: 1 — Configure a Form Entry Object Page target

**DESCRIPTION**: Add a target to your application descriptor (manifest) to use the Object Page component while hiding the header and anchor/navigation bar to produce a form-entry-only page. Place this under the appropriate targets section in manifest.json (for example, "sap.app"/"crossNavigation"/"inbounds" or "sap.ui5"/"routing"/"targets" depending on your project structure).

**LANGUAGE**: JSON

**CODE**:
```json
"FormRootObjectPage": {
    "type": "Component",
    "id": "FormRootObjectPage",
    "name": "sap.fe.templates.ObjectPage",
    "options": {
        "settings": {
            "contextPath": "/FormRoot",
            "editableHeaderContent": false,
            "content": {
                "header": {
                    "visible": false,
                    "anchorBarVisible": false
                }
            }
        }
    }
}
```

**STEP**: 2 — Auto-start application in creation mode (main application Component.js)

**DESCRIPTION**: If you want the app to start directly in creation mode, implement getStartupParameters in your main application Component.js to return a preferredMode of ["create"]. Add this method to your AppComponent extension. Keep this file at your Component.js path (e.g., src/Component.js).

**LANGUAGE**: JavaScript

**CODE**:
```javascript
getStartupParameters: function() {
    return Promise.resolve({
        preferredMode: ["create"]
    });
}

Such as

sap.ui.define(["sap/fe/core/AppComponent"], function(AppComponent)
    "use strict";

    return AppComponent.extend("FormTemplate.Component", {
        metadata: {
            manifest: "json"
        },
        getStartupParameters: function() {
            return Promise.resolve({
                preferredMode: ["create"]
            });
        }
    });
});
```

**STEP**: 3 — Enable singleDraftForCreate in manifest.json

**DESCRIPTION**: Prevent users from creating multiple drafts by enabling singleDraftForCreate in the "sap.fe.app" section of manifest.json. When true, the app checks for existing drafts (entities with IsActiveEntity=false and HasActiveEntity=false). If a draft exists, it opens that draft in edit mode instead of creating a new one.

File: manifest.json — add or update the "sap.fe" -> "app" section.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.fe": {
    "app": {
        "singleDraftForCreate": true
    }
}
```

**STEP**: 4 — Enable singleDraftForCreate via EditFlow controller extension

**DESCRIPTION**: As an alternative or complement to the manifest setting, enable singleDraftForCreate when creating documents via the EditFlow extension. Use editFlow.createDocument and pass the option { singleDraftForCreate: true } so the app will open an existing unsaved draft in edit mode if one exists; otherwise it creates a new entity in edit mode.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
editFlow.createDocument(ListBinding, {singleDraftForCreate: true})
```