ABAP RESTful Application Programming Model – Enable Change Set processing in Multi select Fiori Applications
I hope you had a pleasant start to 2022 😊
I would again like to share my learning from a challenge which I recently encountered while implementing a RAP based SAP Fiori Elements application for our customer, and the respective solution, using which I could overcome the challenge.
We wanted to create a RAP based SAP Fiori Elements List Report application. Customer wanted to have multiple selections enabled in the List Report page for this Fiori Application. It was required to have certain custom actions in the application called ‘Group’.
So basically, the application user can select multiple entries from the list and click on Custom action to group all the selected entries together and assign a common grouping ID to it. However, there were also multiple validations required like we should not allow grouping of all the selected entries if one or more of the selected entries are already grouped.
To achieve the above requirement, we created a RAP based managed service and added custom action called Group to our app, exposed it to UI, enabled multi select in UI by modifying manifest.json (each step explained in detail in next section), and added action implementation in Behavior Pool class to assign Grouping ID to all the selected entries by generating a unique ID using number range object. However, after implementing these steps, when we tested the application, we got to know that only a single record per backend call was being sent from UI to backend. This means, if the user selected 3 entries and clicked on Group, the action implementation would be called 3 times, with a single ‘key’ value in each call, hence, at a given point of time, we didn’t know how many records were selected, and if some of the records selected were already grouped previously. Hence, the validation of the grouping couldn’t be achieved due to this challenge.
To overcome the challenge, we had to explicitly turn on the Changeset using invocation grouping. This can be simply activated by adding parameter ‘invocationGrouping’ in the UI annotation where you are exposing your action and set its value to #CHANGE_SET as highlighted below.
As soon as invocation grouping is added, we were then able to receive all the selected entries in a single backend call, and apart from implementing Grouping, we were also able to implement all the validations, as we now know all the selected entries together.
To demonstrate, I am using ABAP cloud trial to develop the service using a Travel entity and adding a custom action ”Group” to it and exposing it to UI using Business Application Studio.
1. Create a root Travel view entity:
2. Create Behavior Definition and add action called ‘group’.
3. Create Behavior Pool class and implement logic in action implementation method.
4. Create Projection View.
5. Create Behavior Definition Projection.
6. Create Service Definition:
7. Create Service Binding:
8. Expose the oData service to UI using BAS:
Create a new project from Template in Business Application Studio/WebIDE to generate a Fiori Elements app for the generated oData service. Below is the project I generated in BAS:
9. Edit manifest.json file to enable multi select
Test the Fiori App in BAS to see multi-select enablement:
Select some records and hit ‘Group’ button:
Effect of Invocation Grouping:
The below steps explain effect of invocation grouping:
1. Expose ‘Group’ action without invocation Grouping
Add a break-point in action implementation
Select multiple records in UI and hit ‘Group’:
Debugger would stop at action implementation. Check ‘keys’. Only a single value in first backend call. Method is triggered twice since 2 records are selected
2. Expose Group action with invocation grouping
Again, add select multiple records in UI and hit ‘Group’
Check no of values in ‘keys’ in debugging. This time, since we have invocation grouping activated, we receive all the selected entries in a single backend call. That’s the effect invocation grouping brings.
This way, I was able to add all the validations as well.
Please feel free to share your thoughts and feedback 🙂
I usually work with EML which by default provides multiple record processing. Didn't know exposing actions to UI needs this additional settings.
Thanks for the post.
Thanks for the feedback.
Nice one Aman.
Thanks so much for sharing your knowledge with all of us.
Thanks for the feedback Thiago!
Nice one Aman. I was struggling with multiple backend calls. Feeling good now after getting solution from you. Kudos.!
One more scenario if you could come across, is there any way to control backend code based on framework EDIT/DISPLAY mode in managed scenario?
Thanks for your feedback, I am glad this helped you.
Regarding your scenario, for Edit, you can disable the standard Edit operation, and define a custom action with the same/similar name, this way you now have control over the back-end code.
I want to show specific action/certain fields only in EDIT mode of application. During DISPLAY mode, those fields/action should be hidden.
Do we have any possibility in feature control to make it hide/visible .? Have you come across such situation.?
I am aware of custom action. But need to understand visibility control of certain fields using feature control
Thanks, Aman Garg for that great article.
Thanks for your feedback 🙂
I don't know a way right now to check if select all is selected. Checking keys also can be misleading, because framework has internal paging implemented, so even if select all is selected, only first 20 records are sent at first call, so key would have 20 rows only.
In case I get a solution for this, I will update here.
Andre Fischer could you may support? Is there a way to identify if the user has clicked on "select all"?
Hi, Aman Garg. Thanks for your blogpost.
Is it possible to disable the group-button as soon as an entry with a group ID is selected? So I can avoid that a group id can be overwritten.
With multiselect : false. It works fine by using method get_features, but i cannot make it working for multiselect:true.
I haven't tried this yet, but I think this should be possible by using the Global Feature Control feature of RAP framework for our action in our behavior definition and then implementing the respective logic in Behavior Pool.
Please refer to link for details: https://help.sap.com/docs/BTP/923180ddb98240829d935862025004d6/2fc956f7d92842b2872077050856409c.html
I have a scenario where i have to enable Create button through RAP.
I have added in annotation, behavior definition and its appearing when i Previewed it. But it only gets enable when i select any particular row.
Ideally Create should be enabled irrespective of any selection.
Is their a way to do this ? Kindly help
Since Create is an operation, not an action, so it doesn't require any annotation. If you have enabled create in your Interface Behavior Definition and Projection Behavior Definition, then you should always see it, unless there some feature instance implementation in place. Could you share more details or some screenshots and show which annotations have you added?
Thanks for quick reply.
i have attached 2 screenshots. one with issue another has current existing code.
You have to use "static" before action in behavior definition. Then button will be enabled without a record selection.
Static actions are independent and doesn't require a record/instance to be selected.
It worked.. Thanks 🙂
I have the exact requirement where I am able to get static button. But, in action call method, I dont get any parameter in import apart from %cid which is of no use.
My requirement is to read entire table data on press of static button.
ps: I cannot use parameter for static action as it will call pop-up to get user input.
Nice Blog Aman