This is a test message to test the length of the message box.
Login
ABAP RAP Optimize search
Created by Software-Heroes

RAP - Optimize Search and Keys

157

In this article, we will optimize our search help in the custom pattern, use the additional binding, and make our RAP application fit for the end user.



In this article, we focus on the search help in our application and optimize input for the end user to provide the best possible experience.

 

Introduction

We are expanding our Custom Pattern with search help and optimizing input for the end user. In most cases, the actual business user no longer wants to have technical values. They are not interested in whether document type XY or indicator 1 is used. The technical identifiers then usually contain business information, such as the document type for credit memos or the payment indicator for domestic transactions. With this in mind, we want to optimize the application today and hide all technical values from the user.

 

Preparation

To do this, we want to provide two new search aids in our RAP application, one for Team and one for Application. To do this, we first need to create a foundation in the form of tables and then feed them with data.

 

Table

So let's first create the tables. We'll use data elements that we already used for the Custom Entity extension. To do this, we first create the Team.

@EndUserText.label : 'Teams'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zbs_dcp_team {
  key client  : abap.clnt not null;
  key team    : zbs_demo_dcp_team not null;
  description : zbs_demo_dcp_text;
}

 

In the next step, we create the application, whereby an application is initially assigned to a team. Here, we have a relationship to the other data.

@EndUserText.label : 'Application'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zbs_dcp_appl {
  key client      : abap.clnt not null;
  key application : zbs_demo_dcp_appl not null;
  team            : zbs_demo_dcp_team;
  description     : zbs_demo_dcp_text;
}

 

Data

In the next step, we fill the tables with data that we then want to retrieve via our search help. In this case, we write a small class that fills the tables with data. In the "real" world, you could provide a Business Configuration in which business users can maintain and transport the data, or a custom RAP application with more functions.

CLASS zcl_bs_dcp_data_init DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.
ENDCLASS.


CLASS zcl_bs_dcp_data_init IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA teams        TYPE SORTED TABLE OF zbs_dcp_team WITH UNIQUE KEY team.
    DATA applications TYPE SORTED TABLE OF zbs_dcp_appl WITH UNIQUE KEY application.

    teams = VALUE #( ( team = 'BASE_DEV' description = 'Central Development' )
                     ( team = 'FI_DEV' description = 'Development Financial' )
                     ( team = 'HR_CUST' description = 'HR Customizing' ) ).

    DELETE FROM zbs_dcp_team.
    INSERT zbs_dcp_team FROM TABLE @teams.

    applications = VALUE #( ( application = 'GENERAL' team = 'BASE_DEV' description = 'General Developments' )
                            ( application = 'REVIEW' team = 'BASE_DEV' description = 'Review Tool' )
                            ( application = 'CALC' team = 'FI_DEV' description = 'Tax Calculation' )
                            ( application = 'ENGINE' team = 'FI_DEV' description = 'Calculation engine' )
                            ( application = 'ACC_DEF' team = 'FI_DEV' description = 'Account definition' ) ).

    DELETE FROM zbs_dcp_appl.
    INSERT zbs_dcp_appl FROM TABLE @applications.
  ENDMETHOD.
ENDCLASS.

 

Hint: In principle, you can use UUIDs when creating the system, but you cannot later include them in authorization objects to authorize the user. Therefore, we sometimes assign descriptive technical abbreviations as keys.

 

Search Help

In the second step, we create the two search help views directly and forgo a base view for normalizing the fields. To do this, we first create the view for the team, in which we also create a search field across both columns.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'VH for Team'
@Search.searchable: true
define view entity ZBS_I_DCPTeamVH
  as select from zbs_dcp_team
{
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 1.0
  key team        as Team,
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 0.8
      description as Description
}

 

You can find more information about search fields in this article. We'll design the second view similarly, but here we'll also define a search help using the Team field.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'VH for Application'
@Search.searchable: true
define view entity ZBS_I_DCPApplicationVH
  as select from zbs_dcp_appl
{
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 1.0
  key application as Application,
      @Consumption.valueHelpDefinition: [{ entity: { name: 'ZBS_I_DCPTeamVH', element : 'Team' } }]
      team        as Team,
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 0.8
      description as Description
}

 

Hide key

To hide the key, we need three things. First, the text must be available in the entity or bound via association. Second, we store the corresponding text in the key, and as a final step, we determine the display of the key field.

 

Text

To do this, we create two fields in the custom entity that receive the data type from our tables. The fields can be defined at the end of the custom entity.

@UI.hidden: true
TeamDescription  :  zbs_demo_dcp_text;

@UI.hidden: true
ApplDescription  :  zbs_demo_dcp_text;

 

Then we read the data in our query implementation and fill the fields in the GET_REMOTE_DATA method. To do this, we implement a very simple read routine in the loop.

SELECT SINGLE FROM ZBS_I_DCPTeamVH
  FIELDS Description
  WHERE Team = @line->team
  INTO @line->TeamDescription.

SELECT SINGLE FROM ZBS_I_DCPApplicationVH
  FIELDS Description
  WHERE Application = @line->application
  INTO @line->ApplDescription.

 

Hint: You should always remember to exclude the fields from the selection, otherwise no data will be displayed. Therefore, we must also add the two fields to the DELETE_FIELDS statement.

 

Annotation

In the final step, we add the appropriate annotations to the fields. With "ObjectModel.text.element" we define the text for the key field, and with "UI.textArrangement" we can display the key with the text or even hide it completely. This means the user no longer sees it, but it is still used in our application.

@ObjectModel.text.element: [ 'TeamDescription' ]
@UI.textArrangement: #TEXT_ONLY
team            : zbs_demo_dcp_team;

@ObjectModel.text.element: [ 'ApplDescription' ]
@UI.textArrangement: #TEXT_ONLY
application     : zbs_demo_dcp_appl;

 

We can hide the actual text fields with "UI.hidden"; we don't need to display them as additional text. In return, we now get cleanly formatted fields.

 

Change

However, if we switch to change mode, the user will see the technical content again and no longer the readable values.

 

To change this behavior, we need to adapt the two search helps and make the same changes as when integrating them with the annotations. You can find the finished views in the GitHub repository if you'd like to see the customizations in detail; we'll save the listing for now.

 

Additional Binding

We now have a search help that could theoretically use a value from the current entity to limit the search set, or even be automatically populated. In this case, we can use the "Additional Binding" to ensure that this field is included in the search help. To do this, we add an additional property to the search help.

@Consumption.valueHelpDefinition: [ { entity: { name: 'ZBS_I_DCPApplicationVH', element: 'Application' },
                                      additionalBinding: [ { element: 'Team', localElement: 'team', usage: #FILTER } ] } ]

 

The additional binding connects a field in the search help with a local element or a constant value. We can further refine the "USAGE" setting and adapt its functionality to our needs. The field has the following properties:

  • #FILTER - The additional fields are used to restrict the search results.
  • #RESULT - The fields from the search also overwrite the other fields in the entity when a search result is selected.
  • #FILTER_AND_RESULT - A combination of the two previous settings.

 

In this example, we use the #FILTER variant to include the field in our filter and directly restrict the values. To do this, we look at the available applications (5), then select a product, and in the second step, we only see two applications, as the additional filter takes effect.

 

Semantic key

As a bonus, we also adjust the semantic key of the application so that navigation continues to work on a technical level, but the user only sees the description in the application. However, this is an example, since the application is likely to be operated by the developer, who needs the name of the software component for their work. For this we have the semantic key for navigation:

@ObjectModel.semanticKey: [ 'staging', 'sc_name' ]    

 

If we now define the text field in our key field and hide the text, we can influence the appearance.

    @UI.textArrangement: #TEXT_ONLY     
    @ObjectModel.text.element: [ 'descr' ] 
key sc_name         : abap.char(18);

    @UI.hidden: true
    descr           : abap.char(60);

 

The following result would now be displayed in the application. The technical key is no longer visible, and the description, like the key, is highlighted in bold for better visibility.

 

Complete example

As always, you can find all the customizations to the application in our GitHub repository on RAP. You can use the commit to track the changes made and get a simple overview of the topic.

 

Conclusion

With a few annotations, we can improve the search help and the UI, making it easier for users to work with our application. With today's tips, the next application should be significantly better.


Included topics:
RAPBTPSearch HelpAdditional Binding
Comments (0)



And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.


RAP - Fixed Value Filter

Category - ABAP

How do you use fixed values from a domain for a filter and customize it to your needs in RAP? Learn more here.

05/02/2025

RAP - Custom Pattern (Behavior)

Category - ABAP

In this article, we extend the Custom Pattern in RAP with additional data and behavior, allowing us to create added value in the implementation.

04/29/2025

RAP - Custom Pattern

Category - ABAP

How does the custom pattern work in ABAP development, and for which scenarios can you use it? Let's look at an example.

04/25/2025

RAP - Tree View (Deletion behavior)

Category - ABAP

In this article, we'll look at the behavior of deleting nodes in the tree view using RAP. There are some interesting points to note.

04/15/2025

RAP - Tree View

Category - ABAP

Want to easily display a hierarchy in RAP? Learn how to do it in ABAP Cloud in this article.

04/08/2025