cancel
Showing results for 
Search instead for 
Did you mean: 

[onAction] Retrieve the attribute value from ID

guillaume-hrc
Active Contributor
0 Kudos

Hi,

I have many input field for dates in my view.

I would like to have only 1 onEnter event handler.

For this, I pass the ID of the UI element and I would like to retrieve the actual bound attribute from the context.

Could you please tell me how to go all the way from the ID to the bound attribute ?

Thanks in advance.

Best regards,

Guillaume

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

Thomas,

I see this posting was over a year old. I search the support portal for a correction to this problem, but was unable to find a solution. Could you shed some light on the situation?

Best Regards,

Greg Bush

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

>

> Thomas,

>

> I see this posting was over a year old. I search the support portal for a correction to this problem, but was unable to find a solution. Could you shed some light on the situation?

>

> Best Regards,

> Greg Bush

I don't have anything else to add. I provided work arounds. This isn't a bug as much as just missing functionality, so there wouldn't be a patch for it. At best it would be enhanced in 7.02, but that doesn't seem to be the case.

Former Member
0 Kudos

Thanks, for your quick response. I appreciate the information.

Best Regards,

Greg

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

The onEnter event has two parameters that can be exposed (just hit the Parameters for UI action button inside the method editor). They are CONTEXT_ELEMENT and ID. The context element will give you the exact source element. You need only to call the GET_ATTRIBUTE method and pass in the ID to the name parameter.

guillaume-hrc
Active Contributor
0 Kudos

Hi,

Thanks for your answer, Thomas.

It makes me think that I have a problem before this one!

Indeed, the CONTEXT parameter is always initial (it is a reference, it cannot be changed to value, anyway).

Any idea where it comes from ?

Many thanks in advance.

Best regards,

Guillaume

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

CONTEXT_ELEMENT element should get filled automatically. Did you add the parameter manually or have it added via the copy UI parameters option?

alejandro_bindi
Active Contributor
0 Kudos

Thomas, I think I get what Guillaume is referring to as I had the same problem before. I did a quick test now to confirm it:

I have defined this context structure:


CONTEXT
  - ATRIB1
  - ATRIB2
  - TABLE (0..n)
    - ATRIB3
    - ATRIB4

Then I defined a layout with two input fields and a table with two columns (each with one additional input field): INPUT1 bound to ATRIB1, INPUT2 bound to ATRIB2, Table Col1 bound to ATRIB3 and TC2 bound to ATRIB4.

Lastly, I created four actions, binding them each to a different inputfield. For INPUT2 and Table column 2 actions, I marked the UI parameters button you mention.

I have two comments on this:

- For the ones marked with UI parameters, only an ID parameter is available (which receives the name of the inputfield on which the action was triggered). There's no option for transfering the context element explicitly.

- As you know, this parameters are also received implicitly inside the WDEVENT object reference in the event handler. Well, for the references received for the INPUT1 and 2, the CONTEXT_ELEMENT reference is initial. So, to get the element, normal node navigation is required. But, for the objects received in the case of table columns, the CONTEXT_ELEMENT reference is indeed received. I think this is the problem that Guillaume is referring to.

Could this have something to do with the cardinality of the node? Is this the normal behaviour?

I'm on SP12 just in case.

Thanks and regards

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

You are correct. The CONTEXT_ELEMENT parameter is initial when the onEnter is triggered from a non-table UI element. I suppose I never needed the CONTENT_ELEMENT in the standalone case. I tested it in 7.0 EnhP2 and that is still the case. However I have to admit, that this seems a bit counter to the theory that coding in events should be against the context and not the UI elements - especially since the ID parameter then returns the UI element ID. Defintely room for improvement on our part.

So here is a workaround that keeps things pretty generic. First in your WDDOMODIFYVIEW, you will need to capture a reference to the the IF_WD_VIEW object and store in a VIEW attribute for later use:

IF first_time = abap_true.
    wd_this->l_view = view.
  ENDIF.

Now in your onEnter event handler you can place the following code. It will query the UI element to find its binding path and then use the binding path to lookup the context attribute value. Just be careful becuse the value is returned as TYPE REF TO DATA. You will need to cast it safely into a more specific data type.

DATA lr_input TYPE REF TO cl_wdr_view_element.
  lr_input ?= wd_this->l_view->get_element( id ).
  DATA binding_path TYPE string.
  binding_path =  lr_input->bound__primary_property( ).
  data lv_value type ref to data.
  field-SYMBOLS <Wa_data> type csequence.
  lv_value ?= wd_context->path_get_attribute( binding_path ).
  ASSIGN lv_value->* to <wa_data>.

alejandro_bindi
Active Contributor
0 Kudos

That is a nice workaround, but only if you want to avoid coding to an UI element instead of the context, as you said. Otherwise I suppose it's not so safe to store a reference to the view to be used outside of WDDOMODIFYVIEW, I thought it was not a good practice. Just navigating the context as usual to get the data (assuming the binding will not change) seems safer than this to me (plus it requires less code).

Don't get me wrong, I know you're trying as always to give us a solution (and it works), but I hope this gets improved by SAP in the future to receive the context element reference in any case, that would be the best.

Regards

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

>I thought it was not a good practice

That is true in general. You should absolutely never use this approach to modify the view. That can lead to short dumps. That aspect aside (since that isn't the case here), the general rule is that it would be against MVC to code against the view in such a way. Howeve in this case we are pretty much forced to violate MVC because of the limited parameters that the framework passes into the action event handler. Therefore I am just working with what I am given. And yes I will speak to the WD Foundation team about this item. If nothing else, the code that I showed should be placed within the framework and the results passed into the action to avoid such a MVC violation.

The other option of course is to build some sort of CASE statement that maps the UI element ID to your context attribute and looks up via the context without the dynamic binding string lookup. This probably is easier, but personally I cringe at the thought of having UI element level logic in my coding.

alejandro_bindi
Active Contributor
0 Kudos

Very clear response, I had to write that kind of CASE statement for SoldTo / ShipTo inputfields (which needed similar coding).

Something like this (not nice indeed):


METHOD onactionenter_partner_num .

  CONSTANTS:
    lc_soldto_uiid   TYPE string VALUE 'INP_SOLDTO',
    lc_shipto_uiid   TYPE string VALUE 'INP_SHIPTO'.

  DATA: lr_elem       TYPE REF TO if_wd_context_element,
        ls_adrc       type wd_assist->ty_adrc,
        ls_data       TYPE wd_this->element_header.

* Get partner ID entered and update partner info
  lr_elem = wd_context->path_get_element( path = wd_this->wdctx_header ).
  lr_elem->get_static_attributes(
    IMPORTING
      static_attributes = ls_data
  ).

  CASE id.
    WHEN lc_soldto_uiid.
*     Update Sold-To info
      ls_adrc = wd_assist->get_partner_info( ls_data-soldto ).
      ls_data-soldto_name1 = ls_adrc-name1.
      ls_data-soldto_post_code1 = ls_adrc-post_code1.

    WHEN lc_shipto_uiid.
*     Update Ship-To info
      ls_adrc = wd_assist->get_partner_info( ls_data-shipto ).
      ls_data-shipto_name1 = ls_adrc-name1.
      ls_data-shipto_post_code1 = ls_adrc-post_code1.
  ENDCASE.
  lr_elem->set_static_attributes( ls_data ).

ENDMETHOD.

Nevertheless I ended up splitting this into two separate methods later (just to avoid the case on the Inputfield names).

So there you go Guillaume, these are the options so far. If you just need the attribute data and keeping in mind it's a workaround, Thomas's coding is preferable, specially if you have a lot of Inputfields.

Regards

guillaume-hrc
Active Contributor
0 Kudos

Hi,

Waouh... what a detailed answer guys!

Thanks a LOT for this !!

Now, I have many options to sort this out.

Just one thought from a WDA beginner, what about naming the UI element with the exact same name as the context attribute... this way, we would be able to use the ID from the UI element to get the corresponding attribute.

-> this is prone to errors but a cheap solution nonetheless

Thank again for your time.

Best regards,

Guillaume