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. For
more information, see Using the extensionAPI.
After you've created an app extension, its display (for example, control
placement and layout) and system behavior (for example, model and binding usage,
busy handling) lies within the application's responsibility. SAP Fiori elements
provides support only for the official extensionAPI
functions.
Don't access or manipulate controls, properties, models, or other internal
objects created by the SAP Fiori elements
framework.
For global actions, you do not have to select a line in the list report table. This type of action refers to the whole list report, for example, Display Log. Global actions are placed in the list report filter bar next to the Share button.
In SAP Fiori elements for OData V4, footer bar actions are available only on the object page.
.controller.js
file for your extension.
In the code sample below, we assume the following:
App name: my_app
File names: MyListReportExt.controller.js
(extending the
ListReport
controller), MyObjectPageExt.controller.js
(extending
the MainObjectPage
controller), MySubObjectPageExt.controller.js
(extending the SubObjectPage
controller). Individual Controller extensions can be
created for each object page. For more information, see Extending SAP Fiori Elements-Based Apps.
my_app/webapp/ext/controller
ListReport
controller, your controller extension should look
like this:
sap.ui.define([], function() { return { onCustomAction1 : function(oEvent) { … }, onCustomAction2 : function(oEvent) { … }, … } })
When implementing the handler functions for your custom actions, you must use the Using the extensionAPI.
manifest.json
file
In your app's manifest.json
file, under sap.ui5 → extends → extensions
, you can
specify extensions for the ListReport
and the ObjectPage
controllers.
Specify the following information and extend the manifest files as described below:
|
Entity set that is displayed on the list report or on the object page (for example,
Note
If you use multiple views with different |
|
Action names |
|
ID to be used for the action button
Note
The values of the action name and the ID should be identical. |
|
nullText to be displayed on the button (typically a binding to an i18n entry, for example,
null<button text>nullnull |
|
Handler function that is called when the user selects the action button |
|
Indicates whether this is a global action. The default value is
Note
If a determining property is set along with the global property, the action is rendered as a global action since this takes precedence. |
Relevant only for table toolbar actions in the list report and object page:
|
Property that indicates whether the action requires a selection of items. The default value is
|
Relevant only for list report actions and object page header actions:
|
Property that indicates whether the action should be displayed in the footer of the
page.
The default value is |
Relevant only for object page actions: |
ID that either comes from the annotation in which you have provided an ID for the facet or that's made up of the annotation term plus the navigation property. For example: <entity type association>::com.sap.vocabularies.UI.v1.LineItem |
|
Determines if a custom action should be visible or enabled. |
|
Represents the command mapped to a keyboard shortcut defined under
Note
If you are adding the command settings to an existing custom action, the parameter i.e.,
You must not use a keyboard shortcut that is provided by default as custom action keyboard shortcut. For example, Ctrl E , Ctrl Enter and all other default keyboard shortcut should not be overridden. |
Table toolbar action for the list report
... "extends": { "extensions": { "sap.ui.commands": { "<ComponentName>#<Component ID without app ID prefix>": { "<CustomActionCommandName>": { "shortcut": "Ctrl+G" } } }, "sap.ui.controllerExtensions": { "sap.suite.ui.generic.template.ListReport.view.ListReport": { "controllerName": "my_app.ext.controller.ListReportExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Actions": { "<Action 1>": { "id": "<id>", "text": "<button text>", "press": "<handler function>", "requiresSelection": <true| false >, "applicablePath": <path>, "command": "<CustomActionCommandName>" }, "<Action 2>": { ... }, ... } ... } } } } } }
An example of <ComponentName>#<Component ID without app ID prefix>
is
sap.suite.ui.generic.template.ListReport#sap.suite.ui.generic.template.ListReport::STTA_C_MP_Product
.
In order to construct this string, you need the following information:
<ComponentName>
: You can use the component name used in the pages structure
of sap.ui.generic.app
namespace in the manifest. For example,
sap.suite.ui.generic.template.ListReport
.
<Component ID without app ID prefix>
: You can get the corresponding component first,
that can be fetched in the following ways:
Using the corresponding xml view
For example,
Element.getElementById('STTA_MP::sap.suite.ui.generic.template.ListReport.view.ListReport::STTA_C_MP_Product').getController().getOwnerComponent().getId()
where
STTA_MP::sap.suite.ui.generic.template.ListReport.view.ListReport::STTA_C_MP_Product
is the XmlView
ID, and Element
is required from
module sap/ui/core/Element
.
Using ComponentContainer
Element.getElementById('__xmlview0-__clone0--host').getComponent()
where __xmlview0-__clone0--host
is the
ComponentContainer
ID, and Element
is requred
from module sap/ui/core/Element
.
The result is generated in this <app component prefix>---<local component
ID>
format. For example,
application-EPMProduct-manage_st-component---sap.suite.ui.generic.template.ListReport::STTA_C_MP_Product
.
You can remove the app component prefix from the string along with the dashes.
Action for the object page header
... "extends": { "extensions": { "sap.ui.commands": { "<ComponentName>#<Component ID without app ID prefix>": { "<CustomCommandName>": { "shortcut": "Ctrl+K" } } }, "sap.ui.controllerExtensions": { ... "sap.suite.ui.generic.template.ObjectPage.view.Details#my_app::sap.suite.ui.generic.template.ObjectPage.view.Details:: <entity set>": { "controllerName": "my_app.ext.controller.DetailsExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Header" : { "Actions": { "<Action 1>": { "id" : "<id>", "text" : "<button text>", "press" : "<handler function>" "applicablePath": <path>, "command": "<CustomCommandName>" }, "<Action 2>": { ... } } }, ...
Table toolbar action for the object page
... "extends": { "extensions": { "sap.ui.controllerExtensions": { ... "sap.suite.ui.generic.template.ObjectPage.view.Details#my_app::sap.suite.ui.generic.template.ObjectPage.view.Details:: <entity set>": { "controllerName": "my_app.ext.controller.DetailsExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Sections": { "<SmartTable Facet ID>": { "id" : "<SmartTable Facet ID>", "Actions": { "<SmartTable Action 1>": { "id" : "<id>", "text" : "<button text>", "press" : "<handler function>", "applicablePath": <path>, "requiresSelection": <true|false> }, "<SmartTable Action 2>": { ... } } ...
Form action for the object page
... "extends": { "extensions": { "sap.ui.controllerExtensions": { ... "sap.suite.ui.generic.template.ObjectPage.view.Details": { "controllerName": "my_app.ext.controller.DetailsExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Sections": { "<Form Facet ID>": { "id": "<Form Facet ID>", "Actions": { "<Action 1>": { "id" : "<id>", "text" : "<button text>", "press" : "<handler function>" "applicablePath": <path>, }, "<Action 2>": { ... } } ...
Footer bar action in the list report:
"sap.ui5": { "extends": { "extensions": { "sap.ui.controllerExtensions": { "sap.suite.ui.generic.template.ObjectPage.view.Details#my_app::sap.suite.ui.generic.template.ObjectPage.view.Details:: <entity set>": { "controllerName": "my_app.ext.controller.ListReportExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Actions": { "<Action 1>": { "id": "<id>", "text": "<button text>", "press": "<handler function>", "determining": true } } } } } } } } }
Please note that this feature is deprecated. SAP Fiori elements supports this feature only for compatibility reasons. We recommend that you avoid using determining buttons.
Footer bar action in the object page:
"sap.ui5": { "extends": { "extensions": { "sap.suite.ui.generic.template.ObjectPage.view.Details#my_app::sap.suite.ui.generic.template.ObjectPage.view.Details:: <entity set>": { "sap.suite.ui.generic.template.ObjectPage.view.Detail": { "controllerName": "my_app.ext.controller.DetailsExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Header": { "Actions": { "<Action 1>": { "id": "<id>", "text": "<button text>", "press": "<handler function>", "applicablePath": <path>, "determining": true } } } } } } } } } }
List report (global action)
... "extends": { "extensions": { "sap.ui.controllerExtensions": { "sap.suite.ui.generic.template.ListReport.view.ListReport": { "controllerName": "my_app.ext.controller.ListReportExtension", "sap.ui.generic.app": { "<entity set>": { "EntitySet": "<entity set>", "Actions": { "<Action 1>": { "id" : "<id>", "text" : "<button text>", "press" : "<handler function>", "global": <true|false> }, "<Action 2>": { ... }, ... } ...
manifest.json
file.
In your app's manifest.json
file, under sap.ui5 → routing → targets → <target name> →
options → settings → controlConfiguration → <control> → actions
, or in the footer, add actions as
follows:
XML Annotation
"<Action name>": { "press": "<handler function>", "visible": <true|false|handler function>, "enabled": <true|false|handler function>, "text": "<button text>", "position": { "placement": <"Before"|"After">, "anchor": "<Anchor action name>" } }
manifest.json
"myCustomEnablement": { "press": "SalesOrder.ext.CustomActions.navigateExternal", "enabled": "SalesOrder.ext.CustomActions.enabledForCompletedOnly", "text": "Enabled for Completed" }
Example for Handler Function:
enabledForCompletedOnly: function(oBindingContext, aSelectedContexts) { if (aSelectedContexts && aSelectedContexts.length === 1) { return true; } return false; }
Property | Description |
---|---|
|
Name of the custom action |
|
Handler function that is called when the user selects the action button It is of the format |
|
Text to be displayed on the button (typically a binding to an i18n entry, for example
|
|
Name of another action with reference to which this action should be placed. Here are some examples:
Sample Code
Hidden "position": { "placement": "Before", "anchor": "DataFieldForAction::Action" } This places the current action before the
Sample Code
Hidden "position": { "placement": "After", "anchor": "DataFieldForIntentBasedNavigation::SO::Action" } This places the current action after the |
"controlConfiguration": { "<NavigationPropertyFromRootEntityType>/@com.sap.vocabularies.UI.v1.LineItem": { "actions": { "myCustomAction": { "press": "TestApplication.ext.CustomActions.message" .... } } } }
The signature of the method message looks as follows:
sap.ui.define( [], function () { "use strict"; return { message: function (oContext, aSelectedContexts) { // oContext : is the binding context of the current entity // aSelectedContexts : contains an array of binding contexts corresponding to // selected items in case of table action (or) // alert("message"); }, }; } );
Table toolbar action for the list report
{ "sap.ui5": { "routing": { "targets": { "<ListReportTargetName>": { "options": { "settings": { "controlConfiguration": { "@com.sap.vocabularies.UI.v1.LineItem": { "actions": { "<ActionName>": { "press": "<ApplicationId.FolderName.ScriptFilename.methodName>", "text": "<button text>", "enabled": <true|false|handler function>, "visible": <true|false|handler function> } } } } } } }
Action for the object page header
{ "sap.ui5": { "routing": { "targets": { "<ObjectPageTargetName>": { "options": { "settings": { "content": { "header": { "actions": { "<ActionName>": { } } } } } } } } } } }
Table toolbar action for the object page
"sap.ui5": { "routing": { "targets": { "<ObjectPageTargetName>": { "options": { "settings": { "controlConfiguration": { <NavigationPropertyFromRootEntityType>/@com.sap.vocabularies.UI.v1.LineItem": { "actions": { "<ActionName>": { } } } } } } } } } }
Footer bar action in the object page:
"sap.ui5": { "routing": { "targets": { "<ObjectPageTargetName>": { "options": { "settings": { "content": { "footer": { "actions": { "<ActionName>": { ... } } } } } } } } } }
List report (global action)
"sap.ui5": { "routing": { "targets": { "<ListReportTargetName>": { "options": { "settings": { "content": { "header": { "actions": { "<ActionName>": { ... } } } } } } } } } }
Section action
To define a custom action in a section, you must extend the controlConfiguration
of any of the
FieldGroups
in that section with an actions block in a structure as follows:
"sap.ui5": { "routing": { "targets": { "SalesOrderManageObjectPage": { "options": { "settings": { "enhanceI18n": "i18n/SalesOrderObjectPage.properties", "controlConfiguration": { "@com.sap.vocabularies.UI.v1.FieldGroup#OrderData": { "actions": { "customSectionAction": { "press": "SalesOrder.ext.CustomActions.alert", "visible": true, "enabled": true, "text": "Alert", "position": { "placement": "After", "anchor": "DataFieldForIntentBasedNavigation::SalesOrder::manageInline" } }, "sectionAction2": { "press": "SalesOrder.ext.CustomActions.accountDetails", "visible": true, "enabled": true, "text": "Display account details", "position": { "placement": "Before", "anchor": "customSectionAction" } } } } } } } } } } }
Form toolbar action
When you set inline=true
, a given action from a FieldGroup
shows up directly in the form
toolbar instead of the section toolbar.
"sap.ui5": { "routing": { "targets": { "SalesOrderManageObjectPage": { "options": { "settings": { "controlConfiguration": { "@com.sap.vocabularies.UI.v1.FieldGroup#OrderData": { "actions": { "customSectionAction": { "press": "SalesOrder.ext.CustomActions.alert", "visible": true, "enabled": false, "text": "Action on Form", "inline": true }, "customSectionAction2": { "press": "SalesOrder.ext.CustomActions.alert", "visible": true, "enabled": true, "text": "Action not on Form" } } } } } } } } } }
You can explore and work with the coding yourself. Check out our live example in the flexible programming model explorer at Custom Action.