I hope you’re not getting tired of Web Dynpro. I will get back to the function SM and VC stuff soon, but lately I’ve been consumed with converting my Rapier product to ABAP Web Dynpro, so as you can guess, that’s where all of my fun learning experiences have been. For those you tired of this, I promise to be back in functional side again soon. I’m not finished with my conversion, so that means its time to add new functionality… Today it’s creating a dynamic table. For everyone else, I hope you find this useful 🙂
So, to set the stage, a lot of the Rapier functionality is based on dynamic tables. The idea is that you can define how you want your input and output fields to work. That means, I needed to be able to build a dynamic table. I had to a lot of online hunting to pull all this together, but finally got it working how I wanted. Thought I’d share this with y’all.
I implemented all of this in the wdomodifyview method.
*** Coding for Dynamic Table
DATA: lt_col TYPE cl_abap_structdescr=>component_table,
col like LINE OF lt_col,
struct_type TYPE REF TO cl_abap_structdescr,
table_type TYPE REF TO cl_abap_tabledescr,
node_info TYPE REF TO if_wd_context_node_info,
node TYPE REF TO if_wd_context_node,
tab_XXX TYPE REF TO data,
row_XXX TYPE REF TO data,
l_root TYPE REF TO cl_wd_uielement_container,
l_node TYPE REF TO if_wd_context_node,
l_table TYPE REF TO cl_wd_table,
lt_cols TYPE CL_WD_TABLE_COLUMN=>TT_TABLE_COLUMN,
wa_cols TYPE REF TO CL_WD_TABLE_COLUMN,
l_col_hdr TYPE REF TO CL_WD_CAPTION,
lv_col_text TYPE string,
lv_col_fld TYPE string.
data: lv_image TYPE REF TO cl_wd_image.
data: nd type ref to if_wd_context_node,
nd_list type WDR_CONTEXT_CHILD_MAP,
wa_list TYPE WDR_CONTEXT_CHILD.
data: n type i,
idx TYPE i.
FIELD-SYMBOLS: <table> TYPE table,
<row> TYPE data,
<fs_col> TYPE any,
<fs_col2> TYPE any.
*** build table columns
loop at XXX into wa_XXX where visible = ‘X’.
col-name = “anything”.
*** note, if you use describe_by_name, LV_COL_FIELD must be a table-fieldname combination,
*** then the method will find the data type. I wasn’t able to find any way to just enter in the date
*** type.
col-type ?= cl_abap_datadescr=>describe_by_name( LV_COL_FLD ).
append col to lt_col.
endloop.
*** build dynamic structure
struct_type = cl_abap_structdescr=>create( lt_col ).
*** returns meta information about the node
CALL METHOD wd_context->get_node_info
RECEIVING
node_info = node_info.
*** this simply checks to see if the node already exists to stop potential short dumps. This is
***important depending on where you implement this code, and if it runs multiple times.
nd_list = wd_context->get_child_nodes( ).
READ TABLE nd_list with KEY name = ‘XXX’ TRANSPORTING NO FIELDS.
if sy-subrc <> 0.
*** creates info object and adds it as a lower level node CALL METHOD node_info->add_new_child_node(
exporting
name = ‘XXX’
static_element_rtti = struct_type
is_static = abap_false
RECEIVING
child_node_info = node_info ).
endif.
*** child node of lead selection or specific index
CALL METHOD wd_context->get_child_node
EXPORTING
name = ‘XXX’
RECEIVING
child_node = node.
clear n.
n = node->get_element_count( ).
if n = 0.
*** Return RTTI object for sturcture type of static attributes
CALL METHOD node_info->get_static_attributes_type
RECEIVING
rtti = struct_type.
endif.
*** now you have all of the context nodes created… next up, creating the table.
*** create table
table_type = cl_abap_tabledescr=>create( p_line_type = struct_type ).
FREE tab_xxx.
CREATE DATA tab_xxx TYPE HANDLE table_type.
ASSIGN tab_xxx->* to <table>.
refresh <table>.
*** create lines
FREE row_configequiphis.
CREATE DATA row_xxx TYPE HANDLE struct_type.
ASSIGN row_xxx->* to <row>.
*** populate the values for the table. Don’t worry too much about this implementation. This is
***uses dynamic tables to populate the structure. What you need to do is populate all of your
***rows and columns to make a table that will be bound to your new table.
LOOP AT wd_this->it_xxx INTO wa_xxx.
loop at wd_this->it_xxx into wa_xxx.
ASSIGN COMPONENT wa_xxx-yyy OF STRUCTURE <row> to <fs_col>.
if sy-subrc = 0.
ASSIGN COMPONENT wa_xxx-yyy OF STRUCTURE wa_xxx to <fs_col2>.
if sy-subrc = 0.
<fs_col> = <fs_col2>.
endif.
endif.
endloop.
APPEND <row> to <table>.
ENDLOOP.
*** bind the table
node->bind_table( new_items = <table>
set_initial_elements = abap_true ).
*** build table
l_root ?= view->get_element( ‘TC_TABLE’ ).
l_node ?= wd_context->get_child_node( ‘XXX’ ).
cl_wd_dynamic_tool=>create_table_from_node(
ui_parent = l_root
table_id = ‘TB_TABLE’
node = l_node ).
There’s all the magic. It’s as simple as creating the nodes, populating those nodes, and then binding them to the table. Sounds easy right??? as you can see from the code above, it was a lot more complex than I imagined. Hope this makes life easier for you.
As always, thanks for reading and don't forget to check out our SAP Service Management Products at my other company JaveLLin Solutions,
Mike
hi,
thanks for posting this.
I have created the example above but when updating the table’s structure the structure is not being refreshed.
what can i do?
thank you,
javi
Hi Javi,
I’m not sure I understand what is happening? Are you seeing a table render when you try your application? This method won’t really work if you have a table already existing, this concept was for generating the entire table within the code. I’ve since moved away from this approach. I’ve found it’s a lot cleaner to create a “super” table that has everything, and simple hide columns I don’t want, rename headers and change the sequence.
If you can give me more details of what you’re experiencing, I’ll do my best to help.
thank,s
Mike