cancel
Showing results for 
Search instead for 
Did you mean: 

How to delete a dynamically created node using Code

Former Member
0 Kudos

Hello All,

I have created a node for filling the ALV dynamically at the press of a button based on the values the user selects.

If I again click the button it says the child node already exists.

How to resolve this.

How can I delete this node.

              • Next, validate which fields you will use as ALV columns *******

DATA: ls_component TYPE cl_abap_structdescr=>component,

lr_type TYPE REF TO cl_abap_datadescr,

lt_components TYPE cl_abap_structdescr=>component_table.

IF stru_param-carrid = 'X'.

lr_type ?= cl_abap_typedescr=>describe_by_name( p_name = 'S_CARR_ID' ).

ls_component-name = 'CARRID'.

ls_component-type = lr_type .

APPEND ls_component TO lt_components.

ENDIF.

IF stru_param-connid = 'X'.

lr_type ?= cl_abap_typedescr=>describe_by_name( p_name = 'S_CONN_ID' ).

ls_component-name = 'CONNID'.

ls_component-type = lr_type .

APPEND ls_component TO lt_components.

ENDIF.

IF stru_param-fldate = 'X'.

lr_type ?= cl_abap_typedescr=>describe_by_name( p_name = 'S_DATE' ).

ls_component-name = 'FLDATE'.

ls_component-type = lr_type .

APPEND ls_component TO lt_components.

ENDIF.

IF stru_param-price = 'X'.

lr_type ?= cl_abap_typedescr=>describe_by_name( p_name = 'S_PRICE' ).

ls_component-name = 'PRICE'.

ls_component-type = lr_type .

APPEND ls_component TO lt_components.

ENDIF.

IF stru_param-currency = 'X'.

lr_type ?= cl_abap_typedescr=>describe_by_name( p_name = 'S_CURRCODE' ).

ls_component-name = 'CURRENCY'.

ls_component-type = lr_type .

APPEND ls_component TO lt_components.

ENDIF.

              • Next, create a new structure and assign it to a new dynamic

              • context node

DATA: lr_root_info TYPE REF TO if_wd_context_node_info ,

lr_node_info TYPE REF TO if_wd_context_node_info,

lr_structdescr TYPE REF TO cl_abap_structdescr.

call method cl_abap_structdescr=>create

exporting

p_components = lt_components

receiving

p_result = lr_structdescr.

  • Get context node info

lr_root_info = wd_context->get_node_info( ).

  • Generate new node with the dynamic structure

CALL METHOD lr_root_info->add_new_child_node

EXPORTING

name = 'DATA'

is_initialize_lead_selection = abap_false

static_element_rtti = lr_structdescr

is_static = abap_false

RECEIVING

child_node_info = lr_node_info.

  • get instance of new node

DATA: dyn_node TYPE REF TO if_wd_context_node.

dyn_node = wd_context->get_child_node( name = 'DATA' ).

              • Last, Get reference to model *******

DATA: lo_interfacecontroller type ref to iwci_salv_wd_table.

lo_interfacecontroller = wd_this->wd_cpifc_alv( ).

lo_interfacecontroller->set_data( dyn_node ).

Accepted Solutions (0)

Answers (7)

Answers (7)

laurent_touillaud
Contributor
0 Kudos

Hi WDA fans,

Just to complete the post for people who want an additional exemple code when you must do your treatment only in the modifyview method -> creating and deleting nodes and UI dynamic table

ALL IN THE MODIFYVIEW METHOD :

* Delete the UI element content when nodes have been refreshed by a reset/refresh method

TRY.

lr_node = wd_context->get_child_node( 'MY_NODE1' ).

CATCH cx_wd_context. "not yet created

lr_sumpack_cont ?= view->get_element( 'PACKSUMMARIES' ).

lr_sumpack_cont->remove_all_children( ).

ENDTRY.

DATA : l_node TYPE REF TO if_wd_context_node,

l_node_2 TYPE REF TO if_wd_context_node,

l_node_info TYPE REF TO if_wd_context_node_info,

l_table TYPE REF TO cl_wd_table,

nd_list TYPE wdr_context_child_map,

wa_list TYPE wdr_context_child.

* Create a dynamic table of a known structure

DATA: node_info TYPE REF TO if_wd_context_node_info,

comp_tab TYPE cl_abap_structdescr=>component_table,

comp LIKE LINE OF comp_tab,

my_table TYPE REF TO data,

my_row TYPE REF TO data.

FIELD-SYMBOLS: <table> TYPE table,

<row> TYPE data,

<flight> TYPE sflight.

DATA: lo_struct TYPE REF TO cl_abap_structdescr,

lt_comp TYPE cl_abap_structdescr=>component_table,

lo_run_st TYPE REF TO cl_abap_structdescr,

lo_run_tt TYPE REF TO cl_abap_tabledescr,

lo_struc TYPE REF TO data,

lo_ttype TYPE REF TO data.

* fill new node

DATA: ls_gap TYPE zsnc_packing_gap_st.

DATA: lv_node TYPE string.

DATA: lv_table TYPE string.

DATA: lv_numi TYPE i.

DATA: lv_num(1).

DATA: lv_table_header TYPE string.

DATA: lo_table TYPE REF TO cl_wd_table.

DATA: lo_caption TYPE REF TO cl_wd_caption.

DATA: lt_attributes TYPE wdr_context_attr_info_map.

DATA: ls_deltol TYPE zsnc_del_toleran.

DATA: lv_undertol TYPE string.

DATA: lv_lines TYPE i.

FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE,

<fs_line> TYPE any,

<fs_node> TYPE REF TO if_wd_context_node.

* principal table

IF wd_this->lt_gap[] IS NOT INITIAL.

lo_struct ?= cl_abap_structdescr=>describe_by_name( 'ZSNC_PACK_SUMMARY' ).

lt_comp = lo_struct->get_components( ).

lo_run_st = cl_abap_structdescr=>create( lt_comp ).

lo_run_tt ?= cl_abap_tabledescr=>create( p_line_type = lo_run_st ).

* create table for each stock category

lr_sumpack_cont ?= view->get_element( 'PACKSUMMARIES' ).

CREATE DATA lo_ttype TYPE HANDLE lo_run_tt.

ASSIGN lo_ttype->* TO <fs_table>.

CREATE DATA lo_struc TYPE HANDLE lo_run_st.

ASSIGN lo_struc->* TO <fs_line>.

LOOP AT wd_this->lt_gap INTO ls_gap.

MOVE-CORRESPONDING ls_gap TO <fs_line>.

APPEND <fs_line> TO <fs_table>.

AT END OF stock_category. "create one table by stock category

* handle runtime data type by means of generic variables

ADD 1 TO lv_numi. lv_num = lv_numi.

CONCATENATE 'MY_NODE' lv_num INTO lv_node.

CONCATENATE 'MY_TABLE' lv_num INTO lv_table.

* now created the node

TRY.

l_node = wd_context->get_child_node( lv_node ).

CATCH cx_wd_context. "not yet created

node_info = wd_context->get_node_info( ).

l_node_info = node_info->add_new_child_node(

name = lv_node

is_mandatory = abap_true

is_multiple = abap_true

static_element_rtti = lo_run_st

is_initialize_lead_selection = abap_false

is_static = abap_false ).

* attributes = lt_attributes ).

* bind table to node

l_node = wd_context->get_child_node( lv_node ).

l_node->bind_table( <fs_table> )."( new_items = <fs_table> set_initial_elements = abap_true ).

* create the ui element table

l_node_2 = wd_context->get_child_node( lv_node ).

cl_wd_dynamic_tool=>create_table_from_node(

EXPORTING

ui_parent = lr_sumpack_cont

table_id = lv_table

node = l_node_2

RECEIVING

table = lo_table ).

IF lo_table IS BOUND.

CLEAR lv_undertol.

READ TABLE wd_this->lt_deltol INTO ls_deltol

WITH KEY stock_category = ls_gap-stock_category.

IF sy-subrc IS INITIAL.

lv_undertol = ls_deltol-under_tol_perc.

ELSE.

READ TABLE wd_this->lt_deltol INTO ls_deltol

WITH KEY stock_category = space.

IF sy-subrc IS INITIAL.

lv_undertol = ls_deltol-under_tol_perc.

ENDIF.

ENDIF.

CONCATENATE 'PACKING SUMMARY' ls_gap-stock_category lv_undertol

INTO lv_table_header SEPARATED BY space.

lo_caption = cl_wd_caption=>new_caption( text = lv_table_header ).

lo_table->set_header( lo_caption ).

* set visible rows

DESCRIBE TABLE <fs_table> LINES lv_lines.

lo_table->set_visible_row_count( value = lv_lines ).

ENDIF.

FREE : <fs_table>, <fs_line>.

ENDTRY.

ENDAT.

ENDLOOP.

ENDIF.

Reset/refresh method :

node_info = wd_context->get_node_info( ).

DO.

ADD 1 TO lv_numi. lv_num = lv_numi.

CONCATENATE 'MY_NODE' lv_num INTO lv_node.

CONCATENATE 'MY_TABLE' lv_num INTO lv_table.

TRY.

l_node = wd_context->get_child_node( lv_node ).

CATCH cx_wd_context.

EXIT.

ENDTRY.

node_info = node_info->get_child_node( lv_node ). "node to be removed

node_info->remove_dynamic_attributes( ).

node_info = node_info->get_parent( ).

node_info->remove_child_node( lv_node ).

ENDDO.

Former Member
0 Kudos

Thanx U all.

Former Member
0 Kudos

I wud once again suggest u to create unique context node by usin the attributes , like I referred .

no need to delete node and create once again with the same id

regards,

amit

Former Member
0 Kudos

Hello All.

In my application there would be some check boxes. The user would select any or all of these check boxes.

On the click of go button the fields that has been checked alone has to be made visible in the ALV. (Suppose he has choosen ID and CODE of all the fields from the table only these fields should be made visible in the code).

For that I have written the code which I have posted in my first query.

The issue is without refreshing the browser if the user again clicks the go button, the application is throwing an error stating the child node data already exists. I have given the node name as Data.

This is the requirement. If the user again clicks the go button without refreshing the browser also the fields that are now selected by the user should be made visible in the ALV. (Like ID, Name, Code, Address).

Thanx and Regards,

SampathKumar

Former Member
0 Kudos

Hi Sampath,

You know how many fields will be there in ALV. So you can create all the fields and hide them as per the selection.

This will be best rather than going for dynamic node creation.

You need to set visible properties for each column on chkbox selection and button action by calling instantiation for ALV.


* Data declarations
  DATA: lr_column_settings  TYPE REF TO if_salv_wd_column_settings,
        lr_table_settings   TYPE REF TO if_salv_wd_table_settings ,
        lr_column_header    TYPE REF TO cl_salv_wd_column_header  ,
        lt_columns          TYPE salv_wd_t_column_ref             ,
        ls_column           TYPE salv_wd_s_column_ref             .

* Set Cell Editor for input field
  lr_column_settings ?= wd_this->lr_config                   .   "Config reference for ALV
  lt_columns = lr_column_settings->get_columns( )                 .

**Get columns 
  LOOP AT lt_columns INTO ls_column                               .
    CASE ls_column-id                                             .

      WHEN 'CA_ID'                                              .
**To hide ID field
        ls_column-r_column->set_visible(
            cl_wd_uielement=>e_visible-none )  .   "Hide column


    ENDCASE                                                       .
  ENDLOOP                                                         .

Hope this helps!

Thanks,

Tejaswini

Edited by: Tejaswini Chafekar on Aug 27, 2009 11:35 AM

Edited by: Tejaswini Chafekar on Aug 27, 2009 11:38 AM

Former Member
0 Kudos

Hi,

In the button handler.,

Before you create the node you need to delete it to avoid that error.

Please check my code. I have got the root node information and checking for the NAME of the node.

If Yes, then deleting it and creating it again.

Regards,

Lekha.

Former Member
0 Kudos

try referring the WDA " DEMODYNAMIC" under SWDP_DEMO package .

refer the help :http://help.sap.com/saphelp_nw04s/helpdata/EN/af/cb744176cb127de10000000a155106/content.htm

also see Radhika's reply in the thread

Former Member
0 Kudos

hi ,

it is very simple to remove the dynamic context node

u have to simply use the method remove_child_node of the interface if_wd_context_node_info .

just keep in mind that , while creating the dynamic node , using ADD_NEW_CHILD_NODE

u must have set the IS_STATIC parameter to abap_false

otherwise u wont be able to delete the nodes at run time

do check out the following links as well :

thanks

amit

Former Member
0 Kudos

Hi,

To remove your node dynamically you can follow below code.


  DATA  node_info TYPE REF TO if_wd_context_node_info.

  node_info = wd_context->get_node_info( ).
  node_info = node_info->get_child_node( 'MY_NODE' ).    "node to be removed
  node_info = node_info->get_parent( ).
  node_info->remove_child_node( 'MY_NODE' ).

Hope this helps!

Thanks,

Tejaswini

Former Member
0 Kudos

Hi Tejas,

I tried using your code.

I added it at the end of the method.

But on the click of the button the ALV grid itself is not appearing.

I think since we are removing it its not appearing.

Is there any other option.

Thanx,

SampathKumar.

Former Member
0 Kudos

hi sampath ,

I have got ur point , why delete the node

u just need to have a separate id for each dynamic node u r creating

thn it wud not give u error

u create different context nodes SYS00, SYS01, SYS02 and so on ..

as follows :

..

 ->   *generating dynamic node with UNIQUE ID
 -> DATA : lv_node type string value 'SYS',
  ->      CONCATENATE lv_node wd_this->count_sys INTO lv_node.
  ->wd_this->count_sys = wd_this->count_sys + 1.

here count_sys is attribute of type NUM in ur view , now try using the ADD_NEW_CHILD node

exporting name of the node as lv_node .

I hope u wud be successfully able to generate unique dynamic nodes together with attributes thn, without error

ALV grid wud be visible

do revert in case of issue

thanks,

amit

Former Member
0 Kudos

Hi,

You can use the same node name but you need to delete it before creating it.

if root_node_info is not initial.
    lt_nodes = root_node_info->get_child_nodes( ).
    read table lt_nodes into ls_nodes with key name = wd_assist->gc_detailnode.   "NODENAME
    if sy-subrc eq 0.
      lr_node_info = ls_nodes-node_info.
      CALL METHOD root_node_info->REMOVE_CHILD_NODE
        EXPORTING
          NAME = wd_assist->gc_detailnode.   "NODENAME
    endif.
  endif.                "if lr_nd_root_info is not initial.

* Creation of dynamic node for unassigned efforts offshore
  lr_node_info = root_node_info->add_new_child_node(
  name = wd_assist->gc_detailnode                                   "NODENAME
  static_element_rtti = lr_strucdescr  "RTTI structure
  is_static = abap_false
  is_mandatory = abap_false
  is_mandatory_selection = abap_false
  is_multiple = abap_true
  is_multiple_selection = abap_true
  is_singleton = abap_false ).
*  Pass node ref to global variable
  lr_node = wd_context->get_child_node( wd_assist->gc_detailnode ).
* Pass the node reference to global attribute
  IF lr_node IS BOUND.
    wd_comp_controller->lr_node = lr_node.
  ENDIF.                                 "if lr_node is bound.

After doing thing, then ALV instantioation needs to be done and using SET_DATA method to map the node.

Regards,

Lekha.

Former Member
0 Kudos

Hi,

Can you tell us the requirement again, what u exactly need.

Are you using static node and want to remove it.

why u need to remove your node?

Thanks,

Tejaswini

Former Member
0 Kudos

Hi,

* Root node information
  root_node_info = wd_context->get_node_info( ).

  if root_node_info is not initial.
    lt_nodes = root_node_info->get_child_nodes( ).
    read table lt_nodes into ls_nodes with key name = wd_assist->gc_detailnode.  "Node Name
    if sy-subrc eq 0.
      lr_node_info = ls_nodes-node_info.
      CALL METHOD root_node_info->REMOVE_CHILD_NODE
        EXPORTING
          NAME = wd_assist->gc_detailnode.             "Node Name
    endif.
  endif.                "if lr_nd_root_info is not initial.

After this then try to create the node.

Regards,

Lekha.