cancel
Showing results for 
Search instead for 
Did you mean: 

dynamically change embedded interface view in window

Former Member
0 Kudos

I have a Maincomponent M which embedds in its Mainwindow an interface view V_L from a component definition interface cid L. CID L handles the layout with several views and has two at runtime chosen variants (= cid_L-implementating components ) L1 and L2.

now my wd-application starts e.g. with layout L1 and I want to switch at runtime via a button or an event to L2. how can I achieve this?

Because M embedds in its window V_L (which can be filled by L1 or L2) I tried to delete the component in the usage of L1 and create the new component for showing L2.

but this doesn´t work. should I change some navigation links dynamically? because I thought when I create component L2 the interfaceview V_L is filled and I it´s automatically shown in its higher-ranking Mainwindow from M which embedds V_L.

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

I mark this thread as answered and open a new posting with the topic "dynamically created navigation links".

Former Member
0 Kudos

Hi Thorsten.

You have to create the navigations dynamically.

Check the help out:

http://help.sap.com/saphelp_nw2004s/helpdata/en/4c/60154219fce12ce10000000a1550b0/frameset.htm

Also search the forum cause there are some threads regarding this topic.

Cheers,

Sascha

Message was edited by:

Sascha Dingeldey

Former Member
0 Kudos

thanks sascha,

I did set dynamical navigation links in the past but I used the same implementating component (e. g. L1) but now I switch the layoutcomponent at runtime to a different L-component.

the navigation links in Main_Window which embedd V_L from cid_L are set at designtime and so it should work or whats my error in reasoning?

Former Member
0 Kudos

If you use the same outbound plug all the time there will be multiple navigations created and stored. So if you fire that outbound plug all corresponding navigations are triggered and the very first created will be the target.

if you have defined outbound plugs at design time and the navigations are created at runtime only once for each outbound it should work as expected. But if you want to change the layout component m,ultiple times you have to create the outbounds and navigations dynamically. So for each possible navigation there must be one dynamic outbound with navigation.

in my case i have a menu component which decides at runtime which links to show. So I never know how much outbound plugs i need to load the other components. when a link is clicked i check whether i already created a navigation for this link anf if not i call prepare_dynamic_navigation. Then i store the name of the outbound for this navigation (to check when the link is clicked again) and fire the newly created outbound:

l_view_controller_api->fire_plug(

exporting

plug_name = lv_outplug

).

Hope this is not to confusing.

Cheers,

Sascha

Former Member
0 Kudos

ok sascha,

perhabs I am a little bit overworked but I have little problems with this problem context now.

I am allways using the same inbound-plug in V_L (e. g. FROM_M, defined in CID_L) and it should be work with every component of cid_L because I got only one active component (L1 or L2) at runtime which got this inboundplug FROM_M and the name is fixed in the cid_L.

the navigation for L1 is fixed at designtime so switching from L2 to L1 should work.

is it still required to create the outbounds and navigation dynamical under these circumstances? or should I do something like overwrite or renew the navigation....

>>in my case i have a menu component which decides at runtime which links to show. >>So I never know how much outbound plugs i need to load the other components. >>when a link is clicked i check whether i already created a navigation for this link anf if >>not i call prepare_dynamic_navigation. Then i store the name of the outbound for this >>navigation (to check when the link is clicked again) and fire the newly created >>outbound:

can you please tell me (or show me a code snippet) how you can test if a navigation link still exist?

and with storing the name of the outbound for for this navigation you mean

_view_controller_api->fire_plug(
exporting
plug_name = lv_outplug
).

?

EDIT: I got an idea what may cause my problem... when I start my application with L2 a navigationlink is dynamically created and when I switch to L1 these created navigation link still exist and should be replaced by the correct one of L1. so I have to remove the unnecessary navigation link but how?

another way would be starting with L1 where all navigations are fixed at designtime and switch to L2. but there I have to renew and replace the navigation links too.

Because the inbound plug is defined in CID_L and the name is equal in L1 and L2 I don´t have to create it dynamically or am I wrong?

Message was edited by:

Thorsten Winter

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

Hi Thorsten.

Is your scenarion as follows.

You define an outbound plug in your main (e.g. 'OUT') at design time.

Then you start the application and you create a dynmic navigation using OUT

to L1 and embedd L1 in M this way.

Then you click a button and create again a dynamic navigation using OUT as outbound to L2 and embedd L2 in M?

If so you create 2 navigations which will be triggered when you fire OUT.

You can test this by setting the break point on the fire method. Somehow you will come to a point where you will see a table which stores the navigations and should contain 2.

I have a table with authorisation which contains all necessary data for the navigation to a corresponding component. I use the authoridation ID as name for the outbound which have to be created dynamically. And I use a Hashtable to store the value. This is of the type CL_C2S_SAPI_HASHTABLE. I create the object as attribute in view controller. Then each time a link is clicked I check whether the hashtable already contains a value for this authorisation. If not I call

prepare_dynamic_navigation and use the ID as outbound. Afterwards I store it in th hashtable.



lv_outplug = wd_this->outbound_plugs->getvalue( lv_auth ).

*   the navigation to the specified auth is performed
*   for the first time and have to be created.
    if lv_outplug is initial.
      lv_outplug = lv_auth.
      try.
          l_view_controller_api->PREPARE_DYNAMIC_NAVIGATION(
              source_window_name          = 'W_MAIN'
              source_vusage_name          = 'V_MAIN_USAGE_1'
              source_plug_name            = lv_outplug
              target_component_name       = lv_comp
              target_component_usage      = 'USED_COMPONENT'
              target_view_name            = 'W_MAIN'
              target_plug_name            = lv_plug
              target_embedding_position   = 'V_MAIN/UI_COMP_CONTAINER' ).

*         save outbound_plug for later usage.
          wd_this->outbound_plugs->setvalue(
           exporting
             name = lv_auth
             value = lv_outplug
          ).

        catch cx_wd_runtime_repository into lr_exception.
          data s type string.
          s = lr_exception->get_text( ).
          raise exception type cx_wdr_rt_exception.
      endtry.
    endif.
    
    [...]
   
    l_view_controller_api->fire_plug(
     exporting
       plug_name = lv_outplug
     ).


Hope this helps.

Cheers,

Sascha

Former Member
0 Kudos

thanks sascha for your answer again...

I have some remarks...please correct me if I am wrong.

my problem is that when I switch the layout e. g. from L2 to L1 two navigation links exist and one of them is not necessary and is responsible for my fault.

so you create the hashtable outbound_plugs where you put navigation links and can access to these navigation links via the outboundplugname which you created dynamical, right? or what is your "lv_auth" ?

in my scenario I have defined one outboundplugname from M and one inboundplugname in the cid_l at designtime.

so I can´t put these navigation links in the hashtable via the outboundplugname because I only got one outboundplugname?

Im think the central point is that you please explain me your stringparameter "lv_auth".

Former Member
0 Kudos

lv_auth is the ID auf the authorisation assigned to the link.

Is used to identify which component is connected with the link and which inbound plug (lv_plug) of this components interface view should be navigated to.

The problem is that you use the same plug for all navigations. The system stores all navigations in order to neo recreate them all the time. So you must find a way to remember which dynamic navigation you already have craeted. Also you must find a way how to store the names of the outbounds to use for each navigation because when I remember correctly you do not klnow how much different implementations of CID will be used.

In my case I can easily add a new component to my application by customizing my authorisation table. I just need to add a new authorisation and the main component handles the rest.

Cheers,

Sascha

Former Member
0 Kudos

>>The problem is that you use the same plug for all navigations. The system stores all navigations in order to neo recreate them all the time. So you must find a way to remember which dynamic navigation you >>already have craeted. Also you must find a way how to store the names of the outbounds to use for each navigation because when I remember correctly you do not klnow how much different implementations of >>CID will be used.

if I understand it the navigation link is stored or referenced to a plug-combination.

so my problem is that 2 navigation links exist at runtime to my combination outboundplug from m to inboundplug cid L.

ok one solution could be creating all outboundplugs from M to L and the links dynamically with different outboundplugnames and the inboundplug in cid L is still defined at designtime with one name?

is it perhabs possible to do my way and define both plugs (outbound M and inbound cid L) at designtime with one name and remove the last unnecessary link before creating the new navigation link?

or do you have a hint for me?

perhabs the only solution will be to create all inboundplugs at cid_L and outboundplugs from M dynamically and handle the navigationlinks via tables like your example code? but I think this will interrupt the advantage of my cid with its defined plugs...

>>lv_auth is the ID auf the authorisation assigned to the link.

>>Is used to identify which component is connected with >>the link and which inbound plug (lv_plug) of this >>components interface view should be navigated to.

so you have different inboundplugnames for each navigation link which you connect in your hashtable to your navigation links?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

Could it be my solution to create outboundplugs in M for each link to L1, L2, Lx at runtime and store the navigationlinks in a hashtable and access the navigationlink via the outboundplugname which contains the name of the created component of cid L (e. g. outboundplug_z_cid_l1)? so I link these outboundplugs still to one at designtime defined inboundplug of cid L...

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

yes .. this would solve it.

You can not delete the navigations manually ...

And you do not loose anything. It is still dynamic. The called inbound plug just has to exist in your component. So when it is defined in your CID as IP_DEFAULT and this will be the standard start plug of all implementing components you even can write it down hard coded. It is just the target of the navigation.

So maybe you can just tell me where you want to go with your application.

How will you assimble it? Don't you use customzing tables or something like that to create the final running up?

Who hast to decide which components finally should be used?

I mean if you offer the user to choose between 3 Layouts you know that at design time and you can define the navigations at design time. Only iyou do not know at design time which layout components will be offered and can be used you need something dynamic.

Sure, if you use a dynamic approach via a customizing table it would be easy to provide new layouts without touching the main component. Just tell me what you finally want to achieve.

Former Member
0 Kudos

>>yes .. this would solve it.

so I have two possibilities now:

1. if number of layouts not known at designtime: creating outboundplugs in M dynamical and store the navigation links in such a hashtable.

2. number of layouts is known at designtime: creating an outboundplug in M to each possible layoutcomponent Lx at designtime)

I prefer 1. because of the extensibility.

>>So maybe you can just tell me where you want to go with your application.

>>How will you assimble it? Don't you use customzing tables or something like that to create the final running up?

I am new in WDA and its my first project. I only know that I have to create a framework which separates the Layout and other CID´s and a Mothercomponent M which handles the datatransfer between the cid´s and react to events. In a later step it surely should be customizable (layout) and be extendable(functionality).

>Who hast to decide which components finally should be used?

The user actions (e. g. a mouseclick in a menu) at runtime and his role determine which components will be used at runtime.

>Sure, if you use a dynamic approach via a customizing table it would be easy to provide new layouts without touching the main component. Just tell me what you finally want to achieve.

please explain me your concept and what you mean with "dynamic approach via a customizing table" ?

EDIT:

by the way: can you show me a code snippet how I can create an outboundplug at runtime? I think the fire_plug method not only fires an plug but also create the plug?

Message was edited by:

Thorsten Winter

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

> >>yes .. this would solve it.

>

> so I have two possibilities now:

> 1. if number of layouts not known at designtime:

> creating outboundplugs in M dynamical and store the

> navigation links in such a hashtable.

> 2. number of layouts is known at designtime: creating

> an outboundplug in M to each possible

> layoutcomponent Lx at designtime)

>

> I prefer 1. because of the extensibility.

yup.

> please explain me your concept and what you mean with

> "dynamic approach via a customizing table" ?

I have one main component which is responsible for setting up the menu structure. This component holds all possible navigationinfo in context, which is handled as authorisation. There is one action used for all menu entries. When the user clicks a menu entry the action is called and regarding the corresponding navigationinfo element (which contains info about component to load, inbound to navigat to) builds the dynamic navigation. Like described above. So I just need to add authorisations to this customizing table if a new component should be available.

Then I have a user authorisation table where I add authorisation to apecific user.

This info is used by the main component to build the menu.

> EDIT:

> by the way: can you show me a code snippet how I can

> create an outboundplug at runtime? I think the

> fire_plug method not only fires an plug but also

> create the plug?

you already create it dynamically with prepare_dynamic_navigation. It is the parameter source_plug_name. Nothing else to do.

Former Member
0 Kudos

I got still a little lack of understanding.

if I am right M should pass the name of the dynamical created outboundplug to the created component of cid L (e. g. L1) and L1 makes the navigation link (prepare_dynamic_navigation). L1 needs the name of the outboundplug and the hashtable in M store the created navigation links and then fires the correct ouboundplug.

but thats a problem. only M can fire its outboundplug and before L1 must have created the

navigation link because only the view-controller of L1 knows its target_embedding_position. so I can´t create the outboundplug via PREPARE_DYNAMIC_NAVIGATION in M.

how can I realise this?

thanks sascha. if you give me an answer I can start making the changes at my wd-application.

Former Member
0 Kudos

a code snippet from creating a navigation link in a method of my view-controller in L2

l_view_controller_api->DO_DYNAMIC_NAVIGATION(
                   source_window_name          = 'V_L'
                  source_vusage_name          = 'V_L2_USAGE_1'
                  source_plug_name            = 'TO_ERGEBNISVIEW'
                  target_component_name       = 'Z_CID_CB1'
                  target_component_usage      = 'USAGE_Z_CID_CB1' 
                  target_view_name            = 'V_B'
                  target_plug_name            = 'FROM_V_AUSWAHL'
                  target_embedding_position   = 'V_L2/VC_L2_CID_B_ODER_C' ).

So I can´t do this in M because only L2 knows where to link to (e.g. target_component_usage and target_embedding_position) but I need to create the Outboundplug (here TO_ERGEBNISVIEW) in M and then fire this plug in M.

Former Member
0 Kudos

I thought M has the embedding position.

Doesnt M has the view which embedds the interface view of L1 or L2 or L3?

In which view is the button which triggers the dynamic navigation?

Pls explain you design a bit deeper.

Former Member
0 Kudos

>>I thought M has the embedding position.

no, cid L and not M handles the layout and only L1or L2 know the target_embedding_position (e.g. 'V_L2/VC_L2_CID_B_ODER_C').

>>Doesnt M has the view which embedds the interface view of L1 or L2 or L3?

M only embedds the interface view from cid_l (V_L) in its window.

>>In which view is the button which triggers the dynamic navigation?

the button to switch the layout for testing purposes is in the view of L2 but I think this is not important because the layout could be switched everywhere at runtime perhabs if a menu is clicked or so one.

is it possible to create an outboundplug of M in a method of L1 with PREPARE_DYNAMIC_NAVIGATION?

then I can realise it so:

1. button for switching layout is clicked

2. M reacts for this registered event and deletes the component L2 of comp_usage of CID_L and creates component L1

3. M calls a Method of CID_L and passes its name for the outboundplug to L1.

4. the method of CID_L makes the navigation link via PREPARE_DYNAMIC_NAVIGATION (implementated in L1)

5. the link now exists and M can fire the in L1 created outboundplug.

Could this work?

EDIT: I still need the hashtable with outbound plugs when the same layout could be used more than once?

>>lv_auth is the ID auf the authorisation assigned to the link.

what´s "lv_auth" in your hashtable and "lv_outplug" is the outplugname? I think you can use the name of the outboundplug as key and value of the hashtable?

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

man man

kind of complicated design ....

What exactly is L doing when handling the Layout? Anything else as embedding other components? What is the use of it? Special functions? Just tell me more

I would say that CID L is responsible for the layout as it acts as layout controller.

so no one else has to take care about. If I understand you correctly you want to fire an event in L to let M know that user decided to switch to another layout. Then M again calls a method in L to switch the layout ...

Former Member
0 Kudos

>>kind of complicated design ....

I think so too

>>What exactly is L doing when handling the Layout? Anything else as embedding other components? What is the use of it? Special functions? Just tell me more

At the moment L is only handling the layout and embedding other components in viewcontainer and it should be in my wda-application possible to switch the layout (= the used component of cid L).

>>I would say that CID L is responsible for the layout as it acts as layout controller.

Jepp.

>>If I understand you correctly you want to fire an event in L to let M know that user decided to switch to another layout. Then M again calls a method in L to switch the layout ...

At the moment I have a example application and only L2 fire an event where M registered to and I have the problems to switch the component of cid L (e. g. L2 to L1). So please try to answer me tomorrow my last questions how to use exactly the hashtable and where to call the prepare navigation method etc.

I think you are German? Would it be easier to write an email in german? the context is quite complex I think

Former Member
0 Kudos

> At the moment L is only handling the layout and

> embedding other components in viewcontainer and it

> should be in my wda-application possible to switch

> the layout (= the used component of cid L).

Ok, so is it fixed that L1 embedds K1, K2, ... and L2 embedds K3, K4? Or can the user decide what K components he can embedd in L1?

Cause when it is fixed you only have to decide which L you use to change the layout. And this would be decided in M which means that you have to add the prepare_dynamic_navigation method in the view in M that has the embedding position and add the dynamic outbounds in M. The action that triggers the layout change has to be in this view too.

If it is dynamic which Ks get embedded in L1 you also have to do the same thing in L1. The same way as described above. In this case only L1 can dynamically embedd its K components. M should not know anything about the K components.

The prepare_dynamic_navigation method to embedd Ks in L1 must be in the view with the embedding position in L1.

> to L1). So please try to answer me tomorrow my last

> questions how to use exactly the hashtable

add a new outbound OP1:


wd_this->outbound_plugs->setvalue(
           exporting
             name = 'OP1'
             value = 'OP1'
          ).

check whether the outbound already has been used for navigation:


wd_this->outbound_plugs->getvalue( 'OP1 ) is not initial.

add this hashtable object as attribute in you view controller

in wddoinit create the object:


create object wd_this->outbound_plugs.

Former Member
0 Kudos

I have a really silly situation now.

My plan was to check in the hashtable M if an outboundplug to the actual component of cid L exist and if not to make the ob-plug and the navigation links in Lx via prepare navigation method. so I have to pass the name of the ob-plug from M to Lx (I need it as parameter source_plug_name ).

this works so far and I got the name of the ob-plug in the componentcontroller of Lx.

but only the view-controller of Lx can execute the prepare navigation method and I can´t access to a method from the view controler in Lx from its component controller.

at the moment the creation of navi links in Lx is done in the wddoinit of its view. but after this the layout could be changed too. only the view of Lx can make the navigation links because it only knows the target embedding position and not M.

Former Member
0 Kudos

thanks sascha

>>Cause when it is fixed you only have to decide which L you use to change the layout. And this would be decided in M which means that you have to add the prepare_dynamic_navigation method in the view in M that has the embedding position and add the dynamic outbounds in M. The action that triggers the layout change has to be in this view too.

in my eyes this can´t work for my scenario because M only knows the used component of cid l at runtime but M doesn´t know in which view containers the other used comp´s of the other cid´s (you call them k´s) has to be placed for example in L1.

for example relevant paramters of prepare navigation in view from L1 for embedding V_A from CID A in a viewcontainer


target_view_name            = 'V_A'
                  target_plug_name            = 'FROM_V_AUSWAHL'
                  target_embedding_position   = 'V_L1/VC_L1_CID_A' ).

and M doesn´t know how much view containers Lx has and what views of dynamically created components (k´s) are in Lx´s shown.

Former Member
0 Kudos

a solution could be if Lx would tell M its target_embedding_position´s so M can make the navigation links.

There could be one target_embedding_position when 1 view of a CID component is shown and several.

so one source-target-combination (prepared navigation)could have more than one navigation link because each dynamical embedded interfaceview in Lx has another target embedding position.

Message was edited by:

Thorsten Winter

Former Member
0 Kudos

in my eyes this can´t work for my scenario because M

only knows the used component of cid l at runtime but

M doesn´t know in which view containers the other

used comp´s of the other cid´s (you call them k´s)

has to be placed for example in L1.

thats what I am talking about ... your design approach seems to be wrong. M should not and can not now anything about components embedded in L.

M should only handle the dynamic embedding of L components in M itself.

And L should only handle the embedding of K components in L itself. M should not know anything about it.

You should consider another design aproach.

Former Member
0 Kudos

M cannot embedd something in embedding positions in L. M can only embedd interface views of L in M.

Message was edited by:

Thorsten Wintera solution could be if Lx would tell M its

target_embedding_position´s so M can make the

navigation links.

There could be one target_embedding_position when 1

view of a CID component is shown and several.

so one source-target-combination (prepared

navigation)could have more than one navigation link

because each dynamical embedded interfaceview in Lx

has another target embedding position.

Former Member
0 Kudos

thanks sascha

I think you are right and I have to overthink my design concerning dynamical layout component change...I will report you soon...

Former Member
0 Kudos

>>M cannot embedd something in embedding positions in L. M can only embedd interface views of L in M.

yes my fault was creating dynamical navigation link from Lx to the cid´s (A - C) but I have to create the navigation link from M to L dynamical.

I´ll try and give you a feedback.

thanks so far sascha. by the way: seems that you are one of a few experts in this topic here at sdn

Former Member
0 Kudos

I adress my problem now again.

I got the problem now that after I made a

l_view_controller_api->PREPARE_DYNAMIC_NAVIGATION(
              source_window_name          = 'W_MAIN'
              source_vusage_name          = 'V_L_USAGE_1'
              source_plug_name            = OB_PLUG_NAME
              target_component_name       = used_component_name_l
              target_component_usage      = 'COMPONENT_USAGE_CID_L'
              target_view_name            = 'V_L'
              target_plug_name            = 'FROM_V_AUSWAHL'
              target_embedding_position   = '' ).

the outboundplug (-> source_plug_name ) with the name of the string "OB_PLUG_NAME" wasnt´t dynamically created and my wd-application got the error:

"Der Outbound-Plug OB_Z_CID_L2 existiert nicht innerhalb des Views V_AUSWAHL der Komponente Z_CID_MAIN_TEST_UIDYNAMIC"

I didn´t want to create the outboundplug "OB_PLUG_NAME" at designtime so I tried the PREPARE_DYNAMIC_NAVIGATION() method but it didn´t worked.

someone an idea why?

Former Member
0 Kudos

why didn't you specify a target_embedding_position?

Former Member
0 Kudos

when I create an ob-plug "OB_PLUG_NAME" at designtime the programm works but after I fired this plug with

l_view_controller_api->fire_plug(
     exporting
       plug_name = OB_PLUG_NAME
     ).

I only see the old view and not the V_L.

is it the problem that the embedding position is empty? I can´t name a viewcontainer because V_L is embedded in the window W_MAIN.

should I embedd V_L in a View of W_MAIN so that I can name an embedding position with a view container?

Former Member
0 Kudos

>>why didn't you specify a target_embedding_position?

hi sascha,

I can´t specify the target position because I embedd V_L in M in the Mainwindow and V_L is a cid which embedds several other views.

So my only chance I think to specify the target embedding position is to embedd V_L in a viewcontainer of a new view in the mainwindow of M?

Former Member
0 Kudos

has anyone an opinion concerning my last postings or should I create a new post in the forum because the topic will be then more clearly arranged?