ABAP RESTful Application Programming Model (RAP) based SAP Fiori Elements app, gives developer the opportunity to create UI5 apps with minimum (or most of the times with none) front-end code. This includes the benefits of out-of-the box UI5 application features (like value help, filter bar, object page etc.) and standard layout across other apps in FLP.
As a developer, this takes us away from the front end coding or more into back-end programming using CDS and annotations. However, there are rare occurrences when its required to implement features which could be as simple as a piece of cake in a custom UI5 app (true for a pro UI5 app developer) and could be a equally hard task via SAP Fiori Elements.
Then come to our rescue the Flexible Programming Model for SAP Fiori Elements app. There is a detailed help documentation available on possible Extension points, building blocks and controller extension with some executable examples and code snippets. This also documents some added features which can be used to enhance the app.
However, enhancing the app with breakouts comes with additional coding required to keep the custom part of the app in sync with the standard auto generated sections,mostly in terms of User Experience. Just for an example, to achieve same kind of value help features in the breakout code as compared to the SAP Fiori Elements generated standard value help, will require a heavy set of front-end code as well as high maintenance to keep up with the evolving features of the SAP Fiori Elements.
What if there was a way to create custom sections comprising all the SAP Fiori Elements delivered features. This can be made possible using sap.fe.macros.
Using sap.fe.macros instead of custom UI5 element will help reuse the SAP Fiori Elements features. For e.g., if the entity property is linked to a value help(via CDS annotation), the UI will render the value help with no additional coding.
Implementation
Say in the SAP Fiori Elements app there is a requirement to develop a custom fragment which contains some input fields.
These input fields can be directly associated to the field(property) of the OData entity using sap.fe.macros.Field instead of using sap.m.input custom control.
UI Rendering
- Define the xml UI
- the Fragment should look something like this
<core:FragmentDefinition ...... xmlns:macros="sap.fe.macros"> ...... <macros:Field id="myMacroField" metaPath="<nameOfTheEntityProperty>" readOnly="false" change="onChangeMyMacroField" </macros:Field> </core:FragmentDefinition>
where,
- the Fragment should look something like this
-
-
- id(string) : is the identifier of the Field control
-
metaPath(string) : is the relative path of the property in the metamodel, based on the current contextPath
-
readOnly(boolean) : allows us to control the read-only state of the field
- change : an event containing details is triggered when the value of the field is changed
-
- In the controller, at fragment loading,
- create a temporary context binding for the entity (same entity whose property was specified in the sap.fe.macros.Field property metadata)
var oBinding = this.base.getExtensionAPI() .getModel() .bindList("/<ContextPathOfTheEntity>", null, [], [], { $$updateGroupId: "noSubmit", $$groupId: "noSubmit" } );
arguments for bindList,
- sPath(string) : path pointing to the entity that should be bound
- oContext(sap.ui.model.Context) : context object for this databinding
- aSorters(sap.ui.model.Sorter | sap.ui.model.Sorter[ ]) : Initial sort order
- aFilters(sap.ui.model.Filter | sap.ui.model.Filter[ ] ) : Predefined filter/s
- mParameters(object) : additional batch call related parameters
- create a temporary context binding for the entity (same entity whose property was specified in the sap.fe.macros.Field property metadata)
-
- Next, bind the above created binding to the macro element control
oMacroElement.setBindingContext(oBinding.create({}));
- Next, bind the above created binding to the macro element control
- That’s it, the UI will render the sap.fe.macros.Field as an input list , or as a value list or as a checkbox field, as defined in the CDS entity
Reading the value from UI
- The control for the sap.fe.macros.Field is bound to the the entity instance and from here the property can be read
var oEntity = oMacroElement.getBindingContext().getObject();
In the above example the value can be read from oEntity.<nameOfTheEntityProperty>
Error Handling
- To add a custom errors (for any front-end validations) , can be achieved using addMessage method of the sap.fe.macros control
oCreateJobDefinitionAPJ.addMessage({ description: "Some description", message: "Some Error", persistent: false, type: sap.ui.core.MessageType.Error });
arguments for addMessage,
- parameters(object)
- description(string): Message description
- message(string): Message text
- persistent(boolean): True if the message is persistent
- type(sap.ui.core.MessageType): Type of the message
- parameters(object)
- To clear the messages, the change event of the sap.fe.macros.Field can be used.
Conclusion
Through this blog I have shared the concept of sap.fe.macros implementation in SAP Fiori elements breakouts and reusing the features provided by SAP Fiori elements. Basically, a hybrid solution with minimum amount of code. I would encourage you to try using sap.fe.macros elements, next time you work on SAP Fiori elements breakouts.
Please feel free to share your valuable feedback by liking this blog, adding your thoughts / queries in the comment section below. You may also reach out to bigger audience with your queries in SAP community questions.
References
- ABAP RESTful Application Programming Model (RAP)
- help documentation
- related posts can be found here
- some helpful Q&A
- Help documentation for
- sap.fe.macros.Field – The Field Building Block
- bindlist method of sap.ui.model.Model
- Batch Control in bindlist.mParameters.groupId
- Flexible Programming Model Explorer
- To retrieve controls from a Fragment, please refer to this nice blog