Skip to Content

At the end of Part 10a of this tutorial:

As James Carville said to Bill Clinton in 1992: “It’s the indices, stupid” (Part 10a of “Event-Driven” Tutorial on WDR_TEST_UI_ELEMENTS)
An Archaeological “Dig” into SAP Metadata (Part 9 of “Event-Driven” Tutorial on WD-ABAP Component WDR_TEST_UI_ELEMENTS)
When Presentation and Business Logic are Jumbled, Even Minor Housekeeping is Trickier Than It Should Be (Part 8 of Event-Driven Tutorial on WDR_TEST_UI_ELEMENTS)
Sieving Presentation from Business Logic When the Business Application Area is Software Development (Part 7 of “Event-Driven” Tutorial on SAP-Delivered WDABAP Component WDR_TEST_UI_ELEMENTS)
Apache Struts/M2 and SAP WebDynpro/MVC: Can these paradigms alone guarantee separation of business and presentation logic? (Part 6b of Tutorial on WDR_TEST_UI_ELEMENTS)
Part 6a of Event-Driven Tutorial on WDABAP Component WDR_TEST_UI_ELEMENTS
If you’ve written something in SAP from scratch, you (probably) haven’t bothered to understand what someone else has already done (Part 5 of “Event-Driven” Tutorial on WD-ABAP Component WDR_TEST_UI_ELEMENTS)
Part 4 of “Event-Driven” Tutorial on the WD-ABAP Component WDR_TEST_UI_ELEMENTS.
“Procedural” Recap of What’s Been Learned So Far in “Experiential” (“Event-Driven”) Tutorial on WD-ABAP component WDR_TEST_UI_ELEMENTS
The class infrastructure of WDR_UI_TEST_ELEMENTS is exquisite for lazy cloning and change-ups.
Experiential vs Procedural Tutorials: “Breaking” WDR_TEST_UI_ELEMENTS to Learn From It.

we had created the custom metadata table that we need to use in order to load the four trays of detail information we want to display when some node of a Logical Database is selected from the right hand tree view:

image

image

So we’re now ready to use these metadata to expand the four trays above like this:

image

And therefore, we start on this task by looking to see how the original SAP component WDR_TEST_UI_ELEMENTS expands the “Settings” tray it displays in the middle tray view – in paticular, how it does this using the

create_settings_tray

method of the proxy class

CL_WDR_ALL_IN_ONE_UIELEM.

Well, to make a long story short, it turns out that we can

try

to modify

create_settings_tray

to make it do what we want, but if we try this, we’re going to have to go very very deep into the SAP-delivered code and clone a whole bunch of infrastructure classes in order to be able to modify the one we really need to modify – the SAP-delivered class

/1WDA/LSTANDARD

.

Furthermore, as we’re considering this very unattractive option, it occurs to us that we’ve already added action-links to trays before – in the

init_view2

method of the class

ZCL_WDR_ALL_IN_ONE_UTIL

that we cloned from the SAP-delivered class

CL_WDR_ALL_IN_ONE_UTIL

. And in this method, we didn’t have to do anything near as complicated as the stuff that SAP is doing in

create_settings_tray

.

Equally importantly, it occurs to us that if we don’t need all the stuff in

create_settings_tray

, then maybe we don’t need all of the stuff in

create_settings

either – maybe this is all just stuff particular to the business logic which the original component has to use to display settings and events of UI elements. So, before we start the main task of adding links to trays using the code that SAP has in

init_view2

, we decide to take a closer look at

create_settings

to see what we really need from this component.

To make a long-story short again, it turns out that all we need from the

create_settings

component is the code that creates the very topmost node of the tree displayed the righthand treeview shown above. And since we can move this code to our new method

create_lgcldb_tree

, it turns out that we can do some simplifying housekeeping as follows.

Step 1

: Clean-up our modified

create

method.

In If you’ve written something in SAP from scratch, you (probably) haven’t bothered to understand what someone else has already done (Part 5 of “Event-Driven” Tutorial on WD-ABAP Component WDR_TEST_UI_ELEMENTS) of this tutorial, we modified the

create

method of

ZCL_WDR_ALL_IN_ONE_UIELEM

so that it invoked the method we had written to build the right-hand side tree view.  These modications are shown below in bolded italics:

method create.

  data:

    cur_id_variation type string.

  • get a new id variation component

  m_last_used_id_variation = m_last_used_id_variation + 1.

  m_cur_id_variation       = m_last_used_id_variation.

  • save some stuff

  m_library_name              = i_library_name.

  m_definition_name           = i_definition_name.

  m_parent_container          = i_parent_container.

  m_ui_element_group          = i_ui_element_group.

  m_ui_element_container      = i_ui_element_container.

  m_root_node                 = i_root_node.

  m_root_node_info            = i_root_node->get_node_info( ).

  m_root_node_path            = i_root_node->get_meta_path( withoutcontroller = abap_true ).

  m_view                      = i_ui_element_group->view.

  m_parent_view_element       = i_parent_view_element.

  m_parent_aggregation_name   = i_parent_aggregation_name.

  m_view_element              = i_view_element.

  m_hier_tree_context_node    = i_hier_tree_context_node.

  m_hier_tree_context_element = i_hier_tree_context_element.

  m_cur_level                 = i_cur_level.

  • create prefix for all generated nodes, view elements, etc.

  cur_id_variation = m_cur_id_variation.

  condense cur_id_variation.

  concatenate ‘C’ cur_id_variation ‘_’ into m_prefix.

  • create the different areas

  create_settings( ).

  create_events( ).

+* create_aggregations( ).

CASE m_library_name.
WHEN ‘LGCLDBS’.
create_lgcldb_tree( ).
WHEN OTHERS.
create_aggregations( ).
ENDCASE.+

  if m_hier_tree_context_element is bound and m_hier_tree_context_element = m_hier_tree_selected_element.

  •   create the two trays, if necessary

    create_settings_tray( ).

    create_events_tray( ).

  endif.

endmethod.

But as will be seen in a moment, it turns out that we only need one small snippet of code from

create_settings

and no code at all from

create_events

. Plus, since we’ve removed the original UI Element libraries from the list of libraries our cloned component can display in its initial left-hand side tray-view, we don’t need anything from

create_aggregations

either. And therefore, we can simplify our

create

method to:

method CREATE.

  data:

    cur_id_variation type string.

  • get a new id variation component

  m_last_used_id_variation = m_last_used_id_variation + 1.

  m_cur_id_variation       = m_last_used_id_variation.

  • save some stuff

  m_library_name              = i_library_name.

  m_definition_name           = i_definition_name.

  m_parent_container          = i_parent_container.

  m_ui_element_group          = i_ui_element_group.

  m_ui_element_container      = i_ui_element_container.

  m_root_node                 = i_root_node.

  m_root_node_info            = i_root_node->get_node_info( ).

  m_root_node_path            = i_root_node->get_meta_path( withoutcontroller = abap_true ).

  m_view                      = i_ui_element_group->view.

  m_parent_view_element       = i_parent_view_element.

  m_parent_aggregation_name   = i_parent_aggregation_name.

  m_view_element              = i_view_element.

  m_hier_tree_context_node    = i_hier_tree_context_node.

  m_hier_tree_context_element = i_hier_tree_context_element.

  m_cur_level                 = i_cur_level.

  • create prefix for all generated nodes, view elements, etc.

  cur_id_variation = m_cur_id_variation.

  condense cur_id_variation.

  concatenate ‘C’ cur_id_variation ‘_’ into m_prefix.

    • create the different areas

  CASE m_library_name.

    WHEN ‘LGCLDBS’.

      create_lgcldb_tree( ).

  • later, we’ll add methods to build trees for the

  • action links in our other two kinds of metadata

  • libraries (“Programming Trees” and “Report Sets”)

    WHEN OTHERS.

  ENDCASE.

endmethod.

Step 2

: Take what we need from

create_settings

and put it in

create_lgcldb_trees

As noted above, all we need from

create_settings

is the little snippet of code which creates the topmost root node of the tree to be displayed in the right-hand side tree view (e.g. the node “Vendor Database” in the illustration above.) So we take this code and place it in our

create_lgcldb_tree

method as follows (see boldfaced and italicized code):

method CREATE_LGCLDB_TREE.

data:
id type string,
label_for_id type string,
lr_tray type ref to cl_wd_tray,
text type string,
lr_new_view_elem_helper type ref to zcl_wdr_all_in_one_uielem, ” Part 5 try 2 20060908
lr_new_view_element type ref to cl_wdr_view_element,
class_name type string,
method_name type string,
lt_method_params type abap_parmbind_tab,
method_param like line of lt_method_params,
lt_aggregatees type wdy_ui_elem_def_table,
lt_zldbn type tt_zldbn, ” Part 5 try 2 20060908
v_hasch type abap_bool, ” Part 5 try 2 20060908
lr_label type ref to cl_wd_label,
lr_text_view type ref to cl_wd_text_view,
lr_matrix_head_data type ref to cl_wd_matrix_head_data,
lr_matrix_data type ref to cl_wd_matrix_data,
lr_aggregation_node_info type ref to if_wd_context_node_info,
lr_aggregation_node type ref to if_wd_context_node,
lr_context_element type ref to if_wd_context_element,
path type string,
texts_path type string,
node_name type string,
lr_dropdown type ref to cl_wd_dropdown_by_idx,
index type i,
aggregation_allowed type abap_bool,
lr_container type ref to cl_wd_uielement_container,
lr_child type ref to cl_wd_uielement,
lr_rtti type ref to cl_abap_datadescr,
lr_data type ref to data,
is_container type abap_bool,
lr_object type ref to object,
repeat type i,
+

          • begin add-in of code 9/25/2006

    lr_ui_element_group_header type ref to cl_wd_caption,

    display_name_txt           type string.

          • end add-in of code 9/25/2006

+       like line of mt_zldbn.                                  ” Part 5 try 2 20060908

                                  • ” Part 5 try 2 20060908 (declarations from create_aggregatee. except what’s been declared above)

data:

    initial_path                 type string,

    lr_hier_tree_context_node    type ref to if_wd_context_node,

    lr_hier_tree_context_element type ref to if_wd_context_element,

    lr_save_tree_context_element type ref to if_wd_context_element,        ” Part 5 try 2 20060908

    icon                         type string.

  • get the data of the current view element

  read table mt_ui_elem_def_all

       with key library_name    = m_library_name

                definition_name = m_definition_name

       assigning  0.

  •   big problem…

    message x000(00).

  endif.

+

          • begin add-in of code 9/25/2006

  • create a context node where all the settings of the current UI element are stored

  concatenate m_prefix mc_settings_id into m_settings_node_id.

  m_settings_node_info = create_settings_node(

                           i_node_name        = m_settings_node_id

                           i_parent_node_info = m_root_node_info

                           i_is_mandatory     = abap_true ).

  m_settings_node = m_root_node->get_child_node( m_settings_node_id ).

  • create a data node where all multi node settings are stored, like for all view elements

  • that have a data source or attributes with type multiNodeAttribute

  concatenate m_prefix mc_data_id into m_data_node_id.

  m_data_node_info = create_data_node( i_parent_node_info = m_root_node_info ).

  m_data_node_path = m_data_node->get_meta_path( withoutcontroller = abap_true ).

          • end add-in of code 9/25/2006

m_hier_tree_context_element = m_hier_tree_context_node->create_element( ).

  m_hier_tree_context_node->bind_element( new_item = m_hier_tree_context_element set_initial_elements = abap_false ).

  m_hier_tree_context_element->set_attribute( name = ‘EXPANDED’     value = abap_true ).

  m_hier_tree_context_element->set_attribute( name = ‘HAS_CHILDREN’ value = abap_true ).

  m_hier_tree_context_element->set_attribute( name = ‘TEXT’         value = .

**************************************************

  • this is from original create_aggregations

    concatenate m_prefix mc_aggr_explaination_id bind_element( new_item = lr_context_element set_initial_elements = abap_false ).

**************************************************

**************************************************

  • this is from original create_aggregatee

    lr_hier_tree_context_node = m_hier_tree_context_element->get_child_node( ‘UI_ELEMENT_HIER_REC’ ).

    lr_hier_tree_context_element = lr_hier_tree_context_node->create_element( ).

    lr_hier_tree_context_node->bind_element( new_item = lr_hier_tree_context_element set_initial_elements = abap_false ).

    IF set_attribute( name = ‘ICON’         value = icon ).

*************************************************

**************************************************

  • this is from original create_aggregations

  • set the lead selection of the aggregation node to the currently aggregated view element

    index = sy-tabix.

    lr_aggregation_node->set_lead_selection_index( index ).

**************************************************

    lr_hier_tree_context_element->get_attribute( EXPORTING name = ‘HAS_CHILDREN’ IMPORTING value = v_hasch ).

    IF v_hasch = abap_true.

      lr_save_tree_context_element = m_hier_tree_context_element.

      m_hier_tree_context_element = lr_hier_tree_context_element.

      create_lgcldb_nodes( ).

      m_hier_tree_context_element =  lr_save_tree_context_element.

    ENDIF.

  endloop.

And once having done these two bits of clean-up, we can now return to the task of expanding our middle trays without needing any code from

create_settings

,

create_settings_node

, or

create_settings_tray

.

In particular, to expand our middle level trays as shown above, we modify the method

on_select_view_element

of

ZCL_WDR_ALL_IN_ONE_UIELEM

so that it invokes a new method

fill_lgcldbs_trays

and then steal the SAP code from the

init_view2

method of

CL_WDR_ALL_IN_ONE_UTIL

to put in this new method.

The modified

on_select_view_element

method winds up looking just like it did at the end of An Archaeological “Dig” into SAP Metadata (Part 9 of “Event-Driven” Tutorial on WD-ABAP Component WDR_TEST_UI_ELEMENTS), except that it now invokes the new

fill_lgcldbs_trays

method (see boldfaced and italicized code below):

method ON_SELECT_VIEW_ELEMENT.

data:
lr_view_elem_helper like line of mt_aggregated_view_elements,
lr_container type ref to cl_wd_uielement_container,
lt_children type CL_WD_uielement=>tt_uielement,
lr_child like line of lt_children,
id type string,
text type string,

v_ldbnode(30) type c,

idf type string,
idw type string,
idu type string,
idx type string,

v_cnt type i.

i_hier_tree_selected_element->get_attribute( EXPORTING name = ‘TEXT’ IMPORTING value = v_ldbnode ).

  •   remove the old trays

    lt_children = m_parent_container->get_children( ).

    loop at lt_children into lr_child.

  •      if lr_child->id cs mc_settings_id or lr_child->id cs mc_events_id.

      if   lr_child->id cs mc_where_id

        or lr_child->id cs mc_ftchd_id

        or lr_child->id cs mc_used_id

        or lr_child->id cs mc_index_id.

        m_parent_container->remove_child( id = lr_child->id ).

      endif.

    endloop.

    clear m_where_tray.

    clear m_fetched_tray.

    clear m_used_tray.

    clear m_index_tray.

  • save the selected context element of the hierarchy tree

  m_hier_tree_selected_element = i_hier_tree_selected_element.

  CASE m_library_name.

    WHEN ‘LGCLDBS’.

      concatenate m_prefix mc_where_id into idw.

      concatenate m_prefix mc_ftchd_id into idf.

      concatenate m_prefix mc_used_id  into idu.

      concatenate m_prefix mc_index_id into idx.

      SELECT count( * )

        FROM zwdy_ui_elem_def

        INTO v_cnt

       WHERE display_name = v_ldbnode.

      IF v_cnt = 0.

        concatenate text-017 ` ` v_ldbnode into text.

      ELSE.

        text = text-018.

      ENDIF.

      m_where_tray = add_tray_to_container(

                     i_id               = idw

                     i_parent_container = m_parent_container

                     i_header_text      = text ).

      IF v_cnt = 0.

        concatenate text-019 ` ` v_ldbnode into text.

        m_fetched_tray = add_tray_to_container(

                         i_id               = idf

                         i_parent_container = m_parent_container

                         i_header_text      = text ).

        text = text-020.

        m_used_tray = add_tray_to_container(

                        i_id               = idu

                        i_parent_container = m_parent_container

                        i_header_text      = text ).

        concatenate text-021 ` ` v_ldbnode into text.

        m_index_tray = add_tray_to_container(

                        i_id               = idx

                        i_parent_container = m_parent_container

                        i_header_text      = text ).

get_attribute( EXPORTING name = ‘TEXT’ IMPORTING value = v_ldbnode ).

  • fill the where tray

  CLEAR mt_zldbm.

  SELECT *

    FROM zldbm

    INTO

   TABLE mt_zldbm

   WHERE ldbname  = m_definition_name

     AND nodename = v_ldbnode

     AND ( infotype = ‘WE’ OR infotype = ‘WV’ )

   ORDER

      BY infotype colname.

  IF sy-subrc = 0.

    LOOP AT mt_zldbm ASSIGNING -colname ‘:’  coltext INTO display_txt.

  •     create a linktoaction for the current view element inside of the current tray

      lr_link_to_action = cl_wd_link_to_action=>new_link_to_action(

                            id        = id_txt

                            on_action = ‘DISPLAY_COL_DETAIL’

                            text      = display_txt

                            view      = m_view ).

  •     create the grid layout data for the link to action

      lr_matrix_head_data = cl_wd_matrix_head_data=>new_matrix_head_data( lr_link_to_action ).

  •     assign the layout data to the link to action

      lr_link_to_action->set_layout_data( lr_matrix_head_data ).

  •     add the link to action to the current tray

      m_where_tray->add_child( lr_link_to_action ).

    ENDLOOP.

  ENDIF.

  • fill the select tray

  CLEAR mt_zldbm.

  SELECT *

    FROM zldbm

    INTO

   TABLE mt_zldbm

   WHERE ldbname  = m_definition_name

     AND nodename = v_ldbnode

     AND ( infotype = ‘SE’ or infotype = ‘SV’ )

   ORDER

      BY infotype colname.

  IF sy-subrc = 0.

    LOOP AT mt_zldbm ASSIGNING -colname ‘:’  coltext INTO display_txt.

  •     create a linktoaction for the current view element inside of the current tray

      lr_link_to_action = cl_wd_link_to_action=>new_link_to_action(

                            id        = id_txt

                            on_action = ‘DISPLAY_COL_DETAIL’

                            text      = display_txt

                            view      = m_view ).

  •     create the grid layout data for the link to action

      lr_matrix_head_data = cl_wd_matrix_head_data=>new_matrix_head_data( lr_link_to_action ).

  •     assign the layout data to the link to action

      lr_link_to_action->set_layout_data( lr_matrix_head_data ).

  •     add the link to action to the current tray

      m_fetched_tray->add_child( lr_link_to_action ).

    ENDLOOP.

  ENDIF.

  • fill the “used-lower-down” tray

  CLEAR mt_zldbm.

  SELECT *

    FROM zldbm

    INTO

   TABLE mt_zldbm

   WHERE ldbname  = m_definition_name

     AND nodename = v_ldbnode

     AND infotype = ‘UE’.

  IF sy-subrc = 0.

    LOOP AT mt_zldbm ASSIGNING -colname ‘:’  coltext INTO display_txt.

  •     create a linktoaction for the current view element inside of the current tray

      lr_link_to_action = cl_wd_link_to_action=>new_link_to_action(

                            id        = id_txt

                            on_action = ‘DISPLAY_COL_DETAIL’

                            text      = display_txt

                            view      = m_view ).

  •     create the grid layout data for the link to action

      lr_matrix_head_data = cl_wd_matrix_head_data=>new_matrix_head_data( lr_link_to_action ).

  •     assign the layout data to the link to action

      lr_link_to_action->set_layout_data( lr_matrix_head_data ).

  •     add the link to action to the current tray

      m_used_tray->add_child( lr_link_to_action ).

    ENDLOOP.

  ENDIF.

  • fill the “index” tray

  CLEAR mt_zldbm.

  SELECT *

    FROM zldbm

    INTO

   TABLE mt_zldbm

   WHERE ldbname  = m_definition_name

     AND nodename = v_ldbnode

     AND infotype = ‘IX’.

  IF sy-subrc = 0.

    LOOP AT mt_zldbm ASSIGNING -colname ‘:’  coltext INTO display_txt.

  •     create a linktoaction for the current view element inside of the current tray

      lr_link_to_action = cl_wd_link_to_action=>new_link_to_action(

                            id        = id_txt

                            on_action = ‘DISPLAY_COL_DETAIL’

                            text      = display_txt

                            view      = m_view ).

  •     create the grid layout data for the link to action

      lr_matrix_head_data = cl_wd_matrix_head_data=>new_matrix_head_data( lr_link_to_action ).

  •     assign the layout data to the link to action

      lr_link_to_action->set_layout_data( lr_matrix_head_data ).

  •     add the link to action to the current tray

      m_index_tray->add_child( lr_link_to_action ).

    ENDLOOP.

  ENDIF.

endmethod.

Note for the unwary:  I had to modify the custom table zldbm created in Part 9 so that none of the colnames were lower-case.  This is because they’re used to create action-link id’s in the above code, and WD-ABAP does not permit lower-case letters in element ids.

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. David Halitsky
    In the unlikely event that anyone’s actually been following this tutorial in detail, someone may have already caught the mistake made in the last section (Learning what you don’t need is as important as learning what you do (Parts 10b-c) of “Event-Driven” Tutorial on WDR_TEST_UI_ELEMENTS)). In that section, invocation of the create_settings method of the SAP-delivered class cl_wdr_all_in_one_uielem was eliminated and the needed code from this method was placed into the custom method create_lgcldb_tree of the cloned class zcl_wdr_all_in_one_uielem.

    At the time Parts10bc was posted, I thought I had all this “needed code” from the original method. But it turned out I had overlooked an obvious piece of code that needed to be incorporated as well, in order to create a new contest node when a new action link is selected from a lefthand side library.

    In particular, see the revised main post above for the context-node creation code that was left out.

    (0) 

Leave a Reply