cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically add and embed WD components without predefining an interface

Former Member
0 Kudos

Hey Community,

I have the following problem:

I have a view with many ViewContainers in it. When I start the programm I want to decide dynamically which components should be used and displayed in these containers. Bbefore I start the programm I do not know which components I am going to load.

I already saw the possibility to predefine an interface for all components but in my case there would be no common interface. Beside that I tried it with the Interface IF_WD_VIEW_CONTROLLER and its method Prepare_dynamic_navigation. This method looks very similar, but I don' want a navigation, I just want to display it in an existing view.

So my question:

Is it possible to add WD components and embed their views to existing view cointainers during runtime?

Thank you for your help!

Accepted Solutions (1)

Accepted Solutions (1)

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

do_dynamic_navigation does what you want. I use this in a demo test framework where I load many different WD Compoennts with a static menu frame around them. When you perform the dynamic navigation and supply a target_embeding_postion, you won't before total page navigation, but instead only swap the component embedded within the View Container you specify in this parameter:

l_api_main = wd_this->wd_get_api( ).
    try.
        l_api_main->do_dynamic_navigation(
            source_window_name        = 'MAIN'
            source_vusage_name        = 'MAIN_VIEW_USAGE_1'
            source_plug_name          = source_plug_name
            target_view_name          = target_view_name
            target_plug_name          = 'DEFAULT'
            target_embedding_position = 'MAIN_VIEW/VIEW_CONTAINER').
        .
      catch cx_wd_runtime_repository .
        raise exception type cx_wdr_rt_exception.
    endtry.

Former Member
0 Kudos

Hi Thomas,

thanks for your answer!

I understand how you use this method. But can I also use this method if I want to load more than one Component dynamically?

For example:

I start a WD which provides a kind of frame and some static buttons. On this Component I have 5 ViewContainers.

When I start the Component I call a method (for example) which provides me five names of other Web Dynpro Components! Now I want to dynamically define (as a used component) and embed all five WD components at once on my screen!

I am not sure how I could use this method to realise this!

By the way I started working with WD 2 weeks ago and I used your video tutorials amongst others. I really appreciate your work!

Br

Martin

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

>I am not sure how I could use this method to realise this!

Have you tried call this method 5 times with 5 different target container specifications?

Former Member
0 Kudos

I tried, but it doesn't work. May be you could help me out with the right syntax.

I have my Consumer Component which is calles ZTP_TRAVEL. There I have a window W_MAIN and my "frame" view V_MAIN. On this view I have five containers called Container1, Container2, ....

There I want to embed a WD component which is called ZTP_DATES with W_MAIN and V_VIEW.

For test purposes I created a button on my "frame" View which calls a method, and in this method I tried to call this method with no effect.

TIA

Martin

thomas_jung
Developer Advocate
Developer Advocate
0 Kudos

So it doesn't work with even one call or only doesn't work when you call it multiple times?

I can assure you the method does work with one call. Be sure you are specifying unique plug names and that the target container is specified correctly. Perhaps you could post your source code here. Its difficult to troubleshoot without seeing it.

ChrisPaine
Active Contributor
0 Kudos

Have a look at the MAIN view of the FPM_GAF_COMPONENT in the WDDOINIT method. It creates a component usage and embeds the used component view into current view.


  DATA: lr_usage_group TYPE REF TO if_wd_component_usage_group.
  DATA: lr_component TYPE REF TO if_wd_component.

  lr_component = wd_comp_controller->wd_get_api( ).
  lr_usage_group = lr_component->create_cmp_usage_group(
                       name            = 'MESSAGE_AREA_USAGES'
                       used_component  = 'FPM_MESSAGE_MANAGER' ).
  wd_this->mo_message_area_usage = lr_usage_group->add_component_usage( 'MESSAGE_AREA_USAGE' ).
  wd_this->mo_message_area_usage->create_component( 'FPM_MESSAGE_MANAGER' ).

  DATA: lr_view_controller_api TYPE REF TO if_wd_view_controller.

  lr_view_controller_api = wd_this->wd_get_api( ).
  lr_view_controller_api->prepare_dynamic_navigation(
                  source_window_name          = 'FPM_WINDOW'
                  source_vusage_name          = 'MAIN_USAGE_1'
                  source_plug_name            = 'OUT'
                  target_component_name       = 'FPM_MESSAGE_MANAGER'
                  target_component_usage      = 'MESSAGE_AREA_USAGE'
                  target_view_name            = 'MESSAGES'
                  target_plug_name            = 'DEFAULT'
                  target_embedding_position   = 'MAIN/VC_MESSAGE_AREA' ).


  wd_this->fire_out_plg( ).

I can't see why you couldn't repeat this multiple times!

given that what you are asking to do is what the FPM does - it certainly should be possible!

Hope this code snippit helps.

Former Member
0 Kudos

Hey Chris,

it works. I could adapt the syntax of this example to my programm. Thank you very much for this helpful hint!

In addition. If I perform the code twice and chnage the usage group I can use this code for more than one component!

Thanks to all contributors!

Best regards

Martin

Answers (1)

Answers (1)

Former Member
0 Kudos

hi martin,

Based on the scenario , you can create any UI element dynamically using standard classes.

You can also create context nodes and attributes and bind these dynamically created elements to them.

For eg,

cl_wd_input_field is a class using which you can create a new input field as shown below.

CALL METHOD cl_wd_input_field=>new_input_field

EXPORTING

bind_value = lv_ip_attrname

width = '250'

id = lv_input_field_name

RECEIVING

control = lo_input_field.

Here lv_ip_attrname is the name of the attribute to which the input field's value id bound.

You can add the following code in the WDOMODIFY method of the view.

I hope this is what you had asked for.Hope it helps.

Cheers,

Aditya.

Edited by: Aditya Karanth on Aug 31, 2010 1:01 PM

Former Member
0 Kudos

Hey Aditya Karanth,

thank you for your answer. Unfortunately this was not what I was looking for. I am not talking about UI elements, I am talking about whole WD components. Normally if I would use the static way I would do the following steps:

Define the Used Component in the Consumer Component.

Embed a view from the Used Component to a ViewContainer in my Consumer Component.

Now, I was wondering if I could perform these steps dynamically. In NET311 I read that this is possible if I use a common interface but this is not possible in my application.

Best regards

Martin