Skip to Content
Technical Articles
Author's profile photo Sumesh Nair

SAP Fiori Elements: Breakout with sap.fe.macros

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,

      • 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
    • Next, bind the above created binding to the macro element control
       oMacroElement.setBindingContext(oBinding.create({}));​
  • 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
  • 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

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Tristan Heisecke
      Tristan Heisecke

      Hi Sumesh,

      thank you very much for your informative blog. Seeing the Fiori Elements macros in action is interesting and helpful when developing extensions. Especially the ability to add messages is awesome.

      While testing myself I could not interpret which method you meant with “In the controller, at fragment loading”, could you please specify the method name expected to be present in the controller?

      One more thing I noticed when looking at the API reference is that very limited methods are exposed on the macro controls. Is there a way to get access to the underlying control? For example, if I have a table of type sap.fe.macros.Table, how would I toggle the visibility of columns?

      Best regards

      Tristan

      Author's profile photo Fouad Sebbane
      Fouad Sebbane

      Hi Tristan,

      I am also very interested in the answer to your question.

      @Sumesh Nair
      It would be great if you or one of the SAP internal staff could answer Tristan's question.

      Thank you very much,
      Fouad

      Author's profile photo Sumesh Nair
      Sumesh Nair
      Blog Post Author

      Hi Tristan Heisecke ,

       

      Apologies for the delayed reply.

       

      Q1.While testing myself I could not interpret which method you meant with “In the controller, at fragment loading”, could you please specify the method name expected to be present in the controller?

      Solution: Please refer to the Reference section in the blog for 'How to retrieve controls from a Fragment'. In my example i use the `Case 2: Fragment is NOT embedded in a View and given an ID`. The mentioned code can be implemented in the returned promise of the LoadFragment, like below

      Fragment.load({
          name: "demo.fragmentSample.fragment.Table",
          controller: this,
          id: "tableFragment" 
      }).then(function (oDialog) {
        //Your code goes here
      }.bind(this));

       

      Q2. One more thing I noticed when looking at the API reference is that very limited methods are exposed on the macro controls. Is there a way to get access to the underlying control? For example, if I have a table of type sap.fe.macros.Table, how would I toggle the visibility of columns?

      Solution: I will share the API reference once I find one. Until then, I can share what I would do in this situation.

      To know about the available methods for a control, I would get the access to the element into a variable (in the controller CODE). Then while in browser debugging , you can investigate the variable for the list of available methods.

      In your particular case, try to remove/hide the column from the table element in the controller.

      You can try within the INIT method to start with to see this solution works.

       

       

      Regards,

      Sumesh Nair