on 10-09-2008 6:03 PM
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
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
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
>
> 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.
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.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
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
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>.
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
>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.
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
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
User | Count |
---|---|
101 | |
13 | |
13 | |
11 | |
11 | |
7 | |
6 | |
5 | |
4 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.