Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Ajit_K_Panda
Product and Topic Expert
Product and Topic Expert
7,414

Introduction

Based on my brief experience with SAP Fiori Elements, I have previously written two blogs as follows:

This blog post serves as a follow-up to the following preceding post:
CAP with Fiori Elements: Actions on List Report / Object Page using Annotations – Part1

Within this blog post, I have outlined my observations regarding the various types of actions achievable through service definition and annotations.

Explanatio of POC Scenario and Its Resources

We will use the sample project “cap-fe-lr-op-actions” that I have shared on GitHub here to explain the concepts. Let’s briefly examine the project and some of its essential files.

Project StructureFolder or File
Ajit_K_Panda_0-1707105464452.jpeg

Service cap_fe_lr_op_actions_serviceproivides following data set: Roots, Items, Categories, Criticalities, Samples.

Please be aware that in this blog post, my emphasis is on illustrating the functionality of presenting tables in various configurations. It’s worth noting that the service utilized for demonstration purposes may not be flawless and is solely used to explain the functionalities.

Detailed Explanation


Now, let's explore various types of actions that can be incorporated through annotations. To illustrate, we'll use the Samples view from the list report within the application (marked above).

1. Critical Action

  • To accomplish this, the action must be annotated with the @Common.IsActionCritical term.
  • Actions that require user confirmation are called critical actions. This proves beneficial for actions with potentially significant consequences. Upon the user's click of such an action, the system prompts a dialog, in which the user needs to confirm the intended action.
  • Here is the method for annotating both bound and unbound actions:
    annotate service.sua_action_critical with @Common.IsActionCritical;
    annotate service.Samples actions {
      sba_action_critical @Common.IsActionCritical;
    };​​

2. Action with Dialog having Text Input

  • Actions with a dialog are actions that require additional user input, for example, a comment. The system will display a dialog containing one or more input fields for the user to enter the necessary details.
  • To implement an action with a dialog, you can enhance your action by adding extra input parameters as shown below:
    type inText : {
      comment: String;
    };
    
    entity Samples as projection on db.Samples actions {
      action sba_action_text(text:inText:comment);
    };​​
  • It is also possible tassign a label text to the input by including a label in the type:
    annotate service.inText:comment with @Common.Label :'MultiLine Input Text';
  • While Text/String inputs typically display as a single-line input field, you can convert them to multiline by applying the following annotation:
    annotate service.inText:comment with @UI.MultiLineText:true;​
  • Result:

3. Action with Multiple Input

  • Actions can have different kinds of input depending upon the type of input parameters defined for the action in the service definition.
  • Let's look at an example:
    /*=======>> Action Definition <<=======*/
    type inComplexObject : {
      comment : String(50);
      date    : Date;
      datetime: DateTime;
      confirm : Boolean;
      value   : Integer;    
    };
    
    action sba_action_complex(
        aprcomment  :inComplexObject:comment,
        aprdate     :inComplexObject:date,
        aprdatetime :inComplexObject:datetime,
        aprconfirm  :inComplexObject:confirm
    );​
    /*==========>> Annotations <<==========*/
    annotate service.inComplexObject {
      comment   @Common.Label: 'Comment';
      date      @Common.Label: 'Date of Approval';
      datetime  @Common.Label: 'Time of Processing';
      confirm   @Common.Label: 'Confirmation';
    };

    Above action definition and annotations will provide following result:

  • Note: Which type of control will be rendered depends on the data type of the import parameter for the action in the service definition.

4. Action with Mandatory and Default Input

  • It is also possible to make some import parameters of action mandatory and provide default values as well.
  • Here is an example:
    /*=======>> Action Definition <<=======*/  
    type inOtherObject: {
        input1  :String(50);
        input2  :String(50);
        input3  :String(50);
    };    
    
    @cds.odata.bindingparameter.name : '_it'
    action sba_action_other(
        text1 :inOtherObject:input1, 
        @UI.ParameterDefaultValue:'default text'
        text2 :inOtherObject:input2,
        @UI.ParameterDefaultValue: _it.name
        text3 :inOtherObject:input3
    );​​
    /*==========>> Annotations <<==========*/
    annotate service.inOtherObject {
      input1  @Common.Label: 'First Input' @mandatory;
      input2  @Common.Label: 'Second Input';
      input3  @Common.Label: 'Third Input';
    };
  • Result:
    If mandatory parameter is not filled by user, then it throw error as shwon
  • Note-1: @mandatory annotation term is used to make the parameter mandatory
  • Note-2: @UI.ParameterDefaultValue annotation term is used to provide default value for a parameter. It is also possible to use value of a property of selected context as default value.
  • In above sample, we have value of name property as default value for Third Input parameter.

5. Action with DefaultValueFunction based Input

  • Apart from specifying default values with the @UI.ParameterDefaultValue annotation, it is feasible to retrieve default values from the backend service using a function within the service.
  • Let's look at an example
    /*=======>> Action Definition <<=======*/
    service cap_fe_lr_op_actions_service {
      type inObjectFn:{
        text1: String;
        text2: String;
      }
    
      @Common.DefaultValuesFunction: 'cap_fe_lr_op_actions_service.getDefaults'
      action sba_action_defaultfn(text1:inObjectFn:text1, 
                                @@UI.ParameterDefaultValue: 'default value'
                                text2: inObjectFn:text2);
    
      function getDefaults() returns inObjectFn;
    }
    
    
    
    /*=======>> Defulat Function <<=======*/
    srv.on(["getDefaults"], async (req) => {
      return {  text1: 'default text 01', 
                text2: 'default text 02'  };
    });​
    /*==========>> Annotations <<==========*/
    annotate service.inObjectFn {
      text1 @Common.Label: 'First Text Input';
      text2 @Common.Label: 'Second Text Input';
    }
  • Result:

  • Note: @UI.ParameterDefaultValue annotation term takes importance over value from DefaultValuesFunction as eveident from above example for text2.

6. Action with Value Help Input

  • In addition to the default value help that appear for date and datetime import parameters, you have the option to include your own custom value helps.
  • Let's look at example
    /*=======>> Action Definition <<=======*/  
    type inObject :{
      category    : String;
      criticality : String;
    }    
    
    action sba_action_valuehelp(
        category:inObject:category,
        criticality:inObject:criticality
    );​​
    /*==========>> Annotations <<==========*/
    annotate service.inObject {
    category @(
      Common.Label: 'Sample Category',
      Common.ValueList : {
        $Type : 'Common.ValueListType',
        CollectionPath : 'Categories',
        Parameters : [
          { $Type : 'Common.ValueListParameterInOut',
            LocalDataProperty : category,
            ValueListProperty : 'id'                       },
          { $Type : 'Common.ValueListParameterDisplayOnly',
            ValueListProperty : 'descr'                    }
        ],
        Label : 'Choose One Category'
      },
      Common.ValueListWithFixedValues : false
    );
    
    criticality @(
      Common.Label: 'Sample Criticality',
      Common.ValueList : {
        $Type : 'Common.ValueListType',
        CollectionPath : 'Criticalities',
        Parameters : [
          { $Type : 'Common.ValueListParameterInOut',
            LocalDataProperty : criticality,
            ValueListProperty : 'id'                       },
          { $Type : 'Common.ValueListParameterDisplayOnly',
            ValueListProperty : 'descr'                    }
        ],
        Label : 'Choose One Criticality'
      },
      Common.ValueListWithFixedValues : true
    );
    };
  • Result:
  • Note: Value helps are added to the type of import parameter using @Common.ValueList annotation term.

Miscellanous features

1. Handling Messages 

  • There are 2 ways to show messages on SAP Fiori Elements based UI application: Message Toasters, Message Dialog as shown below:
  • The display of a message toast or a dialog depends on the method utilized in a CAP-based service to communicate the message.
  • It's worth noting that using the req.notify method produces a message toast, while other methods such as req.info, req.warn, and req.error result in message dialogs with varying severities.
    req.notify('message to be shown on message toast');
    
    req.error('erroneous message shown on message dialog')​
  • Additionally, when employing req.info, req.warn, req.error, or req.notify, only a single message can be transmitted. To send multiple messages, it is necessary to dispatch all messages from the service using the sap-messages header, as illustrated below:
    srv.on("msg_trigger",async (req) => {
    
      req._.odataRes.setHeader('sap-messages', JSON.stringify([
        { 
          "code" : "500",
          "message" : "info: messages trigger action called!",
          "numericSeverity" : 2                            
        },
        {
          "code" : "504",
          "message" : "This can only be triggered for draft data",
          "numericSeverity" : 3
        },
        {
          "code" : "504",
          "message" : "Error happened! Contact your IT Admin",
          "numericSeverity" : 4
        }
      ]));
    
    });​

    This results in following message dialog:

2. Criticality for Actions

  • Assigning a criticality level to an action, achieved by configuring the "Criticality" property within the annotation, results with both positive and negative semantic representations.
  • Only two criticality values are supported: #Positive (03), #Negative (01)
  • Please be aware that criticality is not universally supported for all actions; its applicability is limited to inline table actions and global/determining actions on the object page.

Conclusion

In this blog post, we have delved into different kinds of actions generated based on service definition and annotations along with handling messages on SAP Fiori Elements.

Together, the Cloud Application Programming Model and Fiori Elements improve developer experience while also boosting productivity and accelerating the development of enterprise-ready applications.

More information about Fiori Elements with cloud application programming model can be found here. You can follow my profile to get notification of the next blog post on CAP or Fiori Elements. Please feel free to provide any feedback you have in the comments section below and ask your questions about the topic in sap community using this link.

6 Comments