Skip to Content
Author's profile photo Former Member

Dynamic UI Generation in Web Dynpro ABAP

How Come!!!. That was my first reaction when I saw the view layout of a webdynpro for abap component as

https://lh6.googleusercontent.com/urTzPvHg0Jqz78LJaDR309FC97LvKK2e35idzhKbA6XUZLEaIBpyOeBwV-ZGPIBEgNIVUoqHZGZpypALB2bEKHt9vm1D0T8tqqfSOAIMZ6zX8cx0o1_X9K-nfiE0bI9ywQ

While output was:

https://lh6.googleusercontent.com/KAxVBi48PYjSaMgRuSKSqWB2IGrUdOJnZ9kxEqo92fQq61dn6-3O8ck92DPdAEWvTWSXcZiHV1rSp7gcbOgVtVgo3p5ONRQ-cn3P2h_rW-VaFylZWsCwEGq8dIsJcR9zPw

And that was my first day when I heard about dynamic UI generation from my Beautiful team lead. It goes like:

There are classes for each UI element in webdynpro for ABAP

( I.e.  CL_WD_CHECKBOX , CL_WD_CHECKBOX_GROUP, CL_WD_INPUT_FIELD etc..)

One can add this created UI element object to the current View in WDDOMODIFYVIEW method of the view.

Let’s start with simple creation of Tray UI element in the View.

Exercise 1:

Create Tray UI element in the view.

Solution:

Create a Webdynpro component using transaction code Se80 and in the MAIN view create a transparent container named

TC_MAIN with flow layout. ( It’s a not mandatory to create it but it’s a good practice to create such transparent container

as it can be helpful if you are planning to change the layout of your view etc.. )

All the dynamic generated UI elements will be placed over this transparent container.

https://lh6.googleusercontent.com/MKxDyQ45nkwNzBpoxfJ4ewmj_m8JPnJPNhehsyDUWIEv8z3N8Po1qcARuowSsNMHzlpR9XAbYD6kc15mN5ld-t66mgshXdMjDSin4QLGIs7joe1rLXN3sX92aqdavaYz4w

Put the below code in your WDDOMODIFYVIEW method of the view and your tray UI Element will be ready.

method WDDOMODIFYVIEW .
 "Let's Create Tray
 data : lr_tray type REF TO cl_wd_tray.
 data : lr_caption TYPE REF TO cl_wd_caption.
 DATA : lr_container  TYPE REF TO cl_wd_uielement_container.
 data : lr_flow type ref to cl_wd_flow_data.
 data : lr_matrix_layout type REF TO cl_wd_matrix_layout.
 
 "As we are gonna put the tray in TC_MAIN ( the transperant container )
 "fetch it ...
 lr_container ?= view->get_element( 'TC_MAIN' ).
 
 "Create a Tray Object
 CALL METHOD CL_WD_TRAY=>NEW_TRAY
 EXPORTING
 ID      = 'TR_TRAY'
 WIDTH   = '100%'
 RECEIVING
 CONTROL = lr_tray.
 
 
 "Need to Assign the flow layout information for this Tray
 "As it is part if ROOTUIELEMENTCONTAINER ( with layout flow )
 lr_flow = cl_wd_flow_data=>new_flow_data( lr_tray ).
 
 lr_tray->set_layout_data( lr_flow ).
 "" add tray to container
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_tray.
 
 "' set layout of tray
 CALL METHOD cl_wd_matrix_layout=>new_matrix_layout
 EXPORTING
 container = lr_tray
 RECEIVING
 control   = lr_matrix_layout.
 
 CALL METHOD cl_wd_caption=>new_caption
 EXPORTING
 id      = 'CA_TRAY'
 text    = 'Yahoo... Here is my Tray (*_*)'
 RECEIVING
 control = lr_caption.
 
 "' set header for tray
 CALL METHOD lr_tray->set_header
 EXPORTING
 the_header = lr_caption.
 
 endmethod.

Save , Activate and RUN

Exercise 2:


Add an input field in the tray with label attached to that input field and a button at bottom.

Solution:

As the input field’s Value property needs to be bind with View context node attribute, we need to create context node/attribute too.

In case of input field UI Element.

Create A method in Component controller Named: RET_CC_CONTEXT.

Exporting parameter : ER_CONTEXT  type ref to IF_WD_CONTEXT_NODE.

Put the below code in your WDDOMODIFYVIEW method and Run it Again.

If you see an Error while activation,scratch your head read the error description and solve it!

method WDDOMODIFYVIEW .
 "Let's Create Tray
 data : lr_tray type REF TO cl_wd_tray.
 data : lr_caption TYPE REF TO cl_wd_caption.
 DATA : lr_container  TYPE REF TO cl_wd_uielement_container.
 data : lr_flow type ref to cl_wd_flow_data.
 data : lr_matrix_layout type REF TO cl_wd_matrix_layout.
 
 "As we are gonna put the tray in TC_MAIN ( the transperant container )
 "fetch it ...
 lr_container ?= view->get_element( 'TC_MAIN' ).
 
 "Create a Tray Object
 CALL METHOD CL_WD_TRAY=>NEW_TRAY
 EXPORTING
 ID      = 'TR_TRAY'
 WIDTH   = '100%'
 RECEIVING
 CONTROL = lr_tray.
 
 
 "Need to Assign the flow layout information for this Tray
 "As it is part if ROOTUIELEMENTCONTAINER ( with layout flow )
 lr_flow = cl_wd_flow_data=>new_flow_data( lr_tray ).
 
 lr_tray->set_layout_data( lr_flow ).
 "" add tray to container
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_tray.
 
 "' set layout of tray
 CALL METHOD cl_wd_matrix_layout=>new_matrix_layout
 EXPORTING
 container = lr_tray
 RECEIVING
 control   = lr_matrix_layout.
 
 CALL METHOD cl_wd_caption=>new_caption
 EXPORTING
 id      = 'CA_TRAY'
 text    = 'Yahoo... Here is my Tray (*_*)'
 RECEIVING
 control = lr_caption.
 
 "' set header for tray
 CALL METHOD lr_tray->set_header
 EXPORTING
 the_header = lr_caption.
 
 
 "****************Create Input field ********************************
 "create Node And Element for input field
 "Part 1: stracture creation : with one field called name
 TYPE-POOLS:  abap.
 
 DATA :
 lt_components     TYPE abap_component_tab,
 lw_component      TYPE LINE OF abap_component_tab,
 lr_structdescr    type ref to CL_ABAP_STRUCTDESCR,
 lt_attribs TYPE  wdr_context_attr_info_map,
 ls_attribs like LINE OF lt_attribs.
 
 
 lw_component-name = 'NAME'.
 TRY.
 lw_component-type = cl_abap_elemdescr=>get_c(  p_length =  20 ).
 CATCH cx_sy_move_cast_error .
 ENDTRY.
 
 append lw_component to lt_components.
 
 lr_structdescr = cl_abap_structdescr=>create( lt_components ).
 "Part2 : Now Create a Node based on this Dynamic struct.
 
 DATA:
 lo_parent_node_info                TYPE REF TO if_wd_context_node_info,
 lo_child_node_info                 TYPE REF TO if_wd_context_node_info,
 *    lo_nd_gen_tab                      TYPE REF TO if_wd_context_node,
 lt_child_node_map                  TYPE wdr_context_child_info_map,
 comp_context type ref to if_wd_context_node.
 FIELD-SYMBOLS : <fs_stru>    TYPE any .
 *  DATA   dy_stru       TYPE REF TO data.
 
 wd_comp_controller->ret_cc_context(
 IMPORTING
 er_context = comp_context ).
 
 lo_parent_node_info = comp_context->get_node_info( ).
 lt_child_node_map = lo_parent_node_info->get_child_nodes( ).
 READ TABLE lt_child_node_map TRANSPORTING NO FIELDS WITH TABLE KEY name = 'ND_DETAIL'.
 IF sy-subrc = 0.
 " REMOVE_CHILD_NODE
 lo_parent_node_info->remove_child_node(  'ND_DETAIL' ).
 ENDIF.
 
 "" get attrib property
 LS_ATTRIBS-name = 'NAME'.
 insert ls_attribs into table lt_attribs.
 
 " create Node in Comp Controller
 CALL METHOD lo_parent_node_info->add_new_child_node
 EXPORTING
 name                         = 'ND_DETAIL'
 is_singleton                 = abap_true
 static_element_rtti          = lr_structdescr
 is_static                    = abap_true
 attributes                   = lt_attribs
 RECEIVING
 child_node_info              = lo_child_node_info.
 
 
 DATA lr_wa            TYPE REF TO data.
 data lo_child_node_detail TYPE ref to if_wd_context_node.
 FIELD-SYMBOLS <lfs_dyn> TYPE any.
 CREATE DATA lr_wa TYPE HANDLE lr_structdescr.
 ASSIGN lr_wa->* TO <lfs_dyn>.
 lo_child_node_detail = comp_context->get_child_node( name = 'ND_DETAIL' ).
 lo_child_node_detail->bind_structure( EXPORTING new_item =   <lfs_dyn> ).
 
 " Map that component controller node to View
 
 DATA: lo_node_info TYPE REF TO if_wd_context_node_info,
 lo_node TYPE REF TO if_wd_context_node,
 mapping_info TYPE wdr_context_mapping_info,
 lv_name TYPE string,
 lt_path TYPE wdr_ctx_element_path_segments.
 DATA map_path TYPE string.
 CLEAR lt_path.
 
 ""
 DATA:
 lr_child_node_info_view                 TYPE REF TO if_wd_context_node_info,
 lt_child_node_map_view                 TYPE wdr_context_child_info_map.
 lo_node_info  = WD_CONTEXT->get_node_info( ).
 lv_name = 'ND_DETAIL'.
 lt_child_node_map_view  = lo_node_info->get_child_nodes( ).
 READ TABLE lt_child_node_map TRANSPORTING NO FIELDS WITH TABLE KEY name = 'ND_DETAIL'.
 IF sy-subrc = 0.
 " REMOVE_CHILD_NODE
 lo_node = wd_context->get_child_node(  name = 'ND_DETAIL' ).
 lr_child_node_info_view = lo_node->get_node_info( ).
 RETURN.
 ELSE.
 ENDIF.
 
 CONCATENATE 'COMPONENTCONTROLLER.' lv_name INTO map_path.
 APPEND map_path TO lt_path.
 mapping_info-controller = 'COMPONENTCONTROLLER'. "conponent name
 mapping_info-path = lt_path. "Controller context node name
 "" create view node refering component node
 CALL METHOD lo_node_info->add_new_mapped_child_node
 EXPORTING
 child_name      = lv_name
 mapping_info    = mapping_info
 is_static       = abap_true
 RECEIVING
 child_node_info = lr_child_node_info_view.
 
 
 "Now Let's Create An input field along with the label and put it in Try
 "Bind the inout field with the Name element of ND_DETAIL Node we created
 
 DATA lr_input  TYPE REF TO cl_wd_input_field..
 DATA lr_matrix_data    TYPE REF TO cl_wd_matrix_data.
 DATA lr_matrix    TYPE REF TO cl_wd_matrix_head_data.
 DATA lv_lbl_id TYPE string.
 DATA lv_lbl_txt TYPE string.
 DATA lv_lbl_for TYPE string.
 DATA lr_label     TYPE REF TO cl_wd_label.
 DATA inp_id TYPE string.
 DATA lv_width TYPE string.
 CLEAR  : inp_id , lv_width.
 
 CALL METHOD cl_wd_input_field=>new_input_field
 EXPORTING
 bind_value             = 'ND_DETAIL.ND_DETAIL.NAME'
 id                     = 'IF_NAME'
 input_prompt           = 'Enter Name'
 RECEIVING
 control                = lr_input.
 
 "" create lbl for Input field
 CALL METHOD cl_wd_label=>new_label
 EXPORTING
 id        = 'LBL_NAME'
 label_for = 'IF_NAME'
 text      = 'Name'
 RECEIVING
 control   = lr_label. " CONTROL
 
 lr_matrix = cl_wd_matrix_head_data=>new_matrix_head_data( lr_label ).
 lr_label->set_layout_data( lr_matrix ).
 
 lr_matrix_data = cl_wd_matrix_data=>new_matrix_data( lr_input ).
 lr_input->set_layout_data( lr_matrix_data ).
 
 "Let's Add this couple to the Try
 
 "' get tray as container
 lr_container ?= view->get_element( 'TR_TRAY' ).
 
 
 "" add label and Input field to Tray
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_label.
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_input.
 
 "Now let's Create a button and add it to Tray
 data : lr_button type REF TO cl_wd_button.
 
 CALL METHOD CL_WD_BUTTON=>NEW_BUTTON
 EXPORTING
 IMAGE_SOURCE           = '~Icon/Search'
 on_action              = 'PROCESS_EVENT'
 ID                     = 'BTN_SEARCH'
 TEXT                   = 'Sumit'
 RECEIVING
 CONTROL                 = lr_button.
 
 "as we want this button to come on new line make it matrix head data
 
 lr_matrix = cl_wd_matrix_head_data=>new_matrix_head_data( lr_button ).
 lr_button->set_layout_data( lr_matrix ).
 
 "" add Button to Tray
 CALL METHOD lr_container->add_child
 EXPORTING
 the_child = lr_button.
 
 endmethod.

  1. SAVE, Activate and Run

https://lh3.googleusercontent.com/-iacYw1sCKZeXAXKpD1fnigPosez2x4lgZehAZ6WLF3HJXvwpYBlCRNHsSjDAnYaJCcDoyFE8TFq4dGT1wzZQNMrRP-WRPnnxZnWEvb07-xKJ019hl8UXcK9q8ziq1uE0Q

If you are not bored ….Try this

Exercise 3:


Get the Value user has entered in Name field and on click of the Button SEARCH Display it in popup.

Note: You need to implement the ONACTIONPROCESS_EVENT Method Which is we have bind with the Search button.

Happy Coding….

Assigned Tags

      1 Comment
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      Hi Raju Borda,

      I am seeing small kid in your screen output, Is this lengthy abap code to generate a small kid in ur output.??