cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically delete an input field

siongchao_ng
Contributor
0 Kudos

Hi all,

I have a set of 5 input fields added dynamically previously. ( Input fiekd generated by code method). The 5 input fields user input value is binded to context node. Beside each input field, there is a delete button. If I want to delete the 2nd input field by pressing the 2nd delete button, how do I code it? There is 2 steps here right? Delete the selected context element and ui element.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

yes, you are right.

save the view instance in the view attribute. when the button is pressed, delete the UI element and then delete the context element.

For this purpose , it is handy to have a context attribute containing the id of each dynamic input field,so that you can easily remove the UI element using its id.

You can also make the creation of the UI element method generic, which read the context element and construct the UI layout. In that case you can just delete the context element and call this generic method.

This method should use the reset_view method of the if_wd_view to delete all dynamic UI elements.

Build the Dynamic layout once again based on the context.

siongchao_ng
Contributor
0 Kudos

Hi Baskaran,

Can you provide the codes detailing the steps you mentioned? Thanks.

Former Member
0 Kudos

hi,

i think saraa_n has fairly explained the steps you need to do your job.

Thanks saraa_n.

Answers (4)

Answers (4)

siongchao_ng
Contributor
0 Kudos

What I did was:

1. Delete and re-arrange my itab ( in delete action )

2. Remove all UI elements (wddomodifyview)

3. Invalidate all context elements (wddomodifyview)

4. Rebind the context with the re-arrange itab (wddomodifyview)

5. Re-render the UI elements with the re-arrange itab (wddomodifyview)

saravanan_narayanan
Active Contributor
0 Kudos

Hello Siong,

for your use case, the context node cardinality should be 1..1 and there should be always one element in the context node. whenever a new input field is added, create a new attribute in the context node and bind the same to the input field.

whenever the inputfield is deleted, then just remove the attribute from the context node.

the context node of cardinality 0..n/1..n will come into picture only if you are displaying Table UI element/ Collection of data. I believe this is not your use case. you are displaying flat set of input fields.

BR

Saravanan

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

The rendering for the set of ui elements all these while is always set on context node cardinality 0...n.

For example: This set of ui elements contains various input fields of infotype 9.

So my context node cardinality 0..n consist of many different attribute of various infotype 9 fields.

Every time user pressed on the "add" button it will add 1 new set of ui elements onto the scree. My context elements will add too.

Example: concatenate 'INFOTYPE9_RENDER.' index '.BANKN' into lv_bindpath.

Now, I need to create 1 delete button beside every set of infotype 9 ui elements. If there is already 5 sets of ui elements there, user decided to delete the 3rd set, user shall press the 'delete' button beside the 3rd set of ui elements to delete all the fields there.

Just now, your code shows to delete the ui elements. But I need to delete the 3rd index of the context elements as well. Otherwise, there will be 4 sets of ui elements now, but in the context elements, there are still 5 sets of it. How do I delete the 3rd set of context elements?

saravanan_narayanan
Active Contributor
0 Kudos

the code to delete the 3rd context element is the same

lo_node = wd_context->get_child_node( name = if_v_main=>wdctx_context_name ).

lo_elem = lo_node->get_element( INDEX ).

lo_node->remove_element ( lo_elem ).

but I'm missing something here. Could you post the code of how you are adding the inputfields and context elements?

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

If I use that code to delete my indexed context element, I will get the adaptor error message i posted earlier.

How I render the ui elements:

  • Text View bank account

lv_index = wd_this->cnt.

CONCATENATE 'TXV_' lv_index '_BANK_ACCOUNT' INTO lv_id.

lv_label = 'Bank Account #'.

ls_text_view = cl_wd_text_view=>new_text_view( id = lv_id ).

ls_text_view->set_design( cl_wd_text_view=>e_design-standard ).

ls_text_view->set_text( lv_label ).

CLEAR lv_id.

CLEAR lv_label.

"Create the matrix data and attach to element

ls_matrix_data = cl_wd_matrix_head_data=>new_matrix_head_data(

element = ls_text_view

  • cell_background_design = cl_wd_matrix_data=>e_cell_background_design-fill1

cell_background_design = cl_wd_matrix_data=>e_cell_background_design-transparent

cell_design = cl_wd_matrix_data=>e_cell_design-padless "r_pad

col_span = '1'

height = ''

width = '40'

h_align = cl_wd_matrix_data=>e_h_align-begin_of_line "center

v_align = cl_wd_matrix_data=>e_v_align-baseline "middle

v_gutter = cl_wd_matrix_data=>e_v_gutter-medium ).

container->add_child( ls_text_view ).

  • Input Field Bank Account

lv_index = wd_this->cnt.

MOVE lv_index to lv_text_index.

CONCATENATE 'INFOTYPE9_RENDER.' lv_index '.BANKN' INTO lv_bindpath.

CONCATENATE 'INP_' lv_index '_BANK_ACCOUNT' INTO lv_id.

ls_input_field = cl_wd_input_field=>new_input_field( id = lv_id ).

ls_input_field->set_length( '10' ).

ls_input_field->bind_value( lv_bindpath ).

CLEAR lv_index.

"Create the matrix data and attach to element

ls_matrix_data = cl_wd_matrix_data=>new_matrix_data(

element = ls_input_field

cell_background_design = cl_wd_matrix_data=>e_cell_background_design-transparent

cell_design = cl_wd_matrix_data=>e_cell_design-padless

col_span = '1'

height = ''

width = '100'

h_align = cl_wd_matrix_data=>e_h_align-justify

v_align = cl_wd_matrix_data=>e_v_align-top

v_gutter = cl_wd_matrix_data=>e_v_gutter-none ).

container->add_child( ls_input_field ).

saravanan_narayanan
Active Contributor
0 Kudos

the bindpath for the inputfields is 'INFOTYPE9_RENDER.' lv_index '.BANKN' . From this code what I understood is that you are creating different context nodes for different sets. isnt it?

in this case whenever user deletes the ui elements, then you need to delete the context node itself and not the context element.

code to delete the context node

lo_nd_data = wd_context->get_child_node( 'INFOTYPE9_RENDER' ).

lo_nd_data_info = lo_nd_data->get_node_info( ).

lo_nd_data_info->remove_child_node( lv_index ).

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

Your lo_nd_data_info type to what? The node is typed if_wd_context_node right? Thanks. Need to try it now asap.

saravanan_narayanan
Active Contributor
0 Kudos

sorry forgot to mention the type... its of type IF_WD_CONTEXT_NODE_INFO

lo_nd_data type ref to if_wd_context_node,

lo_nd_data_info type ref to if_wd_context_node_info.

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

Are you sure about the lo_nd_data_info->remove_child_node( lv_index ).

Coz it not using index as formal parameter. It's supposed to be name. For my case, am I supposed to put in the context node name or all the attributes name?

saravanan_narayanan
Active Contributor
0 Kudos

its the context name....

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

I think it not the node. Its the elements. I will have subnode does not exist dump error.

Just now you mentioned:

the bindpath for the inputfields is 'INFOTYPE9_RENDER.' lv_index '.BANKN' . From this code what I understood is that you are creating different context nodes for different sets. isnt it?

in this case whenever user deletes the ui elements, then you need to delete the context node itself and not the context element.

code to delete the context node

lo_nd_data = wd_context->get_child_node( 'INFOTYPE9_RENDER' ).

lo_nd_data_info = lo_nd_data->get_node_info( ).

lo_nd_data_info->remove_child_node( lv_index ).

Think of this way.

If there is 3 sets of ui elements, I will have:

INFOTYPE9_RENDER.1.BANKN

INFOTYPE9_RENDER.2.BANKN

INFOTYPE9_RENDER.3.BANKN

What you call this? I am creating 3 context element here or 3 context node?

saravanan_narayanan
Active Contributor
0 Kudos

could you post your code for creating

INFOTYPE9_RENDER.1.BANKN

INFOTYPE9_RENDER.2.BANKN

INFOTYPE9_RENDER.3.BANKN

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

The code for rendering the ui elements already posted earlier. Everthing is there. How I create ui element and bind them index ascending to the context nodes and its attributes. Note: In order not to complicate stuff here, there is no coding to creating context node and attributes. The node is fixed at cardinality 0..n with its attributes of the various infotype 9 fields name like BANKN, BANKL, BKONT and etc.

There is only 1 add button. Each time user press the add button, the rendering code I posted will run and add a new set of ui elements. It is working fine.

The problem is cherry picking 1 set to be deleted. What do I do with these indexed context elements? Thanks. Anyone have any idea?

saravanan_narayanan
Active Contributor
0 Kudos

Hello Siong,

you need to reset the binding of all the remaining input fields...

initially say three input elements added

1. Input 1 - Binding -> INFOTYPE9_RENDER.1.BANKN -> value = "Account1"

2. Input 2 - Binding -> INFOTYPE9_RENDER.2.BANKN -> value = "Account2"

3. Input 3 - Binding -> INFOTYPE9_RENDER.3.BANKN -> Value = "Account3"

now if the user deletes the first input set. you are deleting the context element 1. Once you delete the first element, the index of second element will be automatically changed from 2 to 1 and same for 3rd element from 3 to 2.

so after deleting the first element your context collection will look like this

INFOTYPE9_RENDER.1.BANKN -> value = "Account2"

INFOTYPE9_RENDER.2.BANKN -> value = "Account3"

there wont be any element with index 3. But your 3rd input is still pointing to INFOTYPE9_RENDER.3.BANKN which is not available in the context collection.

so in this case you need to change the binding of the reminaing two input fields

1. Input 2 - Binding -> INFOTYPE9_RENDER.1.BANKN -> value = "Account2"

2. Input 3 - Binding -> INFOTYPE9_RENDER.2.BANKN -> Value = "Account3"

hope this helps.

BR Saravanan

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

You mean after lo_node->remove_element (lo_elem),

I rebind my table like:

lo_node->bind_table( intab) ?

How do you reset/ re-bind the remaining ui elements to the context elements? Thanks.

saravanan_narayanan
Active Contributor
0 Kudos

in the example I mentioned, if the user deletes the first set of UI elements, then you need to change the bindpath

"ls_input_field->bind_value( lv_bindpath )" of hte 2nd and 3rd set of UI Elements.

in the sense after deletion of the 1st input field, for the 2nd Input field set the bindpath as

ls_input_field->bind_value( "INFOTYPE9_RENDER.1.BANKN" ).

and for the 3rd input

ls_input_field->bind_value( "INFOTYPE9_RENDER.2.BANKN" ).

but this solution will increase the coding complextity.

Workaround for this usecase

1. Whenver the user clicks on delete button, always delete the last set of UI elements. But in the context node, delete the respective context element (context element of respective index)

ex: if you have 3 set of UI elements, if the user opts to delete the first set, then delete the 3rd set if UI elements and delete the context element of index '1'.

in the same scenario if the user opts of delete the 2nd set of ui elements, then delete the 3rd set of UI elements and delete the context element of index '2'.

saravanan_narayanan
Active Contributor
0 Kudos

Hello Siong,

Is your problem solved or do you still face the dump?

BR Saravanan

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

Thanks for the reply. However the indexing issue is perplexing. I am still getting this sort of dump from time to time after clicking delete and add button a couple of times:

'Adapter error in INPUT_FIELD "INP_002_BANK_ACCOUNT" of view "v_name" Context binding of property value cannot be resolved. Element with index 2 does not exist; context node: v_infotype9.1.infotype9_render

So I came out with another solution but there will be dump too if clicking too many times delete and adding. It seems the program lost track of the indexing. But this time the dump will be something like : INPUT_FIELD "INP_002_BANK_ACCOUNT" of view "v_name already exist! Just sort of compromising the to have fewer dumps.

What I did was:

1. Delete and re-arrange my itab ( in delete action )

2. Remove all UI elements (wddomodifyview)

3. Invalidate all context elements (wddomodifyview)

4. Rebind the context with the re-arrange itab (wddomodifyview)

5. Re-render the UI elements with the re-arrange itab (wddomodifyview)

saravanan_narayanan
Active Contributor
0 Kudos

Hello,

I dont see any problem with your delete code.

any reason for deleting the second element of the context node? If I'm not wrong your context will have only one element. isnt it?

BR Saravanan

siongchao_ng
Contributor
0 Kudos

Hi Saraa,

Right now I am very confused about the indexing here. You see there are 3 type of indexing here which must tally with each other in the deleting and adding part.

1. The internal table which consist my input field values.

2. The context elements which consist my input fielkd values.

3. The ui element index it self.

Say there is 4 set of input fields here. If I delete the 2nd set. I need to delete the ui elements with the corect id pointing to 2nd set. In addition, I need to delete the 2nd set of info in my internal table here and the 2nd index of the context element right? I cannot be having 3 sets of ui elements while there are 4 sets of context elements there.

If I press add button to add another new set of ui elemnents, what is the index of the context elements then?

saravanan_narayanan
Active Contributor
0 Kudos

1. Create a controller variable (in Attributes Tab) - MR_VIEW type ref to IF_WD_VIEW

2. in the WDDOMODIFYVIEW, store the VIEW instance to MR_VIEW

wd_this->mr_view = view.

3. in the button's action handler method write the code to delete the input field

data: lr_container type ref to cl_wd_transparent_container.

lr_container ?= wd_this->mr_view->get_element( 'ROOTUIELEMENTCONTAINER' ). "Containers name

lr_container->remove_child(

id = 'INPUT_FIELD1' "Inputfield id

).

Hope this helps.

BR

Saravanan

siongchao_ng
Contributor
0 Kudos

Hey Saraa,

I have a set of ui elements here (text labels with the input fields). There are 2 sets of ui elements. I click on the delete button for 2nd set. It gave me a dump error. 'Adapter error in INPUT_FIELD "INP_002_BANK_ACCOUNT" of view "v_name" Context binding of property value cannot be resolved. Element with index 2 does not exist; context node: v_infotype9.1.infotype9_render

What could it be? This is how i do it. When I click delete button, it send indicator 'x' to wddomodifyview to indicate a delete action has been performed

In the wddomodifyview:

If wd_this->remove = 'X'.

data ui_id type string.

ls_container ?= view->get_element( 'TCO_NAME' ).

" remove text view ui

concatenate 'TXV_' wd_this->remove_ui_index '_BANK_ACCOUNT' into ui_id.

ls_container->remove_child( id = ui_id ).

clear ui_id.

" remove input field ui

concatenate 'INP_' wd_this->remove_ui_index '_BANK_ACCOUNT' into ui_id.

ls_container->remove_child( id = ui_id ).

clear ui_id.

..............

"remove selected context elements

lo_node = wd_context->get_child_node( name = if_v_main=>wdctx_context_name ).

lo_elem = lo_node->get_element( 2 ).

lo_node->remove_element ( lo_elem ).

wd_this->remove = space.

ENDIF.