Vous êtes sur la page 1sur 148




"A place to learn basics of SAP CRM WEB UI"
Friday, 24 May 2013


Identifying the important parts of normal WEB UI page . Let us identify the important parts of the web ui page. We can divide entire web ui page in to three parts named as 1. Navigation bar 2. Header Area 3. Work area. Navigation bar: This entire frame is called navigation bar. Why it has been named as Navigation bar ? Well , Users, in general, access different applications in CRM by clicking on links of this navigation bar. Like, they will navigate to different pages from navigation bar. You will hide this navigation bar by clicking on the arrow mark. Highlighted in the screen shot. We will discuss navigation bar more in later tutorials.

Header area:

The below screen shot area is called header area.

Together navigation bar and header area forms an L shape navigation in WEB UI page. See below.

Work area :

The area highlighted in the below screen shot called WORKAREA. Any application or object information will be displayed in the WORK AREA. This is the place with which user interacts more. If I click on any link on navigation bar , that particular information will be displayed in the work area.

Let us discuss each part in depth in next chapters.


NAVIGATION BAR: We just show you how navigation bar looks in the previous document. Here we will have closer look at the navigation bar. We can divide navigation bar into following parts. Work Center part Direct link Group Recent Items

WORK CENTER PART: This will look like in the below screen shot. Each link for example HOME or SERVICE ORDERS or REPORTS on the navigation bar is called WORK CENTER. In the below screen shot, there are 11 work centers.

All these work center entries depends upon the BUSINESS ROLE. This means, depending upon the business role, the entries on the navigation bar will change. Here we logged in as SERVICE PROCESSIONAL role. If we log in with the SALES PROFESSIONAL role then entries may be changed. You wont see work center SERVICE ORDER, instead you will see SALES ORDER work center.

Click on any work center, you will be taken to a page called work center page. In which you can find more links in groups like SEARCH, CREATED and reports. This navigation from WORK CENTER to WORK CENTER page is called FIRST LEVEL navigation. If we observe closely, we can see ARROW marks for certain work centers. Accounts & Products, service orders, service contracts etc. if we click on that arrow mark, we will get one more menu like below screen shot.

If you click on any link in the opened menu, we will navigate to the corresponding object SEARCH page. If we click on SERVICE CONTRACTS, then we will be navigated to a SEARCH PAGE. In that SEARCH PAGE, we can search SERVICE CONTRACTS. This navigation from second level menu to search pages of different objects is called SECOND LEVEL NAVIGATION. 2. DIRECT LINK GROUP: What is the use this section? One main use of link section is, it provides direct access to create any object. A user, who logged into WEB UI in role service professional, may need to create SERVICE CONTRACTS number of times. So he can click on link SERVICE CONTRACT and can directly navigate to the page where he can created SERVICE CONTRACT. We can place those objects which need to be created more frequently in this place. So that user can reduce his time in clicks while performing his work.



For example while performing some operation, we visited one business partner with name RAVI and closed it after updating some information of that business partner. That particular business partner will automatically appear in this section. Next time, you can access same business partner by clicking on the link in this section. This saves a lot of time. We can control the number of entries appear in this section.

we can click on arrow mark buttons highlighted in the screen shot , to scroll and see the DIRECT LINK GROUP and RECENT ITEMS section on navigation bar.

TAKING A CLOSER LOOK: Before trying to change the navigation bar, there are certain technical details that we need to know. One such is LOGICAL LINK. What is it? I logged into web ui as service professional role. On the navigation bar I clicked on SERVICE CONTRACTS work center, I have been taken to the SERVICE CONTRACTS work center page. Next, I clicked on SERVICE CONTRACTS in the second level menu, and then I have been taken to SEARCH PAGE of service contracts.

How this navigation is possible. Who tells to WEB CLIENT FRAME WORK to navigate to the SEARCH PAGE, , when, I clicked on SERVICE CONTRACTS. Well this information will come from LOGICAL LINK. At this point of time, just understand that LOGICAL LINK helps us to navigate to different pages from navigation bar.

In above example, the SERVICE CONTRACTS work center will be associated with one logical link and also SERVICE CONTRACTS in the second level navigation also linked with one LOGICAL LINK.

Each link with in the highlighted circle is associated with the LOGICAL LINK. Even All WORK CENTERS on the navigation bar also have their corresponding logical links. WHEN WE NEED TO CREATE LOGICAL LINKS: Generally logical links will be available for all SAP STANDARD components. If we create our own applications and if we want give access to our application from navigation bar then we need to create our own logical links. We need to learn a lot before creating a logical link of our own . At this point of time, try to understand that logical link enables navigation to different pages.


BUSINESS ROLE INTRODUCTION: It is very clear that all employees of organisation need to handle different activities. For example, say there is one organisation called X. It has number of departments like sales, service, marketing etc. So employees in sales department will have to do different activities when compared to the activities of employees in marketing department. So what we do is we assign each employee a role ( in indirect way ) and they log into the CRM WEBCLIENT with this role. So this role is a key and like a container which can almost control everything that user sees on the WEB CLIENT screen. A user, who logged into the WEBUI with the role SALES PROFESSIONAL, can do all of his sales activities at the same time, another user who logged with another role can complete his own job related things. If user is having more than one business role, then he will be prompted to select any one role after user authentication is completed. Kindly see the below screen shot of the user who has two different business roles. He can select one of them.

This is just introduction, in SAP CRM, business role is little complex thing. SAP provides number of standard business roles and its our responsibility to change or enhance those roles according to our requirements. We will discuss on creating new business roles later. In order to access the roles for testing purpose. Kindly follow below instructions. 1. 2. 3. Open the SAP GUI. Open the transaction SU01 (user maintenance). Give the user name and choose edit button.

1. 2.

Go to the parameters tab. Give the parameter name as CRM_UI_PROFILE and give the value as *.


Save the changes. This is just for testing purpose only and assigning roles to users should be followed different way. We will discuss it later. Now if you log into the CRM WEB CLIENT with this user id, you can see all available roles and you can choose whatever you want.


A lot of SAP standard business roles have been provided. We just need to modify them according to our needs. Lets create SERVICE PROFESSIONAL ROLE and configure that role according to our needs. Remember, we always copy the existing role into customer name space and do the changes.

Go to the following path in the transaction SPRO. 1. Enter the transaction SPRO and choose SAP REFERENCE IMG and execute the option as shown in the below screen shot.


Next screen, will list all available business roles in the system. Select the role service professional and click on copy as shown in the below screen shot.


Give appropriate name for business role (starting letter should be Z or Y). Here we have given ZSERCLIENT. Do not change any another entry except the description. We need to identify the user later so Change the description and save the entries.

You will receive message Number of copied entries , choose RIGHT MARK. 1. 2. Service professional role is created now. But it is just a copy of the SAP STANDARD ROLE. Now we need to modify this role according to our requirements. See the field NAV BAR PROFILE which contains the value SRV-PRO. It is navigation bar profile and controls the look and functionality of the navigation bar. If we want to change the navigation bar associated to this business role , then we need to modify this navigation bar profile. But as standard practice, we need to copy it to the customer name space with some name, do the modifications and will assign that new profile to this role.


There are other fields like functional profile, technical profile, PFCG role id and ROLE CONFIGURATION KEY which are very important to know. We will discuss them later one by one. Log in to the web ui with the newly created BUSINESS ROLE. But we need to know some basic details on ORGANIZATIONAL MANAGEMENT IN CRM. BECAUSE THERE IS MORE THAN ONE WAY TO ASSIGN BUSINESS ROLE TO THE USER.


ASSIGNING USERS TO THE BUSINESS ROLE: Discussing organizational management is not part of this tutorial. However in order to understand the concept, we will try to create one ORG model. 1. 2. 3. Basically, there are three ways by which a user can take the business role in SAP CRM system. Thorough the organizational assignment. Directly assigning business roles as values to the profile CRM_UI_PROFILE in parameters tab of the user in the transaction SU01. Assigning user directly to the authorization profile. Lets do the first one. Run the transaction PPOCA_CRM and you will get one dialog box, which shows validity periods. click on CONTINUE. Enter the organization description as mentioned in the below screen shot and press on SAVE button.

Let us create one position in the organization as we generally assign roles to the positions not to the users directly. Users, who are assigned to this position, will take this business role. Click on CREATE button and choose the position as below.

Enter the short text and description and click on continue.

We have created one position in the organization. Then select the position and choose the menu option as highlighted in the below screen shot.

Select the info type BUSINESS ROLE and click on create button.

Enter the newly created business role ( in previous tutorial) and click on save.

We have successfully assigned the role and now we need to assign the user to the position. Right click on position and choose ASSIGN and in the next dialog box choose USER.

In the next screen shot, give user name in the search term field and choose start search and select the user and click on right mark on every dialogue screen. User will be assigned to the position and click on save.

We have successfully assigned the user. Now Its time test the role. Logon to the web ui and give the user name and password and see our new role will be in the list and if it is only role assigned to the user , role will be directly loaded.


Business Role is the key player in the web client frame work. It will decide what can appear on the screen. Navigation bar is controlled by Navigation Bar Profile and this profile will be assigned to the Business role. So if user logs into the WEBCLIENT with a particular business role, then the navigation bar which is associated with this business role will be loaded. Let us take a look at screens where navigation bar can be customized. Transaction Code: CRMC_UI_NBLINKS Path in SPRO -> Customer Relationship Management->UI Framework->Technical Role Definition->Define Navigation Bar Profile Execute the Transaction directly or go to the SPRO transaction in the above mentioned path and click on Execute button.

All highlighted options are navigation bar profiles. You can scroll down and up to see more profiles. We need to know a little about the options which are in left panel. Double click on first option logical links and you will see all logical links in the right panel as highlighted in the below mentioned screen shot.

How they look on the WEB UI.

Next click on DEFINE WORK CENTER LINK GROUPS. You can locate work center link groups on web ui on WORK CENTER Page. What is work center page? The page, to which you can navigate, by clicking on work center in the navigation bar (first level navigation).

Here we clicked on the work center SERVICE CONTRACTS on navigation bar and navigated to the work center page. Where can we see WORK CENTER LINK GROUPS on WEB UI?

You can find three groups here under which certain logical links are grouped. These groups are called work center link groups means group of logical links which present on the work center page. There are three groups available as shown in the screen shot CREATE group, REPORTS group and SEARCH group. Next work center, we have already discussed work centers. Here is the screen shot to show work center on the web ui.

Next double click on the option Define Direct Link Groups. You can see the all groups.

Where can to find direct link groups on the web ui.

Highlighted part is called direct link group. Clicking on this links will make you navigate to creation pages of corresponding objects. Say if we click on Opportunity, We will be taken to opportunity creation screen.


As we studied in the previous lesson 7, there is certain hierarchy followed in making the navigation bar profile. Logical links form the base of the navigation bar profile. If we want to navigate to any page in the WEB UI, we need logical links. These links tell the system about the navigation destination. So first we will create logical links in the system.

For example, I created three logical links named A, B and C. Depending on the requirement like where we want to show this links, we follow the certain flow. 1. We want the link appear on work center link group. So we will add our link to the required work center link group and this work center link group will be assigned to the work center and work center will be assigned to the navigation bar. 2. We want the link appear on direct link group. So we will add our link to the direct link group and this direct link group will be added to the navigation bar profile. Finally navigation profile will be added to the business role. We can control the navigation bar customizing at business role level. Customizing generally involves changing the position of work centers, adding extra logical links to second level navigation or to work center link group on the work center page and deactivating certain work centers. This small explanation is actually required to understand the process of customizing the navigation bar. We will see all this requirements in detail in the next chapters.


In order to customize, it is very important to identify the correct logical link or correct work center link group or even correct navigation bar profile. What is the first step? First we need to identify the navigation bar profile which is associated with the business role with which we logged in to the web client. How to do that? See the business role with which you logged in and go to the transaction code CRMC_UI_PROFILE or use the below SPRO path. Path in SPRO -> Customer Relationship Management->UI Framework-> Business Roles-> Define Business Role. Here I am choosing the service professional role.

go to the transaction and look for the above mentioned role in the SAP GUI. After finding the role just double click on it.

We can see the value for the field navigation bar profile SRV-PRO. This is the navigation bar profile associated with the business role. First step is completed. Then execute the transaction CRMC_UI_NBLINKS to see the entries in the navigation bar profile SRVPRO.

Let us see the work centers assigned to this navigation bar profile. Select the profile and click on Assign Work Centers To Navigation Bar Profile. You can see the work centers associated to the profile. You can also see the work centers and their positions and title of the work center. If we observe the position of the HOME work center, we can notice that its position is 10 and 10 is the least among all other positions thats why it appear at top of the navigation bar on the WEB UI.

Let us take one logical link on the work center page and see the process to find out the same in GUI. Here SERVICE CONTRACT is logical link on the work center page. It is located on CREATE group as highlighted in the screen shot.


We used service professional role to log in so we need to find out what is the navigation bar profile associated with service professional role. We have already done this step above. It is SRV-PRO.


We are on the work center page. So what is the work center on which we clicked to navigate to this page? We have clicked on SERVICE CONTRACTS work center on navigation bar. So we need to look at the all work centers assigned to navigation bar profile. Yes, we found the service contracts work center SRV-CONTR.


Now we need to look at, what are work center link groups assigned to this work center? Take the work center SRV-CONTR and double click on Define Work Centers. Click on position and give it and click on right mark.

We have found that work center entry. Select that row and double click on Assign Work Center Link Groups To Work Center.

We have found the work center link groups assigned to the work center.

Here there are various group ids. We need to look at the group which is service contract and group should CREATE group as our logical link is under CREATE group. So first option is highlighted on the screen. So work center link group is SRV-CTR-CR.


We need to find out the logical links associated with the SRV-CTR-CR. Double click on Define Work Center Link Groups and find out the group id SRV-CTR-CR.


Select that record and double click on Assign Links To Work Center Link Group


We can find the logical link in the list.

This is nothing but the logical link of service contract which we tried to find out.


As We did changes to the Business role by copying standard business role, same way we need to copy any existing navigation bar profile into customer name space and we need to do adjust the navigation bar profile according to our requirements. Follow the business role documents before following this document. Let us copy the navigation bar profile of service professional business role. So open the business role transaction CRMC_UI_PROFILE and identify the service professional role and find out the navigation bar profile associated with it. It will look like the below screen shot.

Open the SRV-PRO navigation bar profile in the transaction CRMC_UI_NBLINKS. Select the navigation bar profile and click on the copy button as shown in the screen shot.

In the next screen, change the nav bar name and press Enter button. In the next dialog box choose COPY ALL ENTRIES.

Press SAVE button in the next screen.

We have copied successfully navigation bar profile. This should be the first step and now we can change the navigation bar profile according to our requirements. In order to use the newly copied profile, assign this navigation bar profile to the business role that we created in the previous documents. Go to the transaction CRMC_UI_PROFILE and change the navigation bar profile and save it.

You can log in with the business role. However we wont notice any change as we just copied the profile but did not change anything in it. we will do it in the next document.


Let us start with small requirement. There is work center on the navigation bar CATALOG MANAGEMENT. Users are not using this work center. So business wants to deactivate it.

Changes always are done to the business role together with the NAVIGATION BAR profile. Why?

One navigation bar profile can be assigned to more than one business role. So I want to show one work center on role A and I dont want to show it on role B. here both role A and B are using same nav bar profile. Thats why changes are specific to role which provides the ability to use same navigation bar profile in different roles.

So go to the transaction CRMC_UI_PROFILE and open the business role.

Here we need to adjust the work center. So click on Adjust Work Centers. It will list all work centers assigned to this profile.

We just need to select the INACTIVE column for the CATALOGUE MANAGEMENT and save the entries. Log off from the WEB UI and again log in. Now that work center wont be shown.


Here we will try to change the position of work center on navigation bar profile. In the below navigation bar, we will move SERVICE OPERATIONS work center from last position to second place.

Let us again open the transaction CRMC_UI_PROFILE and click on the ADJUST WORK CENTERS.

The work center with least value will be at top and work center with max value will be at bottom. So observe the values. Here 10 is min. 100 is max. So in order to put the SERVICE OPERATIONS at second assign the value 20 to it and assign the value 110 to WORK LIST to make it appear at BOTTOM level. Here we can observe the two columns with name WCpos. One is related to the navigation bar profile and another related to the business role. Which means that the actual position of work center WORK LIST is 20 but for this business role we can change the value to any value. So if we again assign this profile to any another business role, then by default WORK CENTER takes position 20 unless we change it.


Read the document titled IDENTIFYING LOGICAL LINK before reading this document.

There is a close relation between second level navigation logical links and the logical links present on the work center link group. Generally we add logical links to WORK CENTER LINK GROUP. At business role level we can control them. We can add them to the second level navigation else we can make them appear on the work center page or even we can show them on both places.

Let us observe the work center link group SEARCH on the SERVICE operations work center page and look at the activities logical link. The first one.

Go to the transaction CRMC_UI_PROFILE and click on ADJUST WORK CENTERS to know the work center id of SERVICE OPERATIONS

Next to we need to know what the work center link group is assigned to this work center. Here we will look for search group as our logical link appearing on the search group on the screen. Go to the transaction CRMC_UI_NBLINKS and click on the DEFINE WORK CETNERS and identify the work center SRV-OPERAT and click on Assign Work Center Link Groups to Work Center. It will list all work center link groups assigned to this WORK CENTER. Here we are looking at activity so try to pick out the activity group.

We have found two activity groups but we will look at only search group. Note down the SRV-ACT-SR. here SR stands for search and CR stands for CREATE. Again double click on Define Work Center Link Groups and find out the group id SRV-ACT-SR and double click on Assign Links To Work Center Link Group to know the logical links assigned to this group.

Here we can see the last one is the one we want. Note down the logical link SRV-ACT-SR. So now we have WORK CETNER, WORK CETNER LINK GROUP and LOGICAL LINK. Again to the transaction CRMC_UI_PROFILE and select the required business role and double click on Adjust Work Center Group Links. Click on the button POSITION at the bottom in right panel and give the details we found.

An entry will be show in the table.

Here observe the entries and we can note that here there are two columns named IN MENU and VISIBLE.

When check the first check box IN MENU, that particular logical link, will appear in the second level navigation menu. If we check the second one VISIBLE, it also appears on the work center page under the work center link group. Here for this link, both check boxes are checked. So it must appear at both places.

If you uncheck the first check box, then it will disappear from the second level menu. If uncheck the visible then it will disappear from the SEARCH group on WORK CENTER PAGE. This is how we control the second level and work center link groups.


Direct link group will have direct links to create CERTAIN business objects. We can configure these links in as per out requirements. Clicking on these links will lead us to the CREATION pages of corresponding business objects.

If we click on SERVICE CONTRACT, then we will be taken to the SERVICE CONTRACT page. Same applies for SERVICE ORDER. Direct link group will be assigned to the navigation bar. Go the transaction CRMC_UI_NBLINKS and select the required navigation bar profile and click on Assign Direct Link Groups to Nav. Bar Profile. It will list the direct link group ids.

You can see the group name SRV-CREATE. We will have separate work for REC_ITEMS. To see the links in that group. Double click on Assign Links To Direct Link Group and give the group id in the next dialog box.

We can there are lot logical links assigned to this group. Then why we are able to see only two logical links on the WEB UI. ? Because again these links will be controlled at business role level. To see the go to the transaction CRMC_UI_PROFILE and select the required business role and click on Adjust Direct Link Groups and select the group id SRV-CREATE and again click on Adjust Direct Links

We can see there are two check boxes are marked in the column VISIBLE. Thats why we are able to see only two links. This is how we can control the direct link groups. This is the correct place to have word about RECENT ITEMS. This is a special group but it does not have any logical links. The links will automatically appear here when you visit any business object. If we want to use the RECENT ITEMS concept here, then this group REC_ITEMS should be added to the navigation bar profile under DIRECT LINK GROUPS category. If you remove the entry from here, then you wont see the recent items on the WEB UI.

Search is the most frequently used operation on WEB UI. In order to open any business object like business partner, contracts, orders, opportunities, leads .etc. We need to search them in the CRM system. We can use different selection criteria to search any information. We want to change first name of business partner x. then first thing we need to do is search for that business partner X in CRM. CRM WEB UI offers flexible and convenient ways to search any business object. Every business object can be found by its corresponding SEARCH page. Here we will show one small example how search works. Search page will look like below and we can navigate to it in two ways. 1. 2. By clicking on second level navigation link on navigation bar. By going to first to work center page and then again click on specific link in the SEARCH group. Kindly see the below screen shots. First way

Second way, first click on work center accounts & products , then click on accounts.

Here is the search page , which we use, to search any business partners. See the points for highlighted areas.

We can use user name, role, account id, count ry.etc. fields. Business partners list will be retrieved when we press on SEARCH button based on the selection criteria that we used . Now I want to search all business partners whose country is USA. Simply go to the COUNTRY field and press F4 button.

We will get one pop up screen, select the entry US. Now you can see the value US in the country filed. Click on the button SERACH. All business partners will be retrieved from CRM , whose country is USA. Check the below screen shot.

Here you can see every record has a value USA for column COUNTRY. If you observe, here only 9 records are showing on the first screen. We need to click on no 2 or FORWARD to see the next 9 records. One more important point is we got only 100 business partners as a result. It does not mean that CRM is having only 100 partners whose country is USA. We got 100 because; in the field MAXIMUM NUMBER of RECORDS we specified 100. We can specify any number here and search result size will be restricted to that number. If we dont specify any number, then all business partners, which will meet the specified criteria, will be fetched by the system. Does the search can be made only six fields as shown in the screen? Answer is NO. Click on the drop down on any search field, we can see all available fields that can be used as part of search criteria will be shown. We can select any field and specify the criteria in the value field. How to execute below search. Find business partners who first name starts with P letter and who country is either USA or INDIA? See the below screen shot, First we need two fields on screen. One is country and another one is FIRST NAME. Choose the first name option in the drop down as shown in the screen shot.

Same way choose the country field. Now the screen will look like below.

But we have two values to enter for COUNTRY. So click on + mark next to the COUNTRY FIELD to bring one more COUNTRY field so that we can specify our criteria.

Our final selection criteria will look like this. Here condition will look like in ABAP. Just for understanding purpose. SELECT * PATNERS FROM (DBTABLE) WHERE (country = IN or country = US) AND first name LIKE p%. Here important point is that two different fields on search criteria forms an AND condition and more than one same fields forms OR condition. P* means, all strings who will start with letter p and remaining string can be anything. If we specify *p, all strings whose last letter is P, will match.

CREATE operation: In the SEARCH tutorial, we searched for business partners based on different selection criteria. Here we will create a new business partner in the CRM webui. This will give us new page types in the CRM, with which, we frequently interact with. Let us begin. There are four ways to create business object in CRM depending on the configuration. 1. Use direct link that is provided in the DIRECT LINK GROUP as shown below. Clicking on this links will take us to the pages, where we can create business objects. This depends on the configuration of navigation bar profile.


On the search page of corresponding business object.


By going to the CREATE group on work center page .


By clicking on NEW button on the already opened business object page. Like if I open one business partner in the CRM, and then if you want to create one new business partner, you can click on the new button as shown below and can create the new business partner.

So in all above scenarios, we will be taken to the creation page of business object. We can enter required information in the provided fields and save the business object.


Transaction: BSP_WD_CMPWB. We will try to learn UI concepts together with implementing them. Because explaining UI component concepts alone, will be complex to understand. We will create one UI component which will look like a service contract screen. We try to explore each topic in depth as this process goes on. Let us start. Go to the transaction above mentioned. We will get below screen. Give any name and Press on CREATE.

As soon as we click on CREATE button, system will throw one popup as shown below. Here we can change the component description and Main window name. After changing Press on Continue button.

Then system will ask to save it. You can save it in the local object or any another transport ( if we want to transport to some other system ). System will throw same popup multiple times as It will create another controllers, context nodes. Just keep on pressing save button until the following screen presented to us. Just double click on Component controller. It will bring one more screen in the right panel, where component controller details will be shown. WINDOW One Ui component can host any number of windows. But at least one window should be there in the component. Without Window, we cannot show anything on WEB UI. All sub components like VIEW SETS or views will be put in the windows.

COMPONENT CONTROLLER: Every UI component has exactly one component controller. It is a parent controller to all another controllers in the component. It has one method named WD_USAGE_INITIALIZE. We need to deal with this method in number scenarios to transfer the data from one component to another component. We can observe that there is one window created with name MAINWINDOW. We have given this name at starting point when it asked for window name. So far we have created just skeleton. We did not tell the system from where data (service contract details) will come into the UI component. Data will be associated to the UI COMPONENT through MODELS. We will discuss it in the next lesson.


ADDING MODEL Adding MODEL to UI component is just very simple step. However understanding MODEL is complex one. This will be too early to dig into this concept. We will discuss in detail in later chapters as it is a most advanced task. We will just have a look at MODEL and how its looks.

Transaction: GENIL_MODEL_BROWSER. This transaction is used to display the MODELs. Give component as BT in the component field and press one display.

It has different objects. All we want to know is, if we want to show contract information, then we will add BTAdminh object into our component. If someone wants item information, we will work with BradminI object. In order to make all this objects available to our component, we need to add the corresponding model to our component. Let us add the model ONEORDER to our new component. go to the component and click on runtime repository. Click on the edit button and right click on the models and choose ADD MODEL. Give the component set name as ONEORDER and choose continue.

Click on save. We have added the model to our component. So all objects in that model, are available in our component. As soon as we add the model, there is one more option available BOL Model Browser. (If you cant see this option immediately, just reopen the component).


SEARCH VIEW: Visiting any transaction information first requires a search. We need to search the required business object, and then we can view its information. Let us build a search view, which will give us an ability to search service contracts. VIEW A block that is used to display the certain information on the WEB UI. In the entire component hierarchy view comes at the bottom place.

Every view has one controller class. Generally we call it as view implementation class. The class name generally ends with *IMPL suffix. In order to display any view on web ui, it must be assigned to either window or to VIEW SET ( here again VIEW SET must be assigned to the WINDOW). Open the component and click on component structure browser and right click on VIEWS and select the view. We can see another option CREATE SEARCH PAGE. This is a new feature available EHP 1. As we want to know the concepts, choose just CREATE option.

Enter view name and choose continue.

In the next step, we need to add the model node. MODEL NODE: Any context node that is based on any BOL entity, is called Model node. VALUE NODE: Any context node that is not based on any BOL entity is called VALUE NODE. Here we will add model node because we have bol entity. Here we are going to create search page. So we will select a BOL entity that will help us to search the contracts. We will look for objects that belong to dynamic search objects category in the one order MODEL. Enter the context node name and choose the BOL entity as shown below. Once you entered the details choose continue.

BTQSrvCon is a dynamic search object used to find service contracts. We can check it in the GENIL MODEL BROWSER transaction in the ONEORDER component set , under the DYNAMIC QUERY OBJECT node. In the next step, we need to enter the value node. However we are not dealing with any value node here, just press continue until you reach the last step SELECT VIEW TYPE as shown in the below screenshot. Select the view type as EMPTY and complete the wizard. In the last complete step, it will summarize the all details , that we have entered so far. Then we will be asked to save the view. If we observe carefully, we can see the framework will create certain classes. Context node class. ZL_ZTUTCOMP_SEARCHPAGE_CN00 Just double click the newly created view, all the classes that were created will be presented in the tree hierarchy. At bottom , we have context node class. This class will hold the data for our view. We can see all attributes of BOL entity that we added under this class. This class will have most important attributes and methods to manipulate the data.


Every view will have one context class controller, ends with *CTXT suffix. If there is any context node exists, then it will be an attribute of this context class. Here we have one context node SEARCH; we can see this node as property of above class. Just double click on the context class.

View implementation class ZL_ZTUTCOMP_SEARCHPAGE_IMPL. This is main view controller and will be responsible for handling all events raised in the view. The context class will be an attribute of view controller. We can in the below screen shot the context class became an attribute with the name TYPED_CONTEXT.

So in order to access any context node from a method in the view controller, generally we see the below syntax. ME->TYPED_CONTEXT->SEARCH (here ME refers instance of view controller class). You can find this syntax in almost all UI components. So far we have designed just controllers. We did not design anything that user can see on the screen that is layout. We will design the layout in the next chapter.


DESIGNING LAYOUT: When we created the search view, framework automatically creates one .htm page for us. We will use this page to show the output to the user.

BSP technology supports HTML. But in SAP has developed new tags which will make developer work very easy. For all advance search pages, we use <thtmlb: advanced Search> tag to display the input fields. User will enter the selection criteria using these search fields. Just double click on SEARCHPAGE.htm and add the following tag in that page.

When you do syntax check, it will throw some errors. Why? Obviously, this tag has certain properties for which we need to use some methods. These methods do not exist in our class. What to do? Here we need to know one important thing that every normal view controller in the WEB UI is inheriting one class I.E CL_BSP_WD_VIEW_CONTROLLER. Double click on view implementation class, go to properties, you can see ZL_ZTUTCOMP_SEARCHPAGE as super class. Double click on it again and in the properties tab you can find CL_BSP_WD_VIEW_CONTROLLER as super class. For normal view, this class is enough. For search view, SAP has provided another special controller that we need to use to give correct input to the ADVANCEDSEARCH tag. All we need to do is , change the super class of ZL_ZTUTCOMP_SEARCHPAGE from CL_BSP_WD_VIEW_CONTROLLER to CL_CRM_BP_ADVSEARCH_CONTROLLER. This class provides the methods GET DQUERY DEFINITIONS and GET POSSIBLE FIELDS. Go to the class and change to edit mode. Go to the properties tab. Change the description and click on CHANGE INHERITANCE button. Give the class as above mentioned. Choose yes in the next popup.

We are not finished yet, again go to the .htm page and repeat the syntax check. It will throw one more error. This time error related to the context node SEARCH. System will add the context nodes to the .htm page as properties. So that we can use the methods or attributes of context node class.

Here also our context node is not a normal context node. It is a search context node. All general context nodes classes have CL_BSP_WD_CONTEXT_NODE as super class. If they are table type context nodes, then they have CL_BSP_WD_CONTEXT_NODE_TV as super class. However search type context nodes need to have CL_BSP_WD_CONTEXT_NODE_ASP as a super class. This class will provide necessary methods for doing advanced search. Change the super class of the context node class ZL_ZTUTCOMP_SEARCHPAGE_CN00.

Save and activate the class. Now go to the .htm page, we wont any syntax errors. Activa te the page. Now we almost finished the search view. We can test it now. Come back the component and press on test application button. It will invoke new browser session. Give user id and password to complete the authentication.

OOPS. I could not see any output. Its a blank page. Why? Let us discuss it in the next chapter.


When we tested the component in the previous chapter, we could not see anything on the WEBUI. Why? Because, we did not assign our view to any window. As discussed, we need to put the view inside a window to make it visible on the web ui. We will do it in the runtime repository. Open the component and click on RUNTIME REPOSITORY and choose EDIT button. right click on the window and choose the option add view as shown below.

In the next popup, choose the view that exists in our application and continue.

Save the runtime repository by pressing on save button. Now our view is assigned to the MAIN WINDOW of our component.

Test the application again by clicking on the button TEST APPLICATION. In the browser window, we can see the output as shown below.

Its just showing some fields that can be used to search. We cannot perform any search as there are no buttons. If you click on first drop down list, you will a there are number fields available. Sometimes user does not want to see all this fields in the list. In the next chapter, we will provide such facility with the help of configuration.


We have a view where we can enter search criteria. However, we did not write any code to use these selection criteria and based on the selection criteria, we need to fetch results from the database. Let us provide one search button to the user and create one event handler to be triggered when user clicks on search button. CREATING BUTTON: We use THTMLB: button tag to create buttons on the screen. Go to the SearchPage.htm and add the following code to add the button.

Here, we have given search as a value to the onClick property of button. So clicking on button will trigger the event handler. Text is nothing but the text that appears on the button. CREATING EVENT HANDLERS: Event handler name is case sensitive. go to the component browser and click on the view and then right click on the event handler in the right panel. Choose create.

In the next popup, give the event name as search and choose continue. Framework will create one event handler with name EH_ONSEARCH. Now we need to code in the event handler.

We need to know one important method at this point of time. Go to the view implementation class ->properties tab and open the super class by double clicking on it.

Go to the methods section. We can the method with name DO HANDLE EVENT. This is method every time called first for any event handler. From this, the control will be delegated to corresponding event handler depending on the event name.

We can see the based on event name, corresponding event handler is called inside the case statement. So we will look at this method by placing break point here, if any event handler is not working (control is not reaching to our event handler). Now you can place a break point (external) here and test the application. When we click on the search button, control will come to this method and from this method, it will go our search event handler. We will fetch the data and display it in the next chapter, A little complex thing.


Here we are going to fetch the data based on the selection criteria. One important point to keep in mind is, we never use any select queries at the UI level (some exceptional cases may be there). We use BOL programming to search, retrieve, update, and delete the data. We will discuss BOL programming in detail in later chapters. There are some predefine steps to search any data from the UI using BOL programming.

Open the event handler search and paste the following code.

An instance of any dynamic search object can be represented as using the class CL_CRM_BOL_DQUERY_SERVICE. If we remember, we used dynamic search object BTQSrvcon to create the context node. So we declared one reference variable lr_selcriteria. Generally user will enter some selection criteria and then press SEARCH button. So these selection criteria we need to read from the context node SEARCH. LR_SELCRITERIA?= ME->TYPED_CONTEXT->SEARCH->COLLECTION_WRAPPER->GET_CURRENT ( ). Above line does exactly same thing. It will give the selection criteria details in the form of instance of class CL_CRM_BOL_DQUERY_SERVICE and that instance we are taking into variable lr_selcriteria. Next we will fire the method GET_QUERY_RESULT to retrieve the records that match with the selection criteria. This method returns the records in the form of collection (just understand collection as container that holds the records) and we are taking that collection into LR_RESULT of type IF_BOL_BO_COL. Now we have the data. Oops, where to display this data. Yes we forgot to create one more view to display this results. Let us create result view in our UI component.


Let us create result view to show the results of the search. Go to the UI component and create one more view. Give the view name and in the second step, give node name as result and choose the BTQRSrvCon.

Just keep pressing continue until select view type step. Here choose the view type as TABLE and context node as result. Check the configurable check box.

Complete the wizard and save all entries. (Try to observe how many classes wizard will generate while saving. You can see impl class, ctxt class, cn00 class. ) We have created table view successfully.

When you see a table icon next to any context node, then it is a table type view. We can generated classes (tick marks in the screen shot). How come Configuration tab available itself? Well we have chosen configuration check box while creating the view.

There are another two important points we need to keep in mind. First one is, why we have selected BTQRSrvConas an entity ? Answer is, every dynamic search object will give results in the form of result type objects as specified in the MODEL. See the below screen shot. Here BTQSRVCON will give you BTQRSRVCON as a result. Thats why we choose BTQRSRVCON as an entity for our view.

Second one, why we created Result view as a table type. Every search will result more number of records of same type. In order to display all those records, table view is the best one. Now we have developed two views. We need to display it on the web ui. Add the view to the window in the runtime repository (chapter 21). Make one configuration by choosing certain fields. Go to the configuration tab and create one configuration. Click on Edit and move required fields from available fields section to the displayed fields section using the arrow marks. Save the configuration once you added the fields.

Test the application and see what will happen.

It is showing only one view. Next chapter will deal with this issue


Let us create a view set to display the two views that we have created. in the previous chapter, we are able to display only one view. in order to show more than one view on the screen, we need to create view set. Go to the UI component- component structure browser. Right click on views and select create view set option from the context menu.

Give a name to the view set.

Here grid size refers to the number of rows and columns that we need to arrange the views. Here we have two views and one column. Something looks like below. So we have given 2 and 1 as grid size.

Search Result
In the next step, we create view areas. Views will be assigned to this view areas in the runtime repository. We will create two view areas so that each view will take one view area.

Except the result area row value, all cell values are 1. Complete the wizard and save it. We have created view set now. We need to assign the two views to the view set first and then view set will be assigned to the window. Go to the runtime repository , expand the view set node and choose the searcharea and right click on and select the add view option.

In the next popup box, choose the search view and continue. View will be added to the view area.

Repeat the same process to add the result view to the result area view area. Then save the runtime repository using the save button. Something wrong we got the following error. Multiple usage of view is not possible. Cancel the popup and press on NO in the next pop up. Yes, because we already added two views to window. So go to the window and right click on the view and choose remove.

Repeat the same to remove the result view from window. Now save the repository. This time there wont be any error. Next we will assign view set to the window. Follow the same process of adding view to window, to add the view set to the window. Right click on window and choose the option add view. In the next pop up select the view set and choose continue. Save the runtime repository. So far what we have done is, Added views to view set and view set to window. Repository will look like below.

Now test the application. See the difference in the output.

Yeah, it is not a nice format as there is no line between search and result. Let us focus on the content first rather than the format. So we have two views on the screen and we fetched the data in the search event handler. We need to move that fetched data from search view to result view. We use Custom CONTROLLER to accomplish this job. Let us create Custom Controller in the next chapter.


Views lost its data as soon as user navigates away from the view. In order to solve this problem, Custom controllers are introduced. We add same type of context nodes to the custom controllers and do the data binding between the custom controller context node and required view context node. One UI component can have any number of custom controllers.

In our case, we will follow below logic for making data flow across context nodes of different views. 1. 2. 3. We will fetch data in the search event handler ( that we completed ). We will fetch instance of custom controller and feed the data we fetched to its context node. We will do the binding between result view context node and custom controller context node so that data will travel to the result view. Let us create custom controller first. Go to the UI component component structure browser. Right click on CUSTOM CONTROLLER and choose option to CREATE. Give the name that has prefix CuCo*.ex: CuCoSearch CuCo stands for custom controller. In the next step, give context node name as result and entity name as BTQRSrvCon, because we will bind this node to the result view context node. Context node base entities should be same for binding. Just complete the wizard by choosing continuebutton and save the entries. We have successfully created custom controller.

Next we will bind the two context nodes. Go to the result view and Right click on the result context node and choose the option create binding.

In the next pop up , choose the controller type as custom controller as we are binding the data to result view. Choose CuCoSearch.do as view controller in the custom controller field and choose the result context node and press on right mark. Thats it, we have done the binding.

once above step is done, We can observer the binding here.

It is saying the result context node of custom controller is bound to the result context node view RESULT. Next we need to add small part of code to the search event handler to get the custom controller instance and feed the data that we have already fetched. Go to the search event handler of search view and add the below code to it.

At line no 16, we used the method get_custom_controller to fetch the instance of custom controller by giving its name. We are giving the returned data lr_result to the context node result of custom controller. Test the application now just click on the search button. It will show some service contracts. Our search page is working now.


When we tested our application, we have seen that view set name is coming as page title at top. We always have to choose, correct title to our page. Let us change the title of the page. Go to the view set implementation class. Change to the edit mode and redefine the method IF_BSP_WD_HISTORY_STATE_DESCR~GET_STATE_DESCRIPTION.

Just assign meaningful value to the variable DESCRIPTION.

Save and activate the class and test the application.You can notice the change in the page title.


Once we fetch the result, user may wish to have detailed look at the service contract. As we know that we are not displaying all the information in the result list. So its standard functionality to make any column as a hyperlink in the result list. User uses this link to go to the detailed page. It is also referred as Overview page. Overview page is special type of view set, which will give us detailed information about any business object. One business object requires a lot of information to be shown. Ex: service contract has header information, dates information, status information, partner information, line item information, actions information, and transaction history information.etc.

Let us create one form view to show important header information. Later we will add this view to the overview page and provide navigation as soon as user clicks on particular column in the result list. Go to the UI component component structure browser and create new view. Give the name as HEADER. In the next step, give the context node name and choose the entity BTAdminH (This entity is used to represent the contract header information ).

Just keep continue until the step select view type. Here choose the FORM view and check the configurable check box and CHANGE/DISPLAY mode box.

Complete the wizard and save it. we have created one form view. Let us configure the view first. Go to the configuration tab of the view HEADER. It will look like as shown below.

Configuration of form view is little bit different when compared to table view. Click on edit button and choose SHOW AVAILABLE FIELDS. It will display the context node that we created above. If you expand the context node, it will bring the list of fields.

In order to bring the filed from list to displayed section, we need to select the field and click on + button to bring the field into display section. Button is used to remove the field from displayed section. There are different types of display sections available. 1. 16 columns/1 panel: click on Make 16 columns/1 panel. All fields are displayed in 16 column space .Try to add two fields. Two fields will be arranged row by row in one single section. fields will be left aligned.

Remove two fields by selecting each field and press button. 1. 16 columns/2 panel: click on Make 16 columns/2 panel. All fields are displayed in 16 column space in two panels(sections). Try to add two fields. Two fields will be arranged by row by row in one single column. We can also bring the second field by clicking on right arrow mark.

Select the 2 field and click on the right arrow button. It will be moved to the second panel as shown in the below.

We can also adjust the field width by selecting it and pressing ALT+CLICK. This will show field properties. In above screen, field logical system, label spans from column A to column C. field content spans from D to H. Select any field and press Alt + (mouse left click). It will display the field properties.

Here we can change the width of the label and width of the field content. We can also control certain properties of fields. We can also change the label of the field. Display: if we check this check box, then field will be used to just display the value. User cannot enter any value into this field. Mandatory: when this property is checked, framework displays an error message to the user, if he/she does not enter any value into this field. We will test these properties when we complete the entire process. 1. 8 columns/1panel: There will be only 8 columns and single panel. Fields will be right aligned. We can make any kind of configuration here. For example we have created 16 columns/2 panels and added two fields.

We have created just header view. In next chapter we will create one overview page and assign this view to that overview page.


Let us create Overview Page. As the name suggests , it is used to display the entire information of particular business object. a service contract over view page displays information about its header information, status information, line item information, pricing details, action profiles ,partner information ...etc in one single page. this is called overview page. Go to the UI component->component structure browser and right click on views and select the option create overview page.

Give the name to the overview page.

Save the entries. As already discussed overview page is also a view set. Go to the runtime repository editor. Under the view set node, you can find the Contract Overview.

Click Edit button and Expand that view set. Right click on view area Overview Page and choose the option add view.

In the next popup, choose the view header and save the runtime repository.

We have successfully assigned the view to the view set. Next step, we need to assign the view set to the window. Assign this view set ContractOveriView to window ( look at chapter 26 to assign view set to window). Configuring the overview page: Go to the configuration tab of over view page. Click on Edit and choose the radio button Overview Page->continue.

In the next step, we can see the headerview available in the available assignment blocks section as we added this view to the over view page.

Select the view and move it to the displayed assignment blocks section and save the configuration.

Here we can give the meaningful title to our assignment block in the title column. We can see there are three load options available. Direct: if we choose this option, then our view will be displayed always on the overview page along with the content. Lazy: our view will be displayed on the overview page. However in order to see the content, we need to click on the expand button on the assignment block. This option will be used where there is a huge content on the view. Instead of displaying the content every time, it provides a choice to the user to see it or not, by improving performance. Hidden: if we want not to show the view, then this option will be chosen. Next part is we need to show some column in the result list view as a hyper link. So when user clicks on that hyper link, he will navigate to the overview page. Change the over view page title by following the previous tutorial CHANGING THE TITLE OF PAGE. Go to the over view implementation class and redefine the method IF_BSP_WD_HISTORY_STATE_DESCR~GET_STATE_DESCRIPTION and assign one meaningful name to the return parameter DESCRIPTION. Let us create hyperlink first and then navigation in the next chapter.


Let us again go to the result view.

Here we want to make , transaction ID column as a hyper link. When user clicks on any transaction id, he will navigate to the overview page, where he can see that transaction id details. Go to the UI component and result view context node.

In order make any field as a hyperlink we need to code in its P GETTER method. P stands for Property. This method is used to change the property of a field. Right click on it and choose generate P getter method. Frame work will generate p getter method . Green symbol indicates that.

Double click on the method and put the following code inside the method and activate it. Here 'objectid' is an event name that will be triggered when user clicks on that hyperlink.

test the application. we can notice the change in the column ID. each transaction no became as an hyper link.


Creating navigation from one to another view needs understanding of certain methods in the framework. There are certain entry and exit points to a view, which are called plugs. 1. 2. INBOUND PLUG: this is a method which acts an entry point to the view. OUTBOUND PLUG: this method acts as a leaving point from the view. Let us take two views A and B. if we want to navigate from view A to view B. then we will create a outbound plug in the view A as we are moving away from A and one inbound plug in the view B as we are moving near to B. How framework knows the source and target? Navigational link. We define it in the run time repository. This link provides the source and target information to the frame work. Let us create plugs first. Create one outbound plug in the result view as it is a source view. Go to the result view and right click on outbound plug and choose create option.

Give any valid name. Framework automatically adds prefix op. we have given TOOVERVIEWPAGE. Go to the overview page and create one inbound plug. Use the above method to create inbound plug.

Creating navigational link: Go to the run time repository and click on the edit button. Right click on navigation links and choose create.

In the next dialog box, choose the values as shown below. Give the meaningful name to the link.

Source is our result view and target is overview page. Choose continue and save the repository. As discussed, in order to navigate to the over view page, still little coding effort is required. Go to the event handler (eh_objectid) in the result view. Call the outbound plug in this event handler as shown below.

Open the outbound plug method in the result view and add the following code to it.

We have completed the navigation part. Test the application. Carry the search and click on any hyperlink in the result list. We will be taken to the overview page. We got following screen.

Oops, there is no data in the view. Yes, we just completed the navigation. We did not feed any data to this view. How we will do it? 1. 2. We will create one new context node in the existing custom controller. In the event handler that we trigger when user clicks on the hyperlink, we will feed the data to this context node. 3. We will bind the context node of header view to the context node of custom controller so that data will flow to the header view. Let us create a context node in custom controller.


Go to the ui component component structure browser. Open the custom controller. Go to the context node level and right click on context node and choose CREATE option.

In the wizard, give the context node name and choose the model entity as BTAdminh.

Why we have chosen BTAdminh as model entity? Because we need to do data binding between this node and node of view header. The base entity that we mentioned for header view is BTAdminh. Entities must be same to bind the data. Just complete the wizard and save the entries. We have created context node. Then we need to bind the data. Go to the view header and right click on the context node header. Choose the create binding option.

In the next dialog box, choose the values as shown below.

We have chosen the context node that we have created in the custom controller. Choose continue to complete the binding. Now data will flow from custom controller context node to header view context node. However we still need to feed the data to the custom controller context node. That we will do in the event handler of result view.


Go to the event handler of result view EH_ONOBJECTID and do the following modifications to set the data in the custom controller context node. Logic: 1. record. 2. 3. We need to find out on which record user has clicked in the result view and we will read that Get the instance of custom controller. Add the found record in the first step to the context node of custom controller.

go to the event handler and do the following changes in the code.

Getting correct type record needs understanding the MODEL. In our case, lr_clickedrecord is of type Query Result Object BTQRSrvCon. But in the header view in the over view page and header context node of custom controller, we used BTAdminh entity. So we cannot add BTQRSrvCon directly. We need to find out the BTAdminh from BTQRSrvCon. In these situations, we will use relationships between entities. We need to take a look at the MODEL. Based on the model, we will have to know what are the relationships that we have to use to fetch the required entities.

If we observe carefully, from the Query Result Object BTQRSrvCon, there is a relation Association BTADVSSrvCon Child Cardinality 1 to the Root Object BTOrder. Again from Root Object BTOrder, there is relation Composition BTOrderHeader Child Cardinality 1 to the Access Object BTAdminH, which we required. This is what exactly we have done in the coding. First we fetched the Border and then from the BTOrder, we fetched BTAdminH. Dont worry if you scared after reading this. Understanding model and writing code in BOL will require patience and time. The more practice you do , the more you gain. What we need to remember is, get_related_entity will fetch the required entity from source entity based on the relation name. We have completed the coding part as well. Go and test the application. Now we can see the data in the header view.

If we observe, the title of the page does not suit to the page as we are not searching for any contracts on this screen. Back button at top right corner is disabled. Once we move from the search to overview page, there is no way to go back. Let us solve this first as it will take less time.


As discussed in the previous tutorial, once we navigate from the search page to the overview page, we are not able to come back to the search page. In the below screen shot, we can see that back button at top right corner is disabled. So we cannot navigate back to the search screen.

in daily work scenario, user may visit number transactions. bread crumbs will help him to visit the transactions that had already been visited by him. Providing this feature is very important to the user. Let us do it. We need to do one line coding and rest will be taken care by WEB CLIENT FRAMEWORK. Go the search overview set implementation class and expand the controller initialization and destruction. Right click on the method WD_DESTROY and choose redefine the method.

Add the following code to the method and activate it. DO NOT FORGET to call the super class method as shown below.

Now test the application. Perform the search and go to the over view page. We can notice the back button is enabled to come back to the search page again.

TASK FOR YOU: 1. change the overview page title . 2. forward button is still disabled. In order to enable it follow the same procedure as above in the overview page implementation class. Then both back and forward buttons are enabled. Once you come back to the search page, you can again go to the over view page using forward button.

Click on it, we can navigate back to the search page.

Where is our Search View? We can see the result view but what happened to the search view? Answer is, we forgot to bind the search view context node to the custom controller context node. If you remember correctly, we bind the result view context node to the custom controllers result context node. This is why data on the result view stayed. We did not bind the search view context node to any custom controller, so we lost the data. That is why we use the custom controllers. We hope now you can get clarity on custom controllers. Let us resolve this issue now in the next chapter.


Treat this chapter as something you need to do it as we have already explained how to create context node at custom controller level and bind the context node from view to the custom controller. Let us put steps that we need to follow. First we need to create one context node at custom controller level using the entity BTQRSrvCon. Why we use this entity because we used same entity in the search view. Second, we need to create data binding from the context node of search view to the above new context node.

We strongly recommend that first try it yourself by looking at the chapter Creating context node at custom controller. Then only look at below content. All steps are same except the entity name. So we will be using only screen shots here. First step

Just complete the wizard by pressing continue for all remaining steps. Context node created. for data binding : step1.


now test the application, visit the over view page by clicking on hyper link. come back to the search page by clicking on back button.


When we know particular field will take some predefine values, then we will make it either a drop down or will provide a F4 help. If number of predefined values is less, then we will choose drop down. If they are too many, then F4 help is a better way. Let us make Process type field on search view as a drop down so that user will choose predefine values from the list.

1. 2.

There are two methods in which we need to code to make a particular field as a drop down. GETTER P method: in this method we tell to the frame work that this particular field will act as a drop down. GETTER V method: Here we will provide the values to be shown in the drop down list. As we want to provide the drop down list to the process type field on the search page, we need manipulate of above mentioned methods of that attribute. Go to the search view, expand the context node and choose the search context node and again expand the attributes.

Select the required attribute. Right click on it and choose the options GENERATE V GETTER and PGETTER methods one by one to generate the corresponding methods.

Once you generate , you can see the methods generated under the attribute.

Double click on the GET_P_PROCESS_TYPE method and add the following code in that method.

Go to the V getter method and copy paste the following code.

Thats it. We have created the drop down for particular field. We can use any custom table and query it if we want to show the custom table data as a drop down. Values should go always as key pairs. On the web ui, frame work only shows the values. Go for the drop downs when for small values of list. Go and test the application to see the drop down list.

Most of the times, providing F4 help for particular field at WEB UI level requires creating a search help in SE11 transaction. Let us create one search help in SE11 first. Go to the SE11 transaction and create one search help. Enter the values as shown in the below. Here we want provide a F4 help to the partner function field at search view.

Selection method is a table name from which values will come. Activate the search help. Go to the UI component and go to the field for which F4 help has to be provided. Here we want to provide it for PARTNER FUNCTION field at search view. Go and generate the v-GETTER method.

Once method is generated,copy and paste the following code.

To make the developers work easy, SAP has provided one standard class CL_BSP_WD_VALUEHELP_F4DESCR. We just need to create one stance of this class by providing some information. 1. Help id : This is search help id that we created in se11.


Input mapping : to provide the mapping between the context node attribute and the attribute in the search help. Here we are providing the f4 help to the PARTNER FUCNTION field. so at line 9, we have given the STRUCT.PARTNER_FCT to the input mappings CONTEXT_ ATTR. In the next line, we mapped it to the PARTNER_FCT in the SE11 search help.


Outputmapping: once user selects any value on the F4 help, we need to transfer the selected value back to the field. This information will be given in the output mapping. In lines 14 & 15, we have done this by telling framework to transfer the value from the PARTNER_FCT to the context node attribute STRUCT.PARTNER_FCT

Activate the method and test the application.

Here we can see two fields at top, partner function, text to search entries. These fields are appeared here because we have given the values 1 and 2 in the SPos column in se11 while we created the search help. If we had left this column blank, then these fields wont appear. Select any value. Value will be automatically transferred to the partner function field. We can every restrict the search by sending values as below . '\''Z*\''' Comment the STRUCTU.PARTNER_FCT and uncomment above value in the line no 9. Activate the method and test the application. Your f4 will be shown as below. All entries that start with Z will be searched.


It is worth to take a look at this most important class. Every record in the BOL will be represented by this class CL_CRM_BOL_ENTITY. We have coded some event handlers so far and we have worked on this class directly or indirectly. In the business scenario, we may work with contracts, orders, leads, service orders, confirmations and etc. At the WEB UI level, all these business objects information can be represented using this class. This is the flexibility of BOL (Business object layer). There may be 100 of different objects, but we use one single class to represent the information. Let us see the data in the debugging. Place an external break point in the search event handler in the search page. Run the application and carry on the search.

Once break point is triggered, double click on the lr_result. Execute the line no 14 by pressing F6. It is a collection that holds all records.

Double click on it. This is collection class holds ENTITY LIST, which stores the records. Double click on it.

can see the list of object references. Each reference is type of CL CRM BOL ENTITY.

Here collection holds 10 records. Double click on any record. We can see the container proxy property as shown. Double click on it.

You can see the DATA_REF property. Double click on it. You will get following screen.Double click on highlighted part.

In the next screen, we can notice the object name BTQRSrvcon. There is one attribute ATTRIBUTE_REF. double click on it.

We can see the data now.

We need to traverse a couple of screens to see the data. This is the flow. CL CRM BOL ENTITY ->CONTAINER_PROXY->DATA_REF->ATTRIBUTE_REF. This is how we can see the data of any object. Let us discuss most important methods of this class in the next chapter.


SEND AN EMAIL TO CRMWEBCLIENT@GMAIL.COM IF YOU WANT BELOW CODE. ********************************************** *BOL PROGRAMMING *SAP CRM WEBCLIENT *GIVES INTRODUCTION TO * basic activities like search, create, update in the bol *programming in order to give introduction to the main classes and methods of business object layer. **********************************************

*used data DATA: lr_core TYPE REF TO cl_crm_bol_core. *in order to use any service of BOL, we need to start the MODEL (component set) using * CORE class. lr_core = cl_crm_bol_core=>get_instance( ). *once we have the instance, then load the component set. *here we will be using ONEORDER component set. *when we are working on web ui, this will be handled by framework. here we are doing it in the report programming so we need to handle it TRY. CALL METHOD lr_core->load_component_set

EXPORTING iv_component_set_name = 'ONEORDER'. CATCH cx_crm_genil_general_error . ENDTRY. *component is loaded, so we can use the BOL services. Let us search for a particular *contract. for that we need to get an instance of dquery service class. DATA: lr_query TYPE REF TO cl_crm_bol_dquery_service, lr_result TYPE REF TO cl_crm_bol_bo_col.

*****SEARCH OPERATION*********************** "get the instance of dynamic search object,which will be used to search service contracts. lr_query ?= cl_crm_bol_dquery_service=>get_instance( iv_query_name = 'BTQSrvCon' ). "Every dynamic search object will have its own result type object. here BTQSrvcon has BTQRSrvcon as r esult object. "so in the result list all objects are type of BTQRSrvcon. "we got the instance, so we need to set the selection criteria. "fetching all contracts whose description is 'testing'. "you can call this method multiple times to add different selection parameters. lr_query->add_selection_param( iv_attr_name = 'DESCRIPTION' iv_sign = 'I' iv_option = 'EQ' iv_low = 'testing' ). "get the list contracts that match the selection criteria in the form of collection. "collection is nothing but a container that holds records. we can compare it like a internal table "that holds records. lr_result ?= lr_query->get_query_result( ). "Let us print the contract id and description of all records in teh collection. "cl_crm_bol_entity is used to represent the record in the BUSINESS OBJECT LAYER. DATA: lr_entity TYPE REF TO cl_crm_bol_entity, lv_objectid TYPE string, lv_descr TYPE char40. "read the first record in the collection. lr_entity ?= lr_result->if_bol_bo_col~get_first( ).

"following while loop mechanism is used to visit each record in the collection. WHILE lr_entity IS BOUND. "read the contract id. "get property as string will return attribute values in the form of string. so we declared lv_objectid a s string. lr_entity->get_property_as_string( EXPORTING iv_attr_name = 'OBJECT_ID' RECEIVING rv_result = lv_objectid ). "get property as value will return the value as it as.so we declared DESCRIPTION with data element. lr_entity>get_property_as_value( EXPORTING iv_attr_name = 'DESCRIPTION' IMPORTING ev_result = lv_descr ). WRITE : lv_objectid, lv_descr. WRITE /:. "read the next record in the collection. lr_entity ?= lr_result->if_bol_bo_col~get_next( ). ENDWHILE.

**************UPDATING OPERATION*************************** "Let us change the description of one service contract. "get the curren entity from the result list. "Every collection holds one pointer which always points to the current record we visited.We generally c all it is a focus "in the BOL language. so get current returns the object which has focus. so what ever the last object w e visited in the "above loop, will be fetched in the below statement. lr_entity ?= lr_result->if_bol_bo_col~get_current( ). IF lr_entity IS BOUND. important in BOL. "we never work on object references which are initial. this is check is very

"can we use the set property as string directly on this lr_entity?. "No, it is dynamic query result object, generally all properties of these type objects are read only. "DESCRIPTION is property of BTAdminH object. we need to get it using the relations. We need to tak

e help from MODEl to see "what are the relations that we need to go through to reach the target object. Transaction GENIL_M ODEL_BROWSER "in our scenario, we have BTQRSrvcon as a soruce in the lr_entity variable. This object has a relation 'Association BTADVSSrvCon Child Cardinality 1' "which will give the object BTOrder. "again BTOrder is having a relation 'Composition BTOrderHeader Child Cardinality 1', which will fetch the target object BTAdminH. this object has "an attribute 'DESCRIPTION'. "while looking at the relations, look at the cardinality of relation. if cardinality is 0...1, then relation always fetch one single entity. if is "0...N, then relation will fetch multiple entities. " use the GET RELATED ENTITY when cardinality is 0...1. " use the GET_RELATED_ENTITIES when cardinality is 0...N. DATA: lr_order TYPE REF TO cl_crm_bol_entity. "read the BTORDER first. " the parameter iv_mode will take another value 'b', which stands for bypassing the buffer. "which means, framework will ignore the values that exist in the bol buffer and read the target "entity values from the database by triggering required APIs. it can decrease the performance. so us e only in necessary "situations like when you are reading that particular entity first time.. TRY. CALL METHOD lr_entity->get_related_entity EXPORTING iv_relation_name = 'BTADVSSrvCon' iv_mode = cl_crm_bol_entity=>bypassing_buffer RECEIVING rv_result = lr_order. CATCH cx_crm_genil_model_error . ENDTRY. "we got the order, then read the BTAdminH. DATA: lr_header TYPE REF TO cl_crm_bol_entity.

IF lr_order IS BOUND. TRY. CALL METHOD lr_order->get_related_entity EXPORTING iv_relation_name = 'BTOrderHeader' iv_mode = cl_crm_bol_entity=>bypassing_buffer RECEIVING rv_result = lr_header. CATCH cx_crm_genil_model_error . ENDTRY.

ENDIF. "we got the BTadminH. change its DESCRIPTION property. IF lr_header IS BOUND. "before changing any property of BOL object, we need to lock it. "this will be accomplished by lock method.

IF lr_header->lock( ) = abap_true.

"if we get the lock, then only continue

"we use set_* methods to change the properties of BOL objects. lr_header->set_property_as_string( EXPORTING iv_attr_name = 'DESCRIPTION' iv_value = 'changed' ). ENDIF. "once change is done, we need to tell about this change to the framework. "we will use core class for this. lr_core->modify( ). "then get the transaction from the entity and check whether this save is possible or not. DATA: lr_transaction TYPE REF TO if_bol_transaction_context. lr_transaction ?= lr_header->get_transaction( ). IF lr_transaction IS BOUND. IF lr_transaction->check_save_possible( ) EQ abap_true. "if we can save , then save the transaction and commit the changes. IF lr_transaction->save( ) EQ abap_true. lr_transaction->commit( ). ENDIF. "we changed the object description. read it again to get the new value. lr_header->get_property_as_value( EXPORTING iv_attr_name = 'DESCRIPTION' IMPORTING ev_result = lv_descr ). ENDIF.


***************CREATE operation***************************** *Let us create one service contract and fill some of its properties. *"first step , we need to create DATA: lr_factory lr_order_new ls_params lt_params the root entity. TYPE REF TO cl_crm_bol_entity_factory, TYPE REF TO cl_crm_bol_entity, TYPE crmt_name_value_pair, TYPE crmt_name_value_pair_tab.

ls_params-name = 'PROCESS_TYPE'. ls_params-value = 'ZSZ'. APPEND ls_params TO lt_params. "create root entity will be handled by the factory class. we use CORE class "to get the instance of required factory class by sending the root object to its "method get entity factory. then we use CREATE method of factory class by sending "the necessary parameters. "here we are creating contracts, so we are sending the process type as input. lr_factory = lr_core->get_entity_factory( 'BTOrder' ). lr_order_new = lr_factory->create( lt_params ). IF lr_order_new IS BOUND. "BTOrder is having only GUID, we need to get BTAdminH entity to fill up some of its properties. TRY. CALL METHOD lr_order_new->get_related_entity EXPORTING iv_relation_name = 'BTOrderHeader' iv_mode = cl_crm_bol_entity=>bypassing_buffer RECEIVING rv_result = lr_header. CATCH cx_crm_genil_model_error . ENDTRY. "fill the properties using the setter method IF lr_header IS BOUND. "#EC NOTEXT

"we use set_* methods to change the properties of BOL objects. lr_header->set_property_as_string( EXPORTING iv_attr_name = 'DESCRIPTION' iv_value = 'New Contract' ).

lr_core->modify( ). lr_transaction ?= lr_header->get_transaction( ). IF lr_transaction IS BOUND. IF lr_transaction->check_save_possible( ) EQ abap_true. "if we can save , then save the transaction and commit the changes. IF lr_transaction->save( ) EQ abap_true. lr_transaction->commit( ). ENDIF. "we changed the object description. read it again to get the new value. lr_header->get_property_as_value( EXPORTING iv_attr_name = 'DESCRIPTION' IMPORTING ev_result = lv_descr ). ENDIF. ENDIF. ENDIF. ENDIF.


Let us have a small discussion about form view and table view. TABLE VIEW: We use table view, to show multiple objects which are of same type. For ex: one service contract has many line items.

Here to show the line items, we use table view. We bring important fields of line item together and display it. As we know that even a single line item will have its own information. So we make one particular field as a hyperlink and provide ability for user to navigate to other pages where he can see detailed information of line item. This provides readability for user. Just imagine if we decide to show each line item as form view on service contract page. 10 line items will easily take up entire space on page. If there are two objects A and B. if the relation cardinality is 1.n, then A will be shown as a form view and table view will be used to show B. This is just a hint. FORM VIEW: It is used to display the most important information of an object by taking information from various related entities. For ex: if you look at service contract details, there we can see service contract id, its description, its main partners, its status, created date and end dateetc . It will give you just an over view about service contract.

TABLE VIEW It can have more than one context node. However only one context node will be base for table view. Context node class has CL_BSP_WD_CONTEXT_NODE_TV as its super class. Chtmlb: configCellerator or chtmlb:configTable tag is used for its configuration. New attribute should be added to the existing context node which is base for table view.

FORM VIEW It can have many context nodes.

Context node class has CL_BSP_WD_CONTEXT_NODE as its super class Chtmlb:config tag is used for its configuration in the .htm page.

New attribute can added to existing context node or a new context can be created with the new attribute

We know that every service contract can have multiple line items. In order to display those items, Let us create one table view in our component. Go to the component and create one new view. Give any suitable name to the view. In the step, ADD MODEL node, we will create dependent nodes. First create one context node with BTAdminh as base entity. This will context node will act as a parent context node. Next click on CREATE button as highlighted in the screen shot.

It will add one new row. Enter the context node name and choose BTItems as a base entity. We need this context node dependent on the HEADER context node. So click on the higher level model node. It will show header context node. Choose it.

Then we need to specify the relation between the base entity of higher level context node to the base entity of dependent context node. Click on BOL relation and choose the value.

We need to add one more model node, which will be dependent on ITEMSET node. Click on create and in the new row give context node name and choose BTAdminI as base entity. To make it dependent on ITEMSET context node chooses entries as shown below.

Here BTAdminI is dependent on BTItems and BTItems dependent on BTAdminH. So if we are able to feed the data to BTAdminH. With help of relations, required data automatically flows to its child nodes. Just click on continue up to the step CREATE LINKS TO CUSTOM CONTROLLERS. Here we bind the HEADER context node in our table view to the HEADER context node of the custom controller. So that data will automatically flow. Choose the entries as shown below.

In the step SELECT VIEW TYPE, choose the view type as table type. Here we need to specify which context node will act as a base for our table view. As we want to show line item details, specify the last context node and choose the option configurable check box. Complete the wizard.

Why we have created three context nodes ? The answer lies in the design we chose and the model on which we are working. First we have created BTAdminH (header context node). We need to feed data first to this one because its independent node in our hierarchy. For this we have done the binding from this context node to the context node of custom controller while creating view itself. So feeding data to the top node is done.

When we create dependent nodes with relations, framework will automatically add code to one method called ON NEW FOCUS of context node classes. See the below screen shot. This method will be used to fetch the data for dependent nodes based on the data from their corresponding parents.

Let us examine this . Go to the context class *CTXT and find the method CREATE CONTEXT NODES.

Double click on it to see the code. This method will be used to create all three context nodes.

As per the code, first CREATE_HEADER method will be triggered. Double click on it to see the code.

We can see the method DO CONEXT NODE BINDING. As soon as header node is created then binding is done to the custom controller context node(This code is there because we bound it to the custom controller while creating view). So data will flow from the custom controller context node to this header context node. Data is feeding to the top node is done. Next go back and double click on next method CREATE_ITEMSET.

Here, from 18 and to 21, they are reading record from header context node and at 25, they are calling the ON NEW FOCUS method of ITEM SET ( dependent of header ) by sending the record from the header context node. Double click on NEW FOCUS to see the code.

Here you can see the relation that we have given while creating second context node. So data is read from the top node using the relation and feeding it to the context node collection.So data from top node is reached to its dependent. Go back to the CRAETE CONTEXT NODEs method and double click on the last method.

We can see now they are reading the record from the second context node ( the data feed to second context node is done in the on new focus of second context node class ) and again calling the on new focus method of third context node class by sending the second context node record ( parent of last context node ). Double click on the on new focus again, you can notice that data is fetched from using method get related entities and relationship name is the relation that we mentioned while creating third context node. So data to the last context node is done from the second context node. This is how dependent context nodes work. First configure the by moving required fields from available fields section to the displaying section on configuration tab.

Go to the runtime repository add our view to the overview set and save the repository.

Now that view will be available in the overview set page configuration. Move it displayed assignment blocks section. (CREATING OVERVIEW PAGE).


While designing any view or any component, we need to design it in such way that it can be reused. The main goal of UI component is reusability. For ex : Almost every transaction deals with partners (customers ). If we want to display those partners on web ui , we need to design a view. Here we wont design a separate partner view for service contracts, one more view for service orders, one more view for service confirmations and one more for opportunities. Instead what we do is we will design one view and reuse it in other transactions. There are some steps that we need to do in order to make a view reusable. First, we should design the view in such way that, it can take data from outside. Second, we need to assign this view to a window. Third, window should be exposed in the interface view section in the runtime repository. Fourth, required context nodes of component controller should be exposed in component interface>interface controller->context section. Then we can reuse this view in any other component by creating component usages.

Let us discuss all points one by one in detail with a practical example. In the next chapter, we will try to reuse a view PARTNER from component BTPARTNER. View must be able to take the data from outside.

Generally data, which come from outside (from another UI component) , fed to the context nodes of component controllers. So one should create binding between the context nodes of component controller and context nodes of view. Here direct binding is not necessary. We just need to make sure that data flow is there from component controller context nodes to the context nodes of view that we want to reuse.

We can see the BTPARTNERSET context node in the view PARTNER is bound to the context node of component controller. Assign the view to WINDOW. The view should be assigned to a window. Then this window will be exposed in the runtime repository as an Interface view for component. Go to the runtime repository.

Partner view is assigned to window. We can a more windows here and each window is having one view assigned to it, making each view a reusable unit. Window should be exposed in the interface view section in the runtime repository. Go to the runtime repository -> component interface section. The window partner list is added as an interface view.

Required context nodes of component controller should be exposed in component interface>interface controller->context section. Required context node BTPARTNERSET has been exposed in this section. Exposing a context node in this section enables it to be bound by other context nodes of different UI components. We use a special method of component controller WD USAGE INITIALIZE to bind the context nodes of different UI components.

We all set to reuse this view in our own component. Let us do it in the next chapter.


Read What it takes to reuse a view before reading this chapter. Go to the component ->run time repository and create a component usage. Click on edit button and right click on component usage and choose the option add component usage.

In the next dialog box, give name to the component usage and details of interface view and component that we want to reuse.

Choose continue once you enter the details. Now this interface view will act as view in our own component. Add this view to the overview page.

Save the runtime repository. Go to the configuration tab of overview page and add the new view to displayed assignment block section.

Now we need to take care of data. In the previous chapter, we know that there is one context node BTPARTNERSET of component controller of component BTPARTNER. So we will create one new same context node at component controller level in our own component. Go to the component controller and create one context node with base entity BTPartnerSet.

Give the base entity name and complete the wizard.

We have created the context node. Then we need to give the data to this context node. There are no of ways doing it. Let us do it through coding. As we know, in the event handler (will trigger whey user clicks on hyper link) of result view, we got the BTAdminh entity. We will fetch related BTPARTNER SET from it and feed it to the context node of component controller.

Do the following changes in the event handler. Save and activate it.

(This is just part of changed code regarding above scenario. Previous code remains as it as ). once we got the header entity BTAdminh, we got its related entity BTPARTNERSET using the relation. Once we got the required record we added it to the collection and this collection is fed to the context node of component controller. Data feeding to context node is done. There is one more important binding left between the context node of our component controller to the context node of BTPARTNER component controller. As discussed we will use the method WD USAGE INITIALIZE to do this job. Go to the component controller and redefine above mentioned method.

Once you redefine, and then double click on that method to open it. write the following code in it and activate it.

Sharing data across context nodes of different components is done. Test the application. If service contract has any partners, then data will be displayed in the partner assignment block.


Before doing operations like edit, save and create operations, we need to know one concept called VIEW GROUP CONTEXT. When we are on overview page, certain times, we need to put all assignment blocks in edit mode and some times, only few or one assignment block should be edited. Every implementation class of view has one attribute called VIEW_GROUP_CONTEXT which is type of IF_BSP_WD_VIEW_GROUP_CONTEXT. At runtime view group context instance can be represented using the class CL_BSP_WD_VIEW_GROUP_CONTEXT. Generally we create an instance of view group for top level controllers. Suppose if OP is an overview page, which is hosting three different assignment blocks A, B and C. Then we will set the property VIEW_GROUP_CONTEXT of OP implementation class. Remaining views A, B and C will automatically inherit its parent view group context. Here their parent is OP. We use SET_VIEW_GROUP_CONTEXT method to set the VIEW_GROUP_CONTEXT property. When setting this property, we always check whether its parent view group context is initial or not. If it is initial, then only we will create one instance of class CL_BSP_WD_VIEW_GROUP_CONTEXT and assign this instance to the VIEW GROUP CONTEXT property. Code will look like below.

We can see that we are checking first parent view group context. If it is not initial, then we are assigning it to the current view viewgroupcontext property else we are creating new one. This class offers some methods to control the display mode of views. In order to set a view in editable mode, we use IF_BSP_WD_VIEW_GROUP_CONTEXT~SET_VIEW_EDITABLE method by sending the instance of view implementation class to it. In order to check, whether a view is in editable mode or not, we use IF_BSP_WD_VIEW_GROUP_CONTEXT~IS_VIEW_IN_DISPLAY_MODE method by sending the instance of view implementation class to it. To put all views in editable mode, we use IF_BSP_WD_VIEW_GROUP_CONTEXT~SET_ALL_EDITABLE ( ). This method will be used in top level controllers like OVERVIEW PAGES. To make any view which is in editable mode in to display mode, we use IF_BSP_WD_VIEW_GROUP_CONTEXT~RESET (). This method not only reset the current view group context but also reset the view group context of its children. Users who generally work on transactions may know that clicking on CANCEL button on top will put all views in to display mode at one go. Whenever we use IF_BSP_WD_VIEW_GROUP_CONTEXT~SET_VIEW_EDITABLE method, it simply adds our view to one internal table. See the below code.

Later when you use the method IF_BSP_WD_VIEW_GROUP_CONTEXT~IS_VIEW_IN_DISPLAY_MODE, it by sending instance of view controller, it simply checks whether this controller is there in the internal table or not. If it is there, then it will return false saying that it is not in display mode else it will return true.

This flag will be given to the DISPLAY MODE property of major configuration tags. So finally based on this value returned by the above mentioned method, configuration tags will decide to make a view editable or not. You can find below code on major views .htm pages. Like below.


Before reading this tutorial, create one context node at overview page level with base entity BTAdminh and bind it to the context node(which has base entity BTAdminh) of custom controller. (Refer custom controller and data binding and CREATING CONTEXT NODE ) Go to the overview page implementation class and redefine the method SET_VIEW_GROUP_CONTEXT. Write following code and activate it.

Let us add three buttons to the overview page to provide EDIT, SAVE and CANCEL operations. In order to add buttons to overview page, we need to add the code to the method IF_BSP_WD_TOOLBAR_CALLBACK~GET_BUTTONS of over view page implementation class. Go the overview page in UI component and redefine the method by choosing the option redefine after right clicking on it. After redefining it, double click on it to open the method.

Add the following code activate it.

When you are adding a new button to standard SAP overview page, do not forget to call the super class method. ON_CLICK: we will assign event handler name to this property. So when this button is clicked, event handler will be triggered. (event handler name is case sensitive ). TYPE : we can specify an icon over here. CL_THTMLB_UTIL has number of icons.

PAGE_ID : it is page id in framework language. It could be look like this. C1_W1_V1 where C1 is your component controller and W1 is window and V1 is your current view. Enabled : if this property is true, then button is enabled else disabled. It is a standard scenario that once you click on EDIT button, page will be in editable mode. In this mode only we will enable save ,cancel buttons and Edit button will be disabled. When user clicks either SAVE or CANCEL, then again EDIT button will be enabled. SAVE and CANCEL buttons will be disabled. We are manipulating the ENABLED property of each button exactly in above mentioned way. We will discuss the scenario for EDIT button. Its clear that , to edit or save or cancel, there should be data. So we are reading the data from current context node into lr_header. First conditions is LR_HEADER is BOUND, which means if there is data, second is LR_header>IS_CHANGE_ALLOWED which means, if data can be changed (why we are testing this condition because the same data may be locked by different user at this point of time) and last condition is VIEW_GROUP_CONTEXT->IS_ANY_VIEW_EDITABLE = ABAP_FALSE which means, no view is already in EDIT mode, then enable the EDIT button else disable it. You can try to understand the logic for remaining buttons. Activate and test the application.

We can notice all buttons are coming under group MORE. This is happened because we forgot to redefine one more method IF_BSP_WD_TOOLBAR_CALLBACK~GET_NUMBER_OF_VISIBLE_BUTTONS. This method controls the no of visible buttons on tool bar. Redefine it and give any integer value greater than 3. If you give 4, then four buttons will be visible on tool bar and remaining buttons if exists any will be displayed as above.

Test the application. All your buttons should be visible.


We have added three buttons EDIT, CANCEL and SAVE buttons to the over view page in the previous tutorial. Let us code in the event handlers of those buttons. Go to the component and overview page and create event handlers wit h name EDIT, CANCEL and SAVE. (Event handler names are case sensitive;all these name of event handlers should match with on click properties of buttons that we have created in the previous chapter). EDIT event handler. Write the following code in the event handler.

First we are reading current record from the context node HEADER into LR_ENTITY. Next, we are checking, it is bound or not. Next we are using method IS_CHANGE_ALLOWED or not, if change is allowed, then we are applying LOCK on that record. Next if lock is successful, using VIEW_GROUP_CONTEXT, we are setting all views editable else we are just resetting the view group context, which put all views into display mode. CANCEL event handler:

We are reading the current record and getting the instance of transaction from it. calling the revert method will cancel all the changes that we have done. Calling reset method will put all views into display mode. SAVE event handler:

We are reading the current record from the context node. If node is bound, then we are taking the transaction context of it. If it is initial, then we are asking core class to provide the transaction context. Then we are checking whether save operation is possible or not using CHECK_SAVE_POSSIBLE method. If we can save the transaction, then we are calling SAVE method and commit the work with one more method COMMIT. One save is done, then put all views into display mode by resetting the view group context. Activate all methods and test the application. Clicking on EDIT button will make all views shift into edit mode.

Press cancel button, all views will go into display mode. Next , we will learn one important topic called UI OBJECT TYPE.


With the help of UI object types in CRM, we can do following things. 1. 2. 3. 4. 5. We We We We We can make different VIEW CONFIGURATIONS can create DYNAMIC NAVIGATION can CONTROL FIELD LABELS, VALUE HELPS FROM DESIGN LAYER. can control the visibility of attributes of BOL objects. can give access to our Z components from navigation bar.

One UI object type will have design objects grouped under it and each design object can control attributes of BOL objects. As a first step, We will create one call back class. Go to the transaction SE24 and create one new class. This class should have interface IF_BSP_DLC_OBJ_TYPE_CALLBACK.

Let us make one new UI object type. Follow the below path in the SPRO transaction. In the next screen choose new entries.

Enter the entries as shown below and save them.

Call back class is used to provide sub object types which will be useful in creating view configurations. Give the class name that we have created above. We will implement required method later point of time. Next we are going to use this UI object type on service contracts, give the genil component name (BT). BTOrder is main root object of BT component. BUS2000112 BOR refers to service contract type. SAVE the entries. We have created new UI object type. As next step, we need to create a design objects under this new UI object type. Follow the below path in spro Customer Relationship Management-> UI Framework-> UI Framework Definition->Design Layer-> Define Design Objects. It will ask for UI object type. Give the new UI object type that we have just created.

Click on new entries. Enter the following information and save the entries.

Once you save the entries, click on DESIGN on the same screen. it will open a new screen like below.

Click on new entries. In the next screen fill up the entries as shown below.

Here I want to control the OBJECT_ID attribute of BOL object BTAdminH. So I have chosen the OBJECT_ID. In the LINK TO BUSINESS OBJECT LAYER, we can mention any another BOL object and its attribute if we want. I also added the new field label. If we choose HIDDEN, then this field wont be available for any configuration (it wont be shown in the available section on configuration tab in the view). We can also make particular field as a drop down or check box if it has some value range by selecting the check box VALUEHELP from ABAP dictionary. (We will see it later). Once data entry is done, then save the entries. We are ready with UI OBJECT TYPE and design object. In the next step, we need to assign it to the required context node with base entity BTAdminH. We will do it in the next chapter.


Certain times, there may be requirement where we need to load the required configuration based on some conditions. For ex: we know that one business partner can be created in any one of three groups. INDIVIDUAL, ORGANZIATION and GROUP. When user wants to create a customer as INDIVIDUAL category, then we need to show different screen to the user with fields like first name and last name. If he wants to create a business partner in ORGANIATION category, then we need to show him separate screen with fields like NAME_ORG1. Here we need to show different to screens to the user based on partner category. Here each screen is nothing but a view configuration. In these situations, we will take a help from the method DO CONFIG DETERMINATION. As name suggests it used to determine the required configuration at run time. In this method we put logic to determine correct configuration keys and then call one more method SET_CONFIG_KEYS to load the correct configuration based on the fed configuration keys. Let us see a example. In the ASSIGNING UI OBJECT TYPE TO CONTEXT NODE, we have created one new configuration with UI object type . Let us load that .

Here there are two configurations exist for view. If we execute directly, system will load first configuration like below. Here you can see OBJECT_ID labeled as TRANSACTIO No.

Second configuration is there with UI object type ZOBJECT_TUT. This configuration looks like below. Here OBJECT_ID labeled as CONTRACT ID.

If I execute the application , this is what I got as output.

It is loading default configuration. Let us make it to load second configuration. Go the VIEW implementation class and look for the method DO CONFIG DETERMINATION. Redefine it. Just add the following line to it.

Just activate it. Here ZOBJECT_TUT is object type that I used when defining second configuration. I am not using any sub object type here as I dont have any sub object in the second configuration. Test the applications once activate is done. You can see the framework will load the second configuration.

This is how we can load required configuration. This is simple example, we can use any base condition to load required configuration. We can have many configurations and can load required configuration dynamically. We left one small concept i.e. defining sub object types. Let us again go back to the callback class created in the chapter UI OBJECT TYPE AND DESIGN OBJECT.

Open the class that we have created in the chapter UI OBJECT TYPE AND DESIGN OBJECTS. If you remember, we have assigned this class as a CALLBACK class to the newly created object type as below. It implements the interface IF_BSP_DLC_OBJ_TYPE_CALLBACK.

Go and place the code shown below and activate the method.

Based on the UI OBJECT TYPE, we simply adding two new sub objects. Save and activate the class. Now go to ui component and any view configuration tab. Click on new configuration . Give the UI object type in the object type field and press f4 in the sub object type field. now f4 gives three possible values. One is default and another two are the values that we have defined in the method.

So along with the UI object type, we can define two new configurations using SUBOBJECT1 and SUBOBJECT2. I just made one new configuration with UI OBJECT TYPE and SUBOBJECT1.

If I want to load this configuration, I need to code as shown below in the do config determination as discussed in the chapter DO CONFIG DETERMINATION.

When I test the application. I got below output as per the new configuration. I can also create one more new configuration with UI OBJECT TYPE ZOBJECT _TUT and sub object type SUBOBJECT2.


Configuration of view is very important task. It provides multiple options like changing labels,fields properties like display, input field and removing unwanted fields from display sectionetc. For every standard component SAP provides default configuration. If we dont want that configuration, we should make our new configurations. We should not do any change in the standard configuration. We can always copy the existing configuration and do the changes or can create whole new configuration. Go to the any view configuration and click on choose configuration button. It will bring all available configuration list of particular view.

Here it is showing two configurations. There are two columns named STD Con. And Cus Conf. the value X tells you which configuration it is. If X is there under STD conf, then it is only standard configuration else it is configuration done by customer. In above example, both are customer configurations (This is not a sap standard component. ). If you see both X marks under both columns, it means that customer has changed sap standard configuration. However, we should not do that. Whenever, we try to create a new configuration, framework will throw one dialog box.

Role configuration key: Every business role has one unique role configuration key. So we can make configuration of a view dependable on any business role with the help of the role configuration key. So while making a configuration, we can specify a role configuration key . A user who uses the business role with role configuration key will be presented the same configuration that we made above. ex: A user U1 has business role B1 with role configuration key RK1. we created a new configuration CG1 for any view using role configuration key RK1. Then CG1 will be loaded for that view automatically by the framework. OBJECT TYPE: SAP has introduced this UI object type to make UI changes independent of BOL. It sits between UI and BOL in the design layer. We already discussed it. OBJECT SUB TYPE: This is sub object and in order to create it we use call back classes. For example: we can create three sub objects INDIVIDUAL, ORGANIZATION and GROUP as sub objects to the business partner(account ) object to make three different configurations. So we will make three different configurations using above three sub objects. If user wants to create INDIVIDUAL account, then we use the configuration created with sub object INDIVIDUAL. If he wants to

create ORGANIZATION, then we will present the configuration with sub object ORGANIZATION to the user. here configuration created with Individual sub object may have fields like first name last name ..etc and the configuration created with the sub object ORGANIZATION may have fields like organization name...etc. COMPONENT USAGE: It is very known fact that we re use one view in different components. When we do so, we create component usages in the parent components(the component in which we are using view of different component). For ex: Let us say a view V2 has been reused in the two components C2 and C3 with corresponding usages CU1 and CU2. If we want, field F1 of this view V2 should be not visible when view V2 reused in C2 and same field F1 should be visible when reused in C3. Assumption is that field is already there on the view V2. So we need not to do anything regarding component C3. So we create one new configuration with CU1 as component usage by removing the field from view V2. So when reused view V2 in C2, based on the component usage name, framework will load correct configuration by not showing the field F1.


Let us learn how to reuse a view of different component as pop up. Before reading this chapter, kindly read the following chapters what it takes to reuse a view Reusing a view of another component. In this example, I am going to provide a f4 help to the product field in the ITEMLIST assignment block that we created in the previous chapters.

I am going to reuse the view set Search Help in the component PRD01QR. This view set has two views one is search and another one is result. So if reuse this view set, I will able to present two views together to the user. So he can search the products and select the results. Step1. First rule to reuse any view is to make a component usage. So here I am reusing the view from the component PRD01QR. Create one component usage in the target component in which you want to reuse a view.

In the Interface view field, I selected the option SearchHelpWindow as interface view. Because the viewset SearchHelp which I want to reuse is assigned to the window SearchHelpWindow and this window is exposed as interface view. You can see the below screen shot of run time repository of component PRD01QR.

You can see there are three entries under component interface node, thats why I got three entries in field interface view while creating component usage. Save the entries. Just press on continue if there is any another pop up. Step2: We need to generate the V getter method for the required field to give a value help. Here field is ORDERED_PROD. Go to the view and to context node under which attribute is located. Right click on the attribute and choose the option generate V-GETTER. Once method is generated , write the following code inside method.

Here OP_SAERCHPRODUCTS is the outbound plug. Create one variable with GV_INDEX with type INT4 in the context node class of attribute for which we are providing this help.

Step3: We need to create one outbound plug with the same name as above mentioned in the code. go to the view and create one outbound plug. Just give the name as SEARCHPRODUCTS. Prefix OP will be automatically added by the framework.

Before going to code in this method, we need to change its visibility to public. Framework automatically creates outbound plugs in the super class with protected visibility so that we can redefine according to our requirements in the subclasses. However for our requirement, we need to change its visibility. As we know that we cannot change the visibility of a inherited method in the subclass. We need to go the super class. Go to the view implementation class first, go to the properties tab. Double click on the super class.

Change into edit mode and open the methods tab. Change the visibility from protected to public for the created outbound plug. Save and activate the class.

We are not over. We need to change the visibility of this method in the subclass as well. Go back to the view implementation class. Change into edit mode and click on button SOURCE code based as shown below.

It will list the class code. Move the code methods OP_SEARCHPRODUCTS redefinition from protected section to the public section as below. Now Let us code in the method. Write the following code inside the method.

Now activate the class. While activating choose all entries in the list. Now you can see the visibility of this method as public in the view implementation class.

Here PRODUCT_POPUP is a public attribute of view implementation class.

Here we are using the method create popup of attributeWINDOW_MANAGER of component controller. The values which we are sending are the values that we used while creating component usage. Next we are calling the method SET ON CLOSE EVENT of popup to set the event handler when popup is closed. So this event handler will be triggered when pop up is closed. The next statement is optional; we use this method if we want to display any messages on the pop up. Generally messages wont be shown up on the pop up unless we use the set display mode method. The last statement, as the method name suggested, will open the pop up. At this step, pop up is ready. As soon as user presses the F4 button on the field, first outbound plug will be triggered and the above code will be executed and pop up will be created. On the pop up, user will be presented two screens to search the product and to see the results. Then user will choose any product. Once he chooses, control automatically goes the event handler that we set using the method SET ON CLOSE EVENT. So we need to get the product that user selected on the pop up , in this event handler. Step4: We need to create the event handler with the above mentioned name and need to code in that event handler. Go to the view and create one event handler with the name PRODUCT.

Write the following code inside the event handler.

We need to know some points above this code. LR_CONTEXT_NODE = PRODUCT_POPUP->GET_CONTEXT_NODE ( IV_CNODE_NAME = 'PRD' ). What is PRD here? It is context node in the component PRD01QR at component controller level. This has been exposed in the runtime repository. Only these types of context nodes are accessible outside of component. We are accessing this context node using the GET_CONTEXT_NODE method PRODUCT_POPUP. But from where data is coming to the context node PRD in that component? As we know, once user searched the products, he will choose one product from the result list. As soon as he selects the product, there is one event handler EH_ONCHOOSE triggered in the result view of product component.

The code above will take user selected record from result list and feed to the context node PRD of component controller. You can see the last method call outbound plug RETURNRESULT in above event handler. This call closes the popup window. This is the outbound plug we have checked in the event handler EHONPRODUCT. Remaining code is a bit straight forward in the event handler EHONPRODUCT; we are reading the product guid from selected record on the pop up. Next we need to set this on item view. In order to know for which record we need to set the value, we are reading the item record using find method by sending the index as GV_INDEX. Gv_index helps to find that record. That is why we have set this variable in the V-getter method of that field to the index of the record on which user has pressed f4. Test the application.


Let us display a Custom table on web ui using value node concept. In the starting chapters, we just told what a value node is. A Value node is nothing but a context node which is not based on any BOL object. It is based on the data elements or fields that come from the DDIC. It is very common requirement in SAP CRM WEB UI to display data of a custom table. Let us develop a table view that displays data of any custom table. I am not going to discuss table creation or records creation in the table. I assume that readers know how to create table in SE11 and insert records into it. I have created below table in se11 and records in it. I am going to create one table view which is based on this table.

Data of that table.

Go to any UI component and right click on view and choose the option create.

Give any suitable name to the view. We dont want to create a model node here skip that step. Next come to the step VALUE NODE. Give any suitable name to the value node.

Skip the next step Add model attributes and come to the step add value attributes. Click on the + symbol in this step.

It will bring one new dialog box.

Enter the table name in the field DDIC structure and press enter. All fields of table will be available in the list. Then select all rows by clicking on the select all button as shown in the above screen shot. Click on Continue. Then skip the next step and come to the step SELECT VIEW TYPE. Select the view type as TABLE VIEW as we want show all records from the database and choose the option configurable. As already discussed for any table view, we need to specify the context node. Give the context node that we created in the previous steps.

Complete the wizard. We have created the view based on value node. Then our duty is to fetch the required data and display that data on the view. Here I am going to code in the DO PREPARE OUTPUT method. This method will be called every time when view is displayed. Here our purpose is to show the data on the view so we have chosen this method. 1. Before coding, complete below two steps. Go to the view configuration tab and create one new configuration by moving fields to displayable section as I did below,

You can change the column titles if you want. 1. Assign this view to the window in the run time repository to make visible on the web ui. Refer the chapter Assigning view to window Now go to the view structure and expand the node request processing. Redefine the method DO PREPARE OUTPUT.

Once you redefine it. Icon will turn into green color. Double click on it and write the following code.

What we have done in the code. First we queried the table and fetched the data. Next we created on collection object to hold the records.

Then we are looping to visit each record in the internal table. For each record we create one value node with the same structure of the table. Technically a value node will be represented by the class CL BSP WD VALUE NODE. So we are creating object of this class by sending the structure of table as a base. One node is created we set the data using the method SET PROPERTIES. Then each value node is added to the collection. We repeated same process for all entries in the internal table and finally we set this collection to the required context node to make this data visible on web ui. Test the application.


When we open any service contract, we can see these one click actions in the item assignment block. These actions help us to edit some important fields of line item there itself in the table view. We need to not navigate to item overview page to edit it and also we can delete that item on the same assignment block. Let us provide one click action for a table view. Here I am going to add OCAs to the table view that I created in the chapter VALUE NODE CONCEPT. However procedure that we follow applies to any table view. Step1. We need to add one value attribute with name THTMLB_OCA with type CRM_THTMLB_ONE_CLICK_ACTION to the context node of table view. Go to the table view context node for which you want to implement ONE CLICK ACTIONS. Add a value attribute as mentioned above. Kindly see the below screen shots for reference.

Complete the wizard. We have created the attribute. Step2. Move the newly created attribute to the displayed fields section on the view configuration tab.

Step3. Go to the context node class of table and redefine the method GET_OCA_T_TABLE.

Write the following code inside that method and activate the method. In this method we have added buttons.

Step4. We need to tell the framework about newly created value attribute is an OCA type. For that we need to code in the P getter method of new attribute. If P-getter is greyed out, then just double click on. Framework will ask to create it. Then choose yes. Then write the following code inside the method.

Here _oca is the event handler name that will be triggered when we click on edit or cancel buttons. Step5.

Create on event handler with name _oca. (event handler name is case sensitive ).

Here for two buttons only one event handler is assigned. So whether you click on EDIT button or DELETE button, same event handler will be triggered. So we need to know on which button user has clicked to process our logic. Write the following code inside the event handler and activate it.

We are getting the ID of buttons on which user has clicked. Based on the button id, We need to process our own logic. Test the application by placing a break point in the above event handler.

Click on any button. I clicked on DELETE button


It is very common requirement to perform a search with the attribute that does not existing in the bp search structure. For Ex: User wants to find out all business partners whose death date is current date. (Sorry for taking death date as an example . As we know that death date is a field that exists in BUT000 and assumes that it is not available in selection criteria. Let us provide search functionality with this new field. Step1. Which dynamic query object is used to implement the BP SEARCH? Ans : Dynamic Query Object BuilHeaderAdvancedSearch.

What is the base structure of this query object? Ans: Attribute Structure CRMT_BUPA_IL_HEADER_SEARCH.

So we need to append our new field to this structure in se11 transaction. Go to the transaction SE11 and append new field to the above structure.

Save and activate the structure. This makes the newly added field available in the UI configuration in the component BP_HEAD_SEARCH. Go to this component and view MAINSEARCH configuration and move the new field from available search criteria to the selected search criteria.

Now we can go to the search page on the WEB UI and we can see the newly added field over there.

Next we need to create one new implementation for the BADI BADI_CRM_BUPA_IL_SEARCH_EXT under enhancement spot CRM_BUPA_IL_SEARCH. Go to the transaction se18 and give the above enhancement spot name in the enhancement spot field and click on display.

Next right click on the BADI BADI_CRM_BUPA_IL_SEARCH_EXT and choose the option CREATE BADI implementation.

It will show already existing enhancement implementations in the next dialog box. Choose create option.

Give suitable name and description and leave the last field as blank.

Once you choose continue, there will be one more dialog box. Here we need give suitable name , description and class name to create BADI implementation. Once you choose continue, then following new implementation will be displayed as below.

Choose Default implementation check box and Implementation is activate. Expand the new implementation and double click on implementing class. It will list class methods along with the details.

Double click on each method and if you receive a message as shown below. Choose Yes.

Once method implementation is created, activate that method. We can see the method IF_EX_CRM_BUPA_IL_SEARCH_EXT~SEARCH_CRITERIA_INITIAL. In this method we need to check whether user has filled the newly added field on web ui with any value before he triggers the search. If user filled it with some value, then we will send one parameter as a TRUE. Based on this value, framework will trigger the next method IF_EX_CRM_BUPA_IL_SEARCH_EXT~SEARCH_PARTNERS , in which we need to code so that we will get only results which satisfy the criteria with newly added field values. Double click the IF_EX_CRM_BUPA_IL_SEARCH_EXT~SEARCH_CRITERIA_INITIAL and add the following code and activate the method.

I am just checking ZDEATHDATE field is filled or not. If it is filled , then I am setting the parameter CV_IS_NOT_INITIAL as TRUE. Next double click the method IF_EX_CRM_BUPA_IL_SEARCH_EXT~SEARCH_PARTNERS and add the following code to it and activate the method.

Here there are two cases. First, user might trigger the search with only new field as selection criteria. In this scenario, no partners will be there in the CT_PARTNER_KEYS. So we just need to return the partner list based on the value in the new field. In this case we need query the table BUT000 based on the DEATH DATE value. Second, user might trigger search with different fields along with the new field as search criteria. Ex: list all bps with role as PROSPECT and death date as 20.03.2013. In above situation, when control reaches, CT_PARTNER_KEYS will have records of those BPS whose role is PROSPECT. Then we need to select only that Bps, whose death date is 20.03.2013. That is what we have coded, when CT_PARTNER_KEYS is not initial. In both cases, if sy-subrc is not initial, we are raising the exception of method NO_PARTNER_FOUND. Next, we have to define the filter value for this BADI implementation. Double click on the Filter Val. Then double click on the COMBINATION and enter the value of the advance search object.

Now activate the whole implementation.

Now you can check the BP search by giving some value to the new field DEATH DATE. Then SEARCH PARTNERS method will return the results accordingly. This is very simple implementation. You can include IV_MAX_HIT in the code to control the maximum number ofresults.


It is very important to know how to enhance a component. It is rare to create a new UI component. Most of the times, we need to change the existing SAP standard component according to our adjustment. So we need enhance the existing components to tailor it as we wanted. This is very important feature of any software. Because it is impossible to create a software to cover all business scenarios. When we enhancement a component, we will create one new bsp application in the customer name space, which reuses the standard application. Whatever the changes we do, are part of this new bsp application and sap standard component is untouched. Later if we want to delete the enhancement, the new bsp application will be deleted without creating any problem to standard component. Sap has provided a container to store all changes to a component while enhancing. This container is called enhancement set. There may be more than one enhancement set available in the system. However, only one enhancement set should be active during runt time. So if we do any change to a UI component under one enhancement set, same changes reflected at runtime when we load same component under same enhancement set.

Pressing F2 button on any field in the web ui will show a popup in which we can about active enhancement set in the system.

Let us enhance one standard component. Go to the transaction BSP_WD_CMPWB and choose the component that you want to enhance.

The highlighted button (1) is used to toggle enhancement set field. If you click it, enhancement field will be hidden and you can display the sap component as it is. If enhancement set field is visible, then you should specify an existing enhancement set to display the component. Let us create the enhancement set. Click on the create button and give required details in the next dialog box.

Enhancement set is created and will be displayed in the enhancement set field.

Now click on display button. We will receive below message at bottom of the screen if that particular component has not been enhanced under the provided enhancement set.

Click on the enhance component button.

First it will ask for an enhancement set. Give the enhancement set that we created in the above step.

Choose continue, then it will ask for new bsp application. Generally we give same component name with prefix Z. (we can choose any suitable name here).

If application does not exist in the system, it will ask to create it or not. Choose yes. In the next step, it will ask for Repository.xml page, just continue

After this step, if there is any application exists with the same name you have given, system will ask you to overwrite it. Dont choose yes in these situations if you are not sure. Somebody might be created it under any other enhancement set. Choose no and it will take you back to the previous dialog box, just cancel it. Again click on enhance component and give new application name and continue.

Once every step is completed save the entries. We have successfully enhanced the component. If a component is enhanced and if we open that component under same enhancement set, you can see a button at top delete enhancement . This means that component has been enhanced. Now we can see the same button in our case.

We just enhanced the component. In order to change any view or window and even component controller, we need to enhance them as well. Generally if open a component under any enhancement set, all non-enhanced parts are greyed out. If you right click on them, you can see an option Enhance.

Let us enhance the view as well. Right click on it and choose the option Enhance. System will automatically create new Z classes for view and context. If these classes already exist in the system, then it will ask user to choose correct name for classes. Here in my case, it asking to change the view implementation class as it already there in the system.

Just change the name if the dialog box appears and continue. I just added 1 to the name and saved the entries. Now I could see new generated classes for view and context.

Here observe the class highlighted with red color. Still it is showing the standard class not z class. When we enhance only view and context classes will be enhanced not the context nodes. If we want to change the any context node, then we need to enhance them separately. Right click any context node and enhance it.

Once we enhanced, the view name is in black color before it was greyed out. Observe the difference. Once enhanced, customer can carry on according to his requirements. HOW MAKE USE OF NEWLY CREATED ENHANCEMENT SET IN RUN TIME? Yes, we have created enhancement set and we enhanced our UI component under it. Now we need to do something to open the same component under our set on web ui. For this there is one special BADI COMPONENT_LOADING. We need to create one new implementation for this BADI and code inside the method IF_BSP_WD_CMP_LOADING_BADI~GET_ACTIVE_ENHANCEMENT_SET. Sample code look like below.

Whatever the enhancement set mentioned in above method , will be the active enhancement set.

TREE VIEW is used to represent hierarchical form of data. Ex: organizational data in SAP CRM can be represented as tree view. In WEB UI terminology, there is no special view type for tree view as we have form view and table view. We can consider tree view is a special form of table view. There is no wizard available to create a tree view. We need to adapt existing view into table view by following certain manual steps.

At first, it looks difficult, but the more number of times you do it, the more you understand it. In this chapter, I am going to create a tree view that looks like below.

As you see, it has two levels. First level will show the lead ID and next level will show its customer. I took this example for simplicity. In order to follow this tutorial, we need to create one table view. I am not going to describe steps to create a table view as we had already covered it in the previous lessons. In this chapter, I created one table view with base entity BTQRLeadDoc. I created one context node with same type at component controller and I coded in the component controllers method DO_INIT_CONTEXT to fetch the data. Then I did component binding between the table view context node and the context node of component controller. So data have been fetched in to our table view. Below is the code that I wrote in the DO INIT CONTEXT method of component controller.

What I did? I simply fetched first 10 lead records and feeding the context node LEAD with those records. As I did data binding between table view and context node of component controller, data will flow to the table view as well.

So we are all set and lets begin the main part. First, go to the table view context node implementation class and change its super class from CL_BSP_WD_CONTEXT_NODE_TV to CL_BSP_WD_CONTEXT_NODE_TREE. If there is any dialog box asking to redefinitions of certain methods, choose yes.

This class provides two important methods GET_TABLE_LINE_SAMPLE and REFRESH. First method will return one structure based on which columns of view are decided. REFRESH method is generally used to generate the first level of nodes or root nodes.

Here I am using just two columns to display information. So go to GET_TABLE_LINE_SAMPLE and add two columns as required.

Once this method is activated. Reopen the entire component using BSP_WD_CMPWB. Now you can see two columns in the view configuration tab. Move two columns from available section to displayable section and change the title accordingly and save the configuration. We will come to REFRESH method later. Now one important step is change the tag in .htm page. All tree views use the chtmlb: configTreeto display the tree view. Go to the .htm page and remove the existing CONFIGCELLERATOR or CONFIGTABLE tags and place the following tag and activate it.

Lead in above tag is a context node. Property nodeTextColumn is used to choose which attribute will act as root of tree or fist column of tree. Here I chose ID column according to my requirement. For node table property, we will send LEAD->NODE_TAB after filling it with required nodes. We specified event handlers collapse when we collapse a tree and expand when we expand the tree for properties OnCollapseNode and onExpandNode. Next, we need to create one class in SE24 with super class CL_BSP_WD_TREE_NODE_PROXY. This class offers one method called GET_CHILDREN. This method is used to create child nodes.

Before activating the class, just redefine the GET_CHILDREN method and activate it. Let us come back to the REFRESH method. Write the following code and activate it.

Here we are simply looping each record of context node i.e. lead record and creating one node for each record using the GET _PROXY method of NODE_FACTORY. Then we are adding the root node to tree using method ADD_ROOT_NODE. In my scenario, above loop will create 10 root nodes as I fetched 10 lead records. I am giving the class name we just created in se24 for proxy type. We are done creating root node but not displaying it. We need to manually add GETTER methods to proxy class to display any attribute on the tree. Go to the proxy class ZCL_TREE_PROXY_MAIN and copy the method IF_BSP_MODEL_SETTER_GETTER~_GET_XYZ and check the filter check box and paste it in the empty row. This process will copy all required import export parameters of the method. Then change the name to GET_ID. We just copied the GETTER method template and renamed it according to the attribute name.

Write the following code to get the ID of lead.

First level node is creation and display is done. Next we need to take care of child (here it is customer) node. In order to create second level node, we need to code in the get_children method first proxy class. We will use one more proxy class to create each child node. Go to SE24 and create one more class as we did above.

We need to display customer as well. Following the same procedure and add one getter method GET_PROSPECT and write the code as below.

Main point, we need to remember is, we created GETTER methods in the proxy classes; they are not part context node class. Display of child node is done. We did not create it. Now go to the first created proxy class ZCL_TREE_PROXY_MAIN and code in the get children method.

What I did? Here we need to use some BOL programming in order to fetch the customer of Lead. So I need to traverse through some relationships to reach the target entity BTPARTNER. Here I am reading all partners of Lead. Once I fetched all partners, I am looping over each partner and creating child node for it using the NODE FACTORY method and proxy class ZCL_TREE_PROXY_CUSTOMER we created above. Here once I created child node, I am setting the IS_LEAF property as TRUE because in my scenario CUSTOMER is the last level and after that I am not displaying any child to customer. So there wont be any arrow mark next to the folder icon for child nodes. Next create two event handlers with name collapse and expand in the view implementation class and write the following code.

As name suggests, these are triggered when you expand or collapse any node. Last thing is we need to add little bit coding in the DO PREPARE OUTPUT method to call REFRESH method.

Now you can execute the application and see the output. When we learn it first time, it seems too many steps, but in actually, it is not that much difficult. Here if I want to display address as child to customer, Then I need to create one more proxy cl ass and write the code in the GET CHILDREN method of CUSTOMER proxy class by using BOL relations from customer to address and need to add one GETTER method to that proxy class to display the address. Dont forget add one more column address in the GET_TABLE_LINE_SAMPLE. You can try it on your own. Hope it helps you and do refer this site to your colleagues if you think it deserves it.