Skip to Content
Technical Articles

Detailed Steps to create Tree View in SAP CRM Web UI

Introduction:

A Tree View is used to present Hierarchical view of information to users.

Sample Tree View:

This document will give a detailed step by step Procedure to create a Tree View in SAP CRM Web UI. Also, the complete codes of the methods are also given in detail to help anyone create Tree View in SAP CRM Web UI.

Please Note: The screenshots given in the blog post were taken from the Tree View built by me from scratch by using the steps below. The codes given in the blog post are codes in creation of the Tree View.

Steps to Create Tree View in SAP CRM Web UI:

  • Create Table view with the required fields
  • Change Super class of the Context Node to CL_BSP_WD_CONTEXT_NODE_TREE
  • Add coding in. htm page of the Table View.
  • Do the necessary configuration to add the fields from Available Fields to Displayed Fields.
  • Create the Overview Page and add the Result View to the Overview Page and do the necessary Configuration.
  • Go to the IMPL Class of the Table View and add coding in DO_INIT_CONTEXT method to populate the values for Tree View. The parent transaction id is mentioned in the field ZPARENT.
  • Create a new class as a copy of the Context Node class and Change the super class to CL_BSP_WD_TREE_NODE_PROXY. Redefine the method ‘IF_BSP_WD_TREE_NODE~GET_CHILDREN’, add attributes COLLECTION_WRAPPER, GR_TREE (Type Ref to ZL_ZTREE_TREEVIEW_CN00) and activate the class.
  • Modify Coding in the GET Method of the fields in the newly created class.
  • Add a global Internal table in the public section of the Context Node class.
  • Add attributes to the Context Node Created.
  • Redefine and add coding in REFRESH method of the Context Node class to build the Linkage between the two Custom Classes and add the values for the Tree Node into the global Internal Table.
  • Create a method GET_CONTEXT_NODE in the view controller class and add coding to get the Context Node details.
  • Create a method DO_ON_PREPARE_OUTPUT in the Context Node class and add coding to call the REFRESH and BUILD methods.
  • Create a method GET_PARENT_CHILD in the Context Node class and add coding to pass the global internal table details into a local variable in the class.
  • Add Coding in the method IF_BSP_WD_TREE_NODE~GET_CHILDREN to call the method GET_PARENT_CHILD to get the values for the Tree and create all the child nodes.
  • Call DO_ON_PREPARE_OUTPUT from DO_PREPARE_OUTPUT method.
  • Create Event Handlers for Expanding and Collapsing and add coding accordingly in the Event Handlers.

Now let us create the Tree View by following the above steps one by one.

  • Create Table view with the required fields

First create a structure with required fields for the Table View.

Now create a Table view with the above fields from TCode bsp_wd_cmpwb.

Complete the Wizard by clicking ‘Continue’ in each stage.

Click Continue and Complete the Wizard.Now the Component and Context node looks like below.

  • Change Super class of the Context Node to CL_BSP_WD_CONTEXT_NODE_TREE

Click on change Inheritance and change super class to CL_BSP_WD_CONTEXT_NODE_TREE.

  • Add coding in. htm page of the Table View.

Coding in .htm page is given below:

<%@page language="abap" %>
<%@extension name="thtmlb" prefix="thtmlb" %>
<%@extension name="chtmlb" prefix="chtmlb" %>
<%@extension name="bsp" prefix="bsp" %>
<chtmlb:configTree id                                 = "Tree"
                   actionsMaxInRow                    = "5"
                   ajaxDeltaHandling                  = "TRUE"
                   nodeTable                          = "<%= ZTREECN->node_tab %>"
                   onCollapseNode                     = "collapse"
                   onExpandNode                       = "expand"
                   onRowSelection                     = "select"
                   selectedRowIndex                   = "<%= ZTREECN->selected_index %>"
                   selectedRowIndexTable              = "<%= ZTREECN->SELECTION_TAB %>"
                   onClose                            = "closehierarchy"
                   selectionMode                      = "<%= ZTREECN->selection_mode %>"
                   scrollable                         = "TRUE"
                   type                               = "COLUMN"
                   table                              = "//ZTREECN/Table"
                   noFrame                            = "X"
                   personalizable                     = "TRUE"
 />

Now the Context Node changes to a Tree as per below screenshot:

  • Do the necessary configuration to add the fields from Available Fields to Displayed Fields.

  • Create the Overview Page and add the Result View to the Overview Page and do the necessary Configuration.

Now add the View to the Viewset.

Now add the Viewset to the Window.

Now do the Configuration in Overview Page.

  • Go to the IMPL Class of the Table View and add coding in DO_INIT_CONTEXT method to populate the values for Tree View. The parent transaction id is mentioned in the field ZPARENT.

Complete Code in DO_INIT_CONTEXT method is given below:

method DO_INIT_CONTEXT.
***********************************************************************************
*Description : In this method we add the values to be displayed in the Tree View.
*              We put the values into an Internal table and put the values
*              into the collection.
***********************************************************************************
DATA     :       lr_wrapper                  TYPE REF TO    cl_bsp_wd_collection_wrapper,
                 lv_struct_ref               TYPE REF TO    zst_tree,
                 lr_reltable_wrapper         TYPE REF TO    cl_bsp_wd_collection_wrapper,
                 lr_collection               TYPE REF TO    cl_crm_bol_entity_col,
                 lr_entity                   TYPE REF TO    if_bol_bo_property_access,
                 lv_value_node               TYPE REF TO    cl_bsp_wd_value_node.
DATA     :       itab_details                TYPE STANDARD TABLE OF ZST_TREE,
                 wa_details                  LIKE LINE OF itab_details,
                 lw_details                  LIKE LINE OF itab_details.
CONSTANTS:       lc_firstline_name           TYPE char20 VALUE 'Map Sequence',
                 lc_firstline_desc           TYPE char60 VALUE 'This is Desc. of the Name'.
* Calling the Super Class
  CALL METHOD SUPER->DO_INIT_CONTEXT.
*************************************************************
* In this section we assign the various values
*************************************************************
  wa_details-ZNAME              = 'ASIA'.
  wa_details-ZDESCRIPTION       = 'CONTINENT'.
  wa_details-Z_PARENT           = space.
* Inserting into the Internal table
  INSERT wa_details INTO TABLE itab_details.
  wa_details-ZNAME               = 'INDIA'.
  wa_details-ZDESCRIPTION        = 'COUNTRY'.
  wa_details-Z_PARENT            = 'CONTINENT'.
  INSERT wa_details INTO TABLE itab_details.
  wa_details-ZNAME               = 'TAMILNADU'.
  wa_details-ZDESCRIPTION        = 'STATE'.
  wa_details-Z_PARENT            = 'COUNTRY'.
  INSERT wa_details INTO TABLE itab_details.
******************************************************************************
* In this section we insert the text 'Map Sequence', 'This is Desc. of the Name' 
* as first row in the Tree View
******************************************************************************
  READ TABLE itab_details INTO lw_details WITH KEY z_parent = ' '.
* Check the value of sy-subrc
  IF sy-subrc EQ 0.
*   Clearing
    CLEAR lw_details-ZNAME.
    CLEAR lw_details-ZDESCRIPTION.
*   Assigning
    lw_details-ZNAME        = lc_firstline_name.
    lw_details-ZDESCRIPTION = lc_firstline_desc.
*   Inserting into the Internal table
    INSERT lw_details INTO itab_details INDEX 1.
  ENDIF.
*create collection
  CREATE OBJECT lr_collection TYPE cl_crm_bol_entity_col.
  CHECK lr_collection IS BOUND.
*Get collection wrapper
  lr_reltable_wrapper = me->typed_context->ztreecn->collection_wrapper.
  CHECK lr_reltable_wrapper IS BOUND.
 CLEAR lw_details.
******************************************************************************
* In this section we loop at the Internal table having various values for the
* Tree and set the values in the Collection.
******************************************************************************
 LOOP AT itab_details INTO lw_details.
* get the last entry of the value node
    lr_entity = lr_reltable_wrapper->get_last( ).
*   Check if the Entity is bound
    IF lr_entity IS BOUND.
*     Set the property of the fields present in value node
   lr_entity->set_property( iv_attr_name = 'ZNAME'        iv_value = lw_details-ZNAME ).
   lr_entity->set_property( iv_attr_name = 'ZDESCRIPTION' iv_value = lw_details-ZDESCRIPTION ).
   lr_entity->set_property( iv_attr_name = 'Z_PARENT'     iv_value = lw_details-Z_PARENT ).
*     Add the entity to the collection
      lr_collection->if_bol_bo_col~add( iv_entity = lr_entity ).
    ENDIF.
*   In below we add a blank line to the Collection
    CREATE DATA lv_struct_ref.
    CREATE OBJECT lv_value_node
      EXPORTING
        iv_data_ref = lv_struct_ref.
    me->typed_context->ztreecn->collection_wrapper->add( lv_value_node ).
  ENDLOOP.
* All the values are set into the collection
  me->typed_context->ztreecn->collection_wrapper->set_collection( lr_collection ).
  endmethod.
  • Create a new class as a copy of the Context Node class and Change the super class to CL_BSP_WD_TREE_NODE_PROXY.

Redefine the method ‘IF_BSP_WD_TREE_NODE~GET_CHILDREN’, add attributes COLLECTION_WRAPPER, GR_TREE (Type Ref to ZL_ZTREE_TREEVIEW_CN00) and activate the class.

 

  • Modify coding in the GET Methods of the fields in the newly created class.

 

  • Add a global Internal table in the public section of the Context Node class.

Click on  button.

Click on Yes in Popup and add coding as below:

  • Add attributes to the Context Node Class

  • Redefine and add coding in REFRESH method of the Context Node class to build the Linkage between the two Custom Classes and add the values for the Tree Node into the global Internal Table.

Complete Code in Refresh Method is given below:

method REFRESH.
***********************************************************************************
* In this method we build the Linkage between the two Custom Classes and 
* add the values of child for the Tree Node into the global Internal Table and 
* we insert the Root Node entity into the collection.
***********************************************************************************
  DATA: lv_entity                   TYPE  REF TO cl_bsp_wd_value_node,
        lr_coll_root                TYPE  REF TO cl_crm_bol_bo_col,
        lv_iterator                 TYPE  REF TO if_bol_bo_col_iterator,
        lr_par_entity               TYPE  REF TO cl_bsp_wd_value_node,
        lr_tree_node                TYPE  REF TO ZL_ZTREE_TREEVIEW_CN01,
        rv_result                   TYPE  REF TO if_bol_bo_property_access,
        lv_iterator_copy            TYPE  REF TO if_bol_bo_col_iterator,
        ls_parent_child_entity      TYPE  gty_par_ch_entity,
        lv_parent_id                TYPE  ZDE_PARENT.
* Super method
  CALL METHOD super->refresh.
  TRY.
*     Get the collection
      lv_iterator = me->collection_wrapper->get_iterator( ).
      IF lv_iterator IS BOUND.
        lv_entity ?= lv_iterator->get_first( ).
*       Get a copy of collection so that Original collection is not changed
        lv_iterator_copy = lv_iterator->get_copy( ).
      ENDIF.
****************************************************************************************
* In this section we check whether Parent is present. If Parent is initial then it
* indicates it is Root Node. At the end of the method we will add the Root Node to the 
* collection.
****************************************************************************************
      CREATE OBJECT lr_coll_root.
*     Checking if the entity is bound
      WHILE lv_entity IS BOUND.
*       Getting the value of the Parent
        CALL METHOD lv_entity->if_bol_bo_property_access~get_property_as_value
          EXPORTING
            iv_attr_name = 'Z_PARENT'
          IMPORTING
            ev_result    = lv_parent_id.
*       If Parent is Initial, it indicates Root Node
        IF lv_parent_id IS INITIAL.
*         Add the Root node to the entity
          lr_coll_root->if_bol_bo_col~add( lv_entity ).
          lr_tree_node ?        = me->node_factory->get_proxy(
                 iv_bo          = lv_entity
                 iv_proxy_type  = 'ZL_ZTREE_TREEVIEW_CN01' ).
          lr_tree_node->if_bsp_wd_tree_node~node_key = me->add_root_node( iv_node = lr_tree_node ).
*         Publish me (Tree ContextNode) to Tree Proxy
          lr_tree_node->gr_tree = me.
*         Make the Root Node as expanded for the first time
          IF gv_fir_time EQ abap_true.
            expand_node( lr_tree_node->if_bsp_wd_tree_node~node_key ).
          ENDIF.
        ELSE.
*********************************************************************************
* If Parent is present it indicates Child. We will add all the Child Node values 
* into a Global Internal table
*********************************************************************************
*           If Parent is present then it indicates it is Child Node
            CALL METHOD lv_iterator_copy->find_by_property
              EXPORTING
                iv_attr_name = 'ZDESCRIPTION'
                iv_value     = lv_parent_id
              RECEIVING
                rv_result    = rv_result.
*       Get the parent entity
          lr_par_entity ?= rv_result.
          ls_parent_child_entity-parent = lr_par_entity.
*        Child entity
          ls_parent_child_entity-child = lv_entity.
*        Insert into a table which stores all the child nodes
          INSERT ls_parent_child_entity INTO TABLE gt_par_ch_entity.
        ENDIF.
*      Get the next entity
        lv_entity ?= lv_iterator->get_next( ).
      ENDWHILE.
    CATCH cx_sy_move_cast_error cx_sy_ref_is_initial.
  ENDTRY.
* Set the collection for the root node 
  me->collection_wrapper->set_collection( lr_coll_root ).
endmethod.

Once Refresh method is activated, the linkage between the Custom Classes is established as per below screenshot.

  • Create a method GET_CONTEXT_NODE in the view controller class and add coding to get the Context Node details.

Code in GET_CONTEXT_NODE method is given below:

method GET_CONTEXT_NODE.
******************************************************************************
*  In this method we add code to get the Context Node details
******************************************************************************
  FIELD-SYMBOLS: <lr_cn> TYPE ANY.
  ASSIGN me->context->(iv_context_node_name) TO <lr_cn>.
  IF <lr_cn> IS ASSIGNED.
    rr_cn ?= <lr_cn>.
  ENDIF.
endmethod.
  • Create a method DO_ON_PREPARE_OUTPUT in the Context Node class and add coding to call the REFRESH and BUILD methods.

Code in DO_ON_PREPARE_OUTPUT method is given below:

method DO_ON_PREPARE_OUTPUT.             
***************************************************************
*  In this method we add code to call REFRESH and BUILD methods
***************************************************************
          refresh(  ).
          me->build_table(  ).
endmethod.    
  • Create a method GET_PAR_CHILD in the Context Node class and add coding to pass the global internal table details into a local variable in the class.

Code in GET_PAR_CHILD method is given below:

  method GET_PAR_CHILD.
*******************************************************************
* In this method , we add code to pass the Global Internal table
* into a Local Table in the class
*******************************************************************
    CLEAR rv_result[].
    rv_result[] = gt_par_ch_entity[].
  endmethod.
  • In the New Class created, add Coding in the method IF_BSP_WD_TREE_NODE~GET_CHILDREN to call the method GET_PARENT_CHILD to get the values for the Tree and create all the child nodes.

Complete code in method IF_BSP_WD_TREE_NODE~GET_CHILDREN is given below:

method IF_BSP_WD_TREE_NODE~GET_CHILDREN.
******************************************************************************************
*In this method we add Coding in the method IF_BSP_WD_TREE_NODE~GET_CHILDREN to call the 
*method GET_PARENT_CHILD to get the values for the Tree and create all the child nodes.
******************************************************************************************
DATA:  lr_entity                 TYPE REF TO cl_bsp_wd_value_node,
       lr_my_child_node          TYPE REF TO ZL_ZTREE_TREEVIEW_CN01.
DATA:  lt_par_ch                 TYPE ZL_ZTREE_TREEVIEW_CN00=>GTY_PAR_CH_ENTITY_TAB,
       ls_par_ch                 TYPE ZL_ZTREE_TREEVIEW_CN00=>GTY_PAR_CH_ENTITY.
       CHECK me->bo IS BOUND.   
       lr_entity ?= bo.
*      Checking if the entity is bound
       CHECK lr_entity IS BOUND.
       CHECK gr_tree IS BOUND.
*      Get the  values for the Tree Node
       lt_par_ch = gr_tree->get_par_child( ).
*      Loop at the Internal table having Parent and Child details
       LOOP AT lt_par_ch INTO ls_par_ch WHERE parent = lr_entity.
           lr_my_child_node ?= me->node_factory->get_proxy(
           iv_bo             = ls_par_ch-child
           iv_proxy_type     = 'ZL_ZTREE_TREEVIEW_CN01'
           iv_parent_proxy   = me ).
    	   lr_my_child_node->gr_tree = gr_tree.
    	   APPEND lr_my_child_node TO rt_children.
*          Expand the Child Node
           IF gr_tree->gv_fir_time EQ abap_true.
              lr_my_child_node->if_bsp_wd_tree_node~expand_node( ).
           ENDIF.
       ENDLOOP.
    endmethod.
  • Call DO_ON_PREPARE_OUTPUT from DO_PREPARE_OUTPUT method.

Complete Coding in DO_PREPARE_OUTPUT method is given below:

method DO_PREPARE_OUTPUT.
**********************************************************************
* In this method , we add coding to call REFRESH and BUILD methods to
* build the table by passing the Tree details
**********************************************************************
DATA: lr_cn_tree          TYPE REF TO ZL_ZTREE_TREEVIEW_CN00,
            lr_cn_items   TYPE REF TO cl_bsp_wd_context_node,
            lr_item       TYPE REF TO if_bol_bo_property_access,
            lr_wrapper    TYPE REF TO cl_bsp_wd_collection_wrapper.
*  Call the Super class
   CALL METHOD super->do_prepare_output
    EXPORTING
      iv_first_time = iv_first_time.
*  Get the Context Node details
   lr_cn_tree ?= get_context_node( 'ZTREECN' ).
   CHECK lr_cn_tree IS BOUND.
*  Pass the first time value
   lr_cn_tree->gv_fir_time = iv_first_time.
*  Get the Context Node details
   lr_cn_items = get_context_node( 'ZTREECN' ).
*  Get the first entity in the collection
   lr_item = lr_cn_items->collection_wrapper->get_first( ).
*  Call the REFRESH and BUILD methods via DO_ON_PREPARE_OUTPUT method
   lr_cn_tree->do_on_prepare_output( iv_first_time = iv_first_time
                                         ir_items      = lr_item ).
endmethod.
  • Create Event Handlers for Expanding and Collapsing and add coding accordingly in the Event Handlers.

Create two Event Handlers EH_ONEXPAND and EH_ONCOLLAPSE and add coding to expand and collapse the context nodes.

 

Code in Method EH_ONEXPAND is given below:

  method EH_ONEXPAND.
******************************************************************************
* This Event Handler is triggered when the Node is expanded
******************************************************************************
   DATA: lv_tree_event  TYPE REF TO cl_thtmlb_tree.
   lv_tree_event ?= htmlb_event_ex.
   typed_context->ZTREECN->expand_node( lv_tree_event->row_key ).
  endmethod.

Code in Method EH_ONCOLLAPSE is given below

method EH_ONCOLLAPSE.
******************************************************************************
* This Event Handler is triggered when the Node is collapsed
******************************************************************************
    DATA: lv_tree_event  TYPE REF TO cl_thtmlb_tree.
    lv_tree_event ?= htmlb_event_ex.
    typed_context->ZTREECN->collapse_node( lv_tree_event->row_key ).
  endmethod.

Now test the Tree View by executing the Component ZTREE.

On collapsing the node, the Tree View appears as below:

On expanding the node, the Tree View appears as below:

Conclusion:

By following the above steps you can build a Tree View in SAP CRM Web UI from scratch and present a Hierarchical view of information to Users.

                                                                     End of Document

2 Comments
You must be Logged on to comment or reply to a post.
  • Hi Subramanian,

    I would like to enhance a standard tree view with an additional column but cannot really find the proper way of doing this

    My example:

    In view ICCMP_INBOX/InboxItems I redefined method GET_TABLE_LINE_SAMPLE and added the additional column and now it shows up on the UI as a new column. However, I still need to find a way of populating a proper value for this.

     

    Thanks a lot and Regards,

    • Dear Swathi,

      As per my example in the blog , after the field has been added to the Configuration in the View , get values for the new field in DO_INIT_CONTEXT method and Modify code in GET method to display the new values.

      Hope this helps.

      Regards,