cancel
Showing results for 
Search instead for 
Did you mean: 

ALV- making row editable.

Former Member
0 Kudos

Hi all.

In my application, i have an ALV table displayed.

I have a button, say change. When the user selects a particular row and clicks the button, i want the entire row to be editable.

I tried using a seperate attribute and then binding the read only property. But, it seems i am going wrong somewhere.

I am fine with making an entire column or entire table editable, but a single row is a problem.

Please suggest. Sample code , if possible, is welcome.

thanks,

Prati.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi Prati,

Cell Editors for all your columns should be Input Field, with text view as cell editor you cannot make a cell editable.

Regards,

Radhika.

Former Member
0 Kudos

Thanks.

lv_column->set_cell_editor( lv_input_field ).

Is the above code correct for setting it as an input field?

And i can make a column or the entire table editable.

I am unable to do it for a single lead selected row.

I hope i am clear.

regards,

Prati.

Former Member
0 Kudos
*---------- ALV table settings.
  DATA: l_table_settings TYPE REF TO if_salv_wd_table_settings .
  l_table_settings ?= lo_value.
  wd_this->l_table =  l_table_settings .

" Make the table editable
  l_table_settings->set_read_only( abap_false ).

*---------- Column settings
  DATA: l_column_settings TYPE REF TO if_salv_wd_column_settings.
  l_column_settings ?= lo_value.

* Get columns
  DATA: lt_columns TYPE salv_wd_t_column_ref ,
        ls_columns TYPE salv_wd_s_column_ref .

  DATA: l_column_header  TYPE REF TO cl_salv_wd_column_header .

  lt_columns = l_column_settings->get_columns( )              .

  LOOP AT lt_columns INTO ls_columns                          .
    CASE ls_columns-id                                        .
     
      WHEN 'COLNAME'                                            .
        l_column_header = ls_columns-r_column->get_header( )  .
        l_column_header->set_ddic_binding_field(
           if_salv_wd_c_column_settings=>ddic_bind_none )     .
        l_column_header->set_text( 'Qty' )                    .
" Create Editable cell ( Input field as cell editor )
        DATA: l_input_field TYPE REF TO cl_salv_wd_uie_input_field.

        CREATE OBJECT l_input_field
          EXPORTING
            value_fieldname = ls_columns-id.
        ls_columns-r_column->set_cell_editor( l_input_field ) .

Regards,

Radhika.

Former Member
0 Kudos

hi Radhika.

Where do I write the code you gave me?

Could you please enlighten me regarding the CASE statement.

What is the COLNAME and qty?

I want that particular row to be editable on the click action of the button, after selecting the row.

regards,

Prati.

Former Member
0 Kudos

Hi Prati,

Suppose you have to cols ( COL1 and COL2 ) for these two columns you should be having two attributes under your node say ATTR1 and ATTR2. Also create an additional attribute EDITABLE type boolean.

The following code in WDDOINIT along with your ALV initialization code.

*---------- ALV table settings.
  DATA: l_table_settings TYPE REF TO if_salv_wd_table_settings .
  l_table_settings ?= lo_value.
  wd_this->l_table =  l_table_settings .

* Set the Editable property to true
  l_table_settings->set_read_only( abap_false ).

*---------- Column settings
  DATA: l_column_settings TYPE REF TO if_salv_wd_column_settings.
  l_column_settings ?= lo_value.

* Get columns
  DATA: lt_columns TYPE salv_wd_t_column_ref ,
        ls_columns TYPE salv_wd_s_column_ref .

  DATA: l_column_header  TYPE REF TO cl_salv_wd_column_header .

  lt_columns = l_column_settings->get_columns( ).

  LOOP AT lt_columns INTO ls_columns                          .
    CASE ls_columns-id                                        .
      WHEN 'ATTR1'                                            .
     l_column_header = ls_columns-r_column->get_header( )  .
        l_column_header->set_ddic_binding_field(
           if_salv_wd_c_column_settings=>ddic_bind_none )     .
" Create Editable cell
        DATA: l_input_field TYPE REF TO cl_salv_wd_uie_input_field.

        CREATE OBJECT l_input_field
          EXPORTING
            value_fieldname = ls_columns-id.
        ls_columns-r_column->set_cell_editor( l_input_field ) .
"binding  the read only property
            l_input_field->set_read_only_fieldname( 'EDITABLE' ).

      WHEN 'ATTR2'                                            .
        l_column_header = ls_columns-r_column->get_header( )  .
        l_column_header->set_ddic_binding_field(
           if_salv_wd_c_column_settings=>ddic_bind_none )     .
      " Create Editable cell
        DATA: l_input_field1 TYPE REF TO cl_salv_wd_uie_input_field.

        CREATE OBJECT l_input_field1
          EXPORTING
            value_fieldname = ls_columns-id.
        ls_columns-r_column->set_cell_editor( l_input_field1 ) .
"binding the read only property
            l_input_field1->set_read_only_fieldname( 'EDITABLE' ).

Now when you bind your table with data, just pass abap_true to the editable field. So all yor rows would be read only initially.

Now in the onAction event of your button, pass abap_false to the editable field of your selected row..

Regards,

Radhika.

Former Member
0 Kudos

The code is getting messed up in the thread. Is the solution clear to you?

Radhika.

Edited by: Radhika Vadher on May 27, 2009 2:22 PM

Former Member
0 Kudos

Hi.

The solution is clear to me.

I just wanted to ask, what is the wd_this ->l_table, in the code that you gave me.

And for passing the value abap_false to the editable of the selected row, i will have to get the selected row index and for that index i have to use method set_attribute.

Correct me if i am thinking of a wrong approach.

Regards,

Prati.

Former Member
0 Kudos

Hi Prati,

Kindly ignore the statement wd_this ->l_table, i was using it in my case to store the reference.

You need not use that in your scenario.

Radhika.

Former Member
0 Kudos

Hi Radhika.

I had a few difficulties.

Let me tell u the scenario.

there are 2 views, main and display.

A summary ALV table is displayed in the MAIN view, with links to actions.

The DISPLAY view displays the corresponding details of the link clicked in an ALV table.

Binding the data to the ALV table in DISPLAY view is done in the MAIN view.

1. Now, the code that you gave me as a reference, where do i write it?

2. value of EDITABLE is to be set to abap_true. Can i set it as default value when i create the editable attribute?

Thanks for the constant support..

Regards,

Prati.

Former Member
0 Kudos

Hi,

In the MAIN view user can perform some actions and in DISPLAY view you wnat to display the data in ALV in read only mode.

When you bind the table to the ALV node use the Radhika's code to set the columns in the MAIN view.

In the Button handler(ON CHNAGE) write the code to make the table as editable.

What exaclty you wanted to do in DISPLAY view.

Regards,

Lekha.

Former Member
0 Kudos

Thanks!

I want the lead selected row to become editable. I need to get the index of the same and then set the EDITABLE attribute for that row to make it open for change.

Correct me if i am wrong.

I have written the code in the INIT method of the MAIN view.

When I run the application, its giving me Null reference access.

I am not able to figure out where exactly. Are there any specific points where I can check?

Regards,

Prati.

uday_gubbala2
Active Contributor
0 Kudos

Hi Prati,

Below is the complete coding for making the lead selected row as editable. You need to write this within the event handler method for the ALV event ON_LEAD_SELECT. Only then would you get the proper results.

Regards,

Uday

METHOD onactionleadselection.
  DATA: node_flights TYPE rref to if_wd_context_node,
        lo_el_flights TYPE REF TO if_wd_context_element.

  it_flights type if_componentcontroller=>elements_flights,
  ls_flights type if_componentcontroller=>element_flights,
  v_index type i.

  node_flights = wd_context->get_child_node( 'FLIGHTS' ).

  lo_el_flights = node_flights->get_element( ).

* get all declared attributes
* Here you will get the selected row values into structure

  lo_el_flights->get_static_attributes( IMPORTING static_attributes = ls_flights ).

  CALL METHOD lo_el_flights->get_index
    RECEIVING
      my_index = v_index.

uday_gubbala2
Active Contributor
0 Kudos
*now populate READONLY value of structure

  ls_flights-readonly = abap_false.

*Get the table data

  CALL METHOD node_flights->get_static_attributes_table
    IMPORTING
      table = it_flights.

*now modify the internal table

  MODIFY it_flights FROM ls_flights INDEX v_index TRANSPORTING readonly.

*Now bind the table to context

  CALL METHOD node_flights->bind_table
    EXPORTING
      new_items = it_flights.

*now the below logic is for to make the row input enable. Note: l_value is ALV table reference.
*Get the Column to which you want to make editable

  DATA: lr_input TYPE REF TO cl_salv_wd_uie_input_field,
        l_column1 TYPE REF TO cl_salv_wd_column,
        lt_columns TYPE salv_wd_t_column_ref,
        ls_columns TYPE salv_wd_s_column_ref,
        lt_node_info TYPE wdr_context_attr_info_map,
        ls_node_info TYPE wdr_context_attribute_info,
        lv_tabix TYPE sy-tabix,
        lr_info TYPE REF TO if_wd_context_node_info.


  TYPES:BEGIN OF ty_name,
 	 name TYPE string,
        END OF ty_name.

  DATA: lt_name TYPE TABLE OF ty_name,
        ls_name TYPE ty_name.

  lr_info = node_flights->get_node_info( ).
  lt_node_info = lr_info->get_attributes( ).

  LOOP AT lt_node_info INTO ls_node_info.
    	ls_name-name = ls_node_info-name.
    	APPEND ls_name TO lt_name.
  ENDLOOP.

  lt_columns = l_value->if_salv_wd_column_settings~get_columns( ).

  LOOP AT lt_columns INTO ls_columns.
    	 l_column1 = ls_columns-r_column.
    	 lv_tabix = sy-tabix.
    	 READ TABLE lt_name INTO ls_name INDEX lv_tabix.
    	 CREATE OBJECT lr_input1 EXPORTING value_fieldname = ls_name-name.
    	 l_column1->set_cell_editor( value = lr_input1 ).
*To make the first row is editable
    	 lr_input1->set_read_only_fieldname( value = 'READONLY' ).
  ENDLOOP.

* Set the table Editable
  l_value->if_salv_wd_table_settings~set_read_only( value = abap_false ).
* delete column
  l_value->if_slav_wd_column_settings~delete_column('READONLY').
ENDMETHOD.

"onActionLeadSelection

Former Member
0 Kudos

Thanks Uday.

Firstly, i m making the row editable as the result of a button click.

So,this code has to appear on the onAction event of the button.

But, that is fine.

What is bothering me is the error that i get upon running the application.

The scenario would be clear to u if u go through a few posts,above.

Regards,

Prati

Former Member
0 Kudos

hi.

U suggest me to write the entire code above in the onleadselect method?

Thanks,

Prati.

Former Member
0 Kudos

Hi,

1st step:Initialy when the ALV is loaded that time entire table should be Non-editable right.

Loop at..............

for all records READ_ONLY should be set as abap_true.

endloop.

2nd step: Write the code for ALV instantiation and the Setting of columns.

3rd Step: Based on the selection of the row write the code to make it as editable in the CHANGE button handler.

LOOP.........

if only for that index..

read_only = abap_false.

else.

read_only = abap_true.

endif.

endloop.

1 and 2nd can be written in the in the WDODINIT of the view/If you have any seleciton screen where you you have any buton which takes you to the MAIN view in that HANDLERfrom<<first screen>. there also you can write the code.

If you write the code in the ONLEADSELECT then it gets editable by default. As per you requirement you need to select the row and ckick the CHANGE button right. Then write the code in the button handler.

Cretae an handler for the ALV button(ONFUNCTION) and wrie the code there.

If this button is an ALV button then use the ONFUNCTION othersiwe normal button handler is enough thta is not part of ALV.

Is this clear.

Regards,

Lekha.

Former Member
0 Kudos

hi.

Thanks for clearing the approach.

When i want to set the read_only as abap_true, I have to loop at what? the table columns?

But the set_read_only is a method in table_settings and not for column_settings.

Thanks & regards,

Prati.

Former Member
0 Kudos

Hi,

Step 1:

Loop at lt_table into ls_table "Table that you want to bind to ALV

ls_table-read_only = abap_true....

modify table..............

endloop.

Step2: Get the column referenceds of the ALV and based on the column reference

(Check the UDAY's code)

Step3: ONCHANGE - get the column references and

crreate a object (lr_input) and for lr_input use the method set_read_only_fieldname.

(Check the UDAY's code)

Regards,

Lekha

Former Member
0 Kudos

Hi Prati,

I had similar issue while working with our tool development. What I did, instead of making a row editable, I displayed same fields in another view on click of ADD or CHANGE button, wherein the data will be inserted in field format. Something like this:

Value1 : Input field1

Value2 : Input field2

....... Go on to the number of fields in the row.

I set three buttons : BACK, SUBMIT, RESET.

Back you know how it works.

Submit, when I click submit, the single line data is sent to the program for further validations and then it is saved accordingly if it is proper, if not errors will be displayed on the same view.

Reset will clear all the values if the user wants to clear prior to the submit.

This is how I did, and it minimized my time and it is working fine.

Hope this could be useful.

Regards,

-Syed.

Edited by: wahid hussain syed on Jun 4, 2009 7:06 AM

uday_gubbala2
Active Contributor
0 Kudos

Hi Prati,

Seen that your thread regarding the editable ALV has been going on for ages. Could you please give out more details of what exactly you are trying to achieve? Is it something like you display an ALV and when you do a leadselection, you want that entire row to become as editable? Or is it something like you can select multiple rows & then when you press on a button you want to make all those rows as editable? Do let me know and I will pass on the entire working code for you.

Regards,

Uday

Former Member
0 Kudos

hi.

When i lead select in ALV, i click on the change button and the lead selected row(Single) becomes open for changes.

Thanks,

Prati.

Former Member
0 Kudos

Hi,

1 . 1st time when you show the table then try to make entire table as non-editable by following the earlier posts.

2. ONCHNAGE button handler, get the lead selection of the table and make that row editable.

In this you write the code -

lv_index = (get the lead selection index).

Loop at lt_table into ls_table.

if sy-tabix = lv_index.

read_only = abap_false.

else.

read_only = abap_true.

endif.

modify the table.

endloop.

Regards,

Lekha.

uday_gubbala2
Active Contributor
0 Kudos

Hi Prati,

This is simple. Suppose I am displaying data of SFLIGHT in my ALV. I have created a context node SFLIGHT at my component controller level. I have the attributes CARRID, CONNID, FLDATE & PRICE under it. In addition to these I have another attribute CELLS_ENABLED of type WDY_BOOLEAN & I have given it a default value of X. I would be using this attribute in my program to toggle the enable/disable states of my ALV row.

(I didnt get as to why you wanted to leadselect a row & then again press up on a button to make that row as enabled. You can directly make the leadselected row as enabled as anyway you are not planning to make more than 1 row as editable at a time. I am giving you the coding for making the leadselected row directly enabled. I would also later pass you the coding for making it enabled after leadselecting & pressing on a button.)

Below is the code from within my WDDOINIT:

METHOD wddoinit .
  DATA: wd_node TYPE REF TO if_wd_context_node,
        lt_sflight TYPE wd_this->elements_sflight,
        wa_sflight TYPE wd_this->element_sflight.

  wd_node = wd_context->get_child_node( name = 'SFLIGHT' ).
  SELECT carrid
         connid
         fldate
         price FROM sflight UP TO 20 ROWS INTO CORRESPONDING FIELDS OF TABLE lt_sflight.

  LOOP AT lt_sflight INTO wa_sflight.
    wa_sflight-cells_enabled = 'X'.
    MODIFY lt_sflight FROM wa_sflight TRANSPORTING cells_enabled.
  ENDLOOP.
  wd_node->bind_table( new_items = lt_sflight ).

**** Code for making all the ALV cells as input fields By default I make all of them as input fileds
**** But set them as readOnly. I would then make them as enabled upon leadSelection in ON_LEAD_SELECT
  DATA: l_ref_cmp_usage TYPE REF TO if_wd_component_usage.

*** Instantiate the used ALV component
  l_ref_cmp_usage =   wd_this->wd_cpuse_alv( ).
  IF l_ref_cmp_usage->has_active_component( ) IS INITIAL.
    l_ref_cmp_usage->create_component( ).
  ENDIF.

  DATA: l_ref_interfacecontroller TYPE REF TO iwci_salv_wd_table,
        lr_column_settings TYPE REF TO if_salv_wd_column_settings,
        lt_columns         TYPE        salv_wd_t_column_ref,
        lr_input1           TYPE REF TO cl_salv_wd_uie_input_field,
        l_value TYPE REF TO cl_salv_wd_config_table.

  FIELD-SYMBOLS <fs_column> LIKE LINE OF lt_columns.

  l_ref_interfacecontroller =   wd_this->wd_cpifc_alv( ).

*** Get reference to the model
  l_value = l_ref_interfacecontroller->get_model( ).

  l_value->if_salv_wd_table_settings~set_read_only( abap_false ).

  lr_column_settings ?= l_value.
*** Get the reference to all the columns of my ALV
  lt_columns = lr_column_settings->get_columns( ).

*** Loop through all the columns and make their cell editors as input fields
  LOOP AT lt_columns ASSIGNING <fs_column>.
*** Create an instance of an input field
    CREATE OBJECT lr_input1
      EXPORTING
        value_fieldname = <fs_column>-id.
*** Am binding the readOnly state of the created input field to my boolean attribute CELLS_ENABLED
    lr_input1->set_read_only_fieldname( value = 'CELLS_ENABLED' ).
*** Set the created input field as the cell editor for the current column i., <fs_column>-id
    <fs_column>-r_column->set_cell_editor( lr_input1 ).
***
  ENDLOOP.
*** The boolean attribute CELLS_ENABLED which we have created under SFLIGHT will also
*** get displayed by default. So delete that particular column from the ALV
  l_value->if_salv_wd_column_settings~delete_column( id = 'CELLS_ENABLED' ).
ENDMETHOD.

uday_gubbala2
Active Contributor
0 Kudos

Next i create an eventhandler method by name ON_LEAD_SELECT for the event ON_LEAD_SELECT of the ALV. So whenever the user does a lead selection this method would get triggered. Within this method I would obtain the index of the row selected and change its readonly status to false.

Below is the coding from my eventhandler method ON_LEAD_SELECT:

METHOD on_lead_select .
  DATA: wa_modified_data TYPE salv_wd_s_table_mod_cell,
        lv_index TYPE i VALUE 0,
        lv_date TYPE date,
        wd_node TYPE REF TO if_wd_context_node,
        lt_sflight TYPE wd_this->elements_sflight,
        wa_sflight TYPE wd_this->element_sflight.

  wd_node = wd_context->get_child_node( name = 'SFLIGHT' ).

*** Fetch all the data currently being displayed in the ALV
  CALL METHOD wd_node->get_static_attributes_table
    EXPORTING
      from  = 1
      to    = 2147483647
    IMPORTING
      table = lt_sflight.

*** This code below is to make any previously leadselected row as disabled
*** when the user does a leadselection again. So at any time only 1 row would be enabled
  READ TABLE lt_sflight INTO wa_sflight WITH KEY cells_enabled = ''.
  IF sy-subrc = 0.
    wa_sflight-cells_enabled = 'X'.
    MODIFY lt_sflight FROM wa_sflight INDEX sy-tabix TRANSPORTING cells_enabled.
  ENDIF.

*** Obtain the index of the row currently lead selected
  lv_index = r_param->index.

*** Fetch corresponding rows information into workarea
  READ TABLE lt_sflight INTO wa_sflight INDEX lv_index.

*** Modify our flag variable so as to make the rows cells as enabled
  wa_sflight-cells_enabled = ''.
  MODIFY lt_sflight FROM wa_sflight INDEX lv_index TRANSPORTING cells_enabled.

*** Finally bind the ALV with this new modified internal table
  wd_node->bind_table( new_items = lt_sflight ).
ENDMETHOD.

Regards,

Uday

uday_gubbala2
Active Contributor
0 Kudos

Hi Prati,

The code format is getting all messed up so I have also mailed you a copy of the same. Hope it helps resolve your problem.

Regards,

Uday

uday_gubbala2
Active Contributor
0 Kudos

Hi Prati,

In my earlier post I had given you the code by which you could directly make the leadselected row as editable. Now below is the coding where in you leadselect a row and then need to press up on a button for making it as editable.

Most of the coding remains the same. The same node & context attributes apply even to this coding. The main difference lies in the fact that in the earlier approach you were obtaining the index of the row selected by the user using the parameter (R_PARAM) being passed by the framework to the eventhandler for ON_LEAD_SELECT.

R_PARAM->INDEX

In this case you would be obtaining the row index by using the method of IF_WD_CONTEXT_NODE.

lv_index = wd_node->get_lead_selection_index( ).

Below is the coding within my buttons action handler method:

METHOD onactionedit_row .
  DATA: wd_node TYPE REF TO if_wd_context_node,
        lv_index TYPE i VALUE 0,
        lt_sflight TYPE wd_this->elements_sflight,
        wa_sflight TYPE wd_this->element_sflight.

  wd_node = wd_context->get_child_node( name = 'SFLIGHT' ).

  lv_index = wd_node->get_lead_selection_index( ).

*** Fetch all the data currently being displayed in the ALV
  CALL METHOD wd_node->get_static_attributes_table
    EXPORTING
      from  = 1
      to    = 2147483647
    IMPORTING
      table = lt_sflight.

*** This code below is to make any previously leadselected row as disabled
*** when the user does a leadselection again. So at any time only 1 row would be enabled
  READ TABLE lt_sflight INTO wa_sflight WITH KEY cells_enabled = ''.
  IF sy-subrc = 0.
    wa_sflight-cells_enabled = 'X'.
    MODIFY lt_sflight FROM wa_sflight INDEX sy-tabix TRANSPORTING cells_enabled.
  ENDIF.

*** Fetch corresponding rows information into workarea
  READ TABLE lt_sflight INTO wa_sflight INDEX lv_index.

*** Modify our flag variable so as to make the rows cells as enabled
  wa_sflight-cells_enabled = ''.
  MODIFY lt_sflight FROM wa_sflight INDEX lv_index TRANSPORTING cells_enabled.

*** Finally bind the ALV with this new modified internal table
  wd_node->bind_table( new_items = lt_sflight ).
ENDMETHOD.

Regards,

Uday

Former Member
0 Kudos

Hi...

Thanks a tons.

It was perfect.

I was going wrong in regards to the r_param and was missing out a few things.

Thanks a lot, my concept regarding editing the row and even the approach got cleared in the right sense.

Regards,

Prati.

Answers (2)

Answers (2)

former_member226203
Active Contributor
0 Kudos

u need to use an input field as cell editor for the column which should

be editable.

DATA: it_edit TYPE REF TO if_salv_wd_column_settings,

v_input_field TYPE REF TO cl_salv_wd_uie_input_field.

it_edit ?= v_value.

it_column = it_edit->get_column( 'field' ).

CREATE OBJECT v_input_field EXPORTING value_fieldname = 'FIELD'.

it_column->set_cell_editor( v_input_field ).

uday_gubbala2
Active Contributor
0 Kudos

Hi Prati,

Kindly go through Suman's suggestions in this [thread|;.

Regards,

Uday