cancel
Showing results for 
Search instead for 
Did you mean: 

Custom view - managing EDIT/DISPLAY mode

matteo_montalto
Contributor
0 Kudos

Hi Experts,

shortly; i made a custom WDC in order to use it in a standard SRM WD Application (specifically, a new FPM tab in a document's overview).

The view is very basilar, as it has a lot of input fields  and some checkboxes bound on a context node's attributes.

Now... I basically have to manage the FPM EDIT and DISPLAY mode in the way standard does, so that:

- when in DISPLAY mode, all the input fields should be rendered as "read only" (but enabled);

- when in EDIT mode, the inputfields should behave w.r.t. enable property defined in the WD view.

An obvious way to proceed is to put a sketch of code like that in WDDOMODIFYVIEW:

   lo_task_factory = /sapsrm/cl_ch_wd_taskcont_fact=>get_instance( ).

   lr_mo_task_container = lo_task_factory->get_task_container( ).

   lr_mo_task_container->get_transaction_mode( IMPORTING ev_pdo_trans_mode = lv_trans_mode ).

   IF lv_trans_mode EQ 'DISPLAY'.

     DATA: elemcb TYPE REF TO CL_WD_CHECKBOX,

                elemif TYPE REF TO CL_WD_INPUT_FIELD.

     elemcb ?= view->get_element( 'PROD_ENG_CBOX' ).

     elemcb->set_read_only( abap_false ).

and similar for inputfields. Obviously, I have to manage the ELSE fork setting the read_only property to abap_true.

This approach is quite a waste of code as I have dozens of inputfields, so I'm asking: isn't there a facility/standard class-method to obtain such a result without having to process any field of the view?

By the way.... these Inputfields and checkboxes are stored in a GROUP element (CL_WD_GROUP)... unfortunately, the GROUP element doesn't have the READ_ONLY property 😞

Accepted Solutions (1)

Accepted Solutions (1)

Lukas_Weigelt
Active Contributor
0 Kudos

Hi Matteo,

I'm not aware of any standard class providing such a functionality; but you might want to wait for others to post, maybe I'm mistaken here. What you could do though, to keep things simple and short, would be some generic coding like this (pseudo code):

field-symbols: <ls_children_puffer> type ref to cl_wd_uielement.

lo_el_group ?= view->get_element( '<xyz>' ).

lt_children = lo_el_group->get_children( )

Loop at lt_children assigning <ls_children_puffer>.

TRY

     <ls_children_puffer>->set_read_only( abap_false ).

     CATCH cx_root.

ENDTRY.

Endloop.

In case you have more nested containers etc. you could write two recursive methods climbing/polling down the UI-tree (one for containers, groups, tables row-repeaters, etc. polling children and one for flat ui-elements to set the properties). That way you can avoid casting down each and every element with a dedicated ID separately.

Cheers, Lukas

matteo_montalto
Contributor
0 Kudos

Hi Lukas and thanks for your help,

that's an interesting option.... however, CL_WD_UIELEMENT does not have SET_READ_ONLY method, which is instead proper of specific UI elements like checkboxes or inputfield...
I'm gonna give it a try anyway, try/catch clause should prevent horrible dumps 😛

Lukas_Weigelt
Active Contributor
0 Kudos

Hey Matteo,

yes, true, in that case you need to code it even more generic. Let me fetch a snippet I wrote somewhere for generic access key activation.. and here it is:

LOOP AT me->it_prot_element_list INTO ls_prot_element_list.

     UNASSIGN <generic_buffer>. " sicher ist sicher

     CREATE DATA lo_buffer TYPE REF TO (ls_prot_element_list-zz_type).

     ASSIGN lo_buffer->* TO <generic_buffer>.

     IF <generic_buffer> IS ASSIGNED.

       <generic_buffer> ?= lo_view->get_element( id = ls_prot_element_list-zz_id ).

       lo_object_buffer ?= <generic_buffer>. " muss sein, weil <generic_buffer> zur Designzeit noch nicht weiß, dass es mal eine steile Karriere als Objekt haben wird! \o/

     ENDIF.

     IF lo_object_buffer IS NOT INITIAL. " sonst Nullpointer möglich, wenn in der expliziten Übergabe an die Hauptmethode eine ID übergeben wird, die es nicht gibt

       CALL METHOD lo_object_buffer->(lc_acc_method) EXPORTING value = abap_true.

     ENDIF.

ENDLOOP.

So, basically I have a list of UI-Elements somewhere that I cast against the UI-tree and try to execute a certain method for the element that comes back from the casting. For you, the actually relevant part would be the "lo_object_buffer" which is of generic "TYPE REF TO object". Then I execute a method that I hope is contained by the object by that point of time (hence the constant in brackets), this way you don't get a syntax error when compiling. Might wanna TRY CATCH around it additionally (in my above example snippet I already caught possible exceptions elsewhere, that's why there's no try-catch phrase there) to avoid 'them horrible dumps'

Cheers, Lukas

EDIT: P.S. Still no syntax high-lighting for ABAP :´<

Answers (2)

Answers (2)

ramakrishnappa
Active Contributor
0 Kudos

Hi Matteo,

I would suggest to go for custom table where the view fields,  properties are maintained per mode ( .ie. change, create, display )

Based on the table entries, we can set the properties of view ui elements using VIEW object reference.

So, every thing is controlled by custom table entries. Event you can maintain the user settings.

Hope this helps you.

Regards,

Rama

amy_king
Active Contributor
0 Kudos

Hi Matteo,

I handle this in my custom components by having a context attribute, readonly of type wdy_boolean which I set to true or false as needed. I bind the readOnly property of all inputs to this context attribute. In your example, you could set the readonly context attribute according to the value of lv_trans_mode.

Cheers,

Amy

matteo_montalto
Contributor
0 Kudos

Hi Amy,

this is for sure the cleanest way to do it... However, this leads me to another issue....

If I bind each checkbox/inputfield READ_ONLY property to the same attribute, then I will have to write code to implement specific clauses, for example:

"if user has a specific role, then inputfield X and checkbox Y should be editable while other inputfields and checkboxes should be read-only"

In such a case I would have to manage individual READ_ONLY property; in a certain way, I would have to override the property binding on particular situations.

I could easily solve saying that:

- DISPLAY/EDIT Mode --> deals with READ_ONLY property

- EDITABLE ui element --> deals with ENABLE property

But... doing so will render as greyish all the fields which are not editable, and customer don't like that much

amy_king
Active Contributor
0 Kudos

Hi Matteo,

Good point, if a user's role may override the display/edit mode for certain fields then using a context binding could get complicated. Lukas' approach has the added benefits that you would have all of the logic for whether fields are editable or not in one place instead of spread across multiple context attributes, and if a new field were ever added in the future, the generic processing would capture the new field automatically.

Cheers,
Amy