cancel
Showing results for 
Search instead for 
Did you mean: 

Passing control from one component to another

Former Member
0 Kudos

Hi,

I have a question regarding inter-portal-component communication.

The scenario is as follows: Component A performs the actual task and is the 'main' component. Component B performs a search task.

Both components are JSPDynPages ie derived from PageProcessorComponent

The idea is that component B should be a working component in its own right, and should be 'callable' from within other components. In my case component A has a search button which fires an event to component A. A's handler handler then redirects to B ie handing control to B. The state of A is stored in the user session to be restored once B returns. The scenario is modelled on function/procedure call semantics.

Once the request is redirected to B the user should now interact with B, search, scroll etc until the desired object is found. When the user clicks 'select' B stores the found items in the session (for retrieval by A) and hands control back to A, again via a redirect.

Thus far I'm able to perform the redirect:

import com.sapportals.portal.prt.component.IPortalComponentContext;

import com.sapportals.portal.prt.component.IPortalComponentRequest;

import com.sapportals.portal.prt.component.IPortalComponentResponse;

import com.sapportals.portal.prt.pom.INode;

import com.sapportals.portal.prt.pom.IComponentNode

. . .

INode myNode = request.getNode();

IPortalComponentContext cntxt = request.getComponentContext("Component B");

IComponentNode cnode = myNode.getPortalNode().createComponentNode(REDIRECT_NAME, cntxt);

response.include(request, cnode);

. . .

The problem is that even though the search page of B appears after the redirect, subsequent events are still directed to Component A.

I have even tried specifying the 'action' attribute in the <htmlb:form> tag but that didn't work either.

I'm relatively new to the whole portal thing, and my thinking is still in the servlet paradigm, so any help putting me on the straight and narrow would be appreciated

Cheers

Michael.

Accepted Solutions (0)

Answers (5)

Answers (5)

Former Member
0 Kudos

hi all ,

I had gone through ur answers.Can u pls tell me where should I put this following code in Component A.

INode myNode = request.getNode();

IPortalComponentContext cntxt = request.getComponentContext("Component B");

IComponentNode cnode = myNode.getPortalNode().createComponentNode(REDIRECT_NAME, cntxt);

response.include(request, cnode);

thanks

ss

Former Member
0 Kudos

I was wondering if the issue mentioned above was solved.

I have two iViews. iView one is an Order Search and second iView is Detailed Order Information. When user searches for an order, they get order list and when they select one order, I need show them the other Order Detail iView. I have tried doing include or dispatchRequest from the order search iView but the content is shown for both iView. Is there any way I can replace the Content of iView order search when user selects the order so that the user sees only the content of Order Detail iView.

Please help !!

Former Member
0 Kudos

Hi,

yes the problem was solved ... well kind of. I have since been told that the way to solve such problems is client side epcf eventing.

the posting by Stefan Batzdorf solved the problem - thank you.

the 'calling component' needs to note the 'caller' in the portalapp.xml file.

in my application i was doing some user manipulation so my 'callee' was a search user iview.

portalapp.xml

<component name="UserAdminController">

<component-config>

<propertyname="ClassName"value="...Controller"/>

<property name="mode" value="UserSearch">

<property name="delegate" value="UserSearch"/>

. . .

i just used the component name as the mode names.

now in the iViews themselves i just used the dispatching mechanism.

NodeMode currentMode = thisNode.getNodeMode();

NodeMode newMode = new NodeMode(newModeName);

thisNode.setNodeMode(newMode);

///IPortalComponentContext cntxt = req.getComponentContext(componentName);

IPortalComponentContext cxt = req.getComponentContext();

IComponentNode cnode =

thisNode.getPortalNode().createComponentNode(REDIRECT_NAME, cxt);

req.dispatchRequest(cnode, resp);

The crux, it seemed was the entry in the portalapp.xml.

the dispatching seems to work bothways ie when you're search iview is finished you just call the same redirect method only with mode 'default'.

i passed parameters via the context variable.

i have'nt looked at this further... you know how it is

you get sent to another project.

i did get some 'illegalstateexceptions' i think it complained about calling getPortalNode or the setNodeMode but i'm not sure.

the other thing was in the prt runtime doc (640) there is a section on Portal Component Modes. there it talks about how the doXXX method is called on the delegate.

XXX is the name of the mode. I never had a special method maybe it called doContent in the absence of an

appropriate method. i'm pretty green with the whole portal thing but it seemed to work for me.

hope this helps

cheers

m.

Former Member
0 Kudos

Hi,

nice to hear that delegation works in ep6. But how about ep 5. There isn't a portalapp.xml and the properties mode and delegate are widely unknwon.

My problem is similar like yours. I would like to delegate a request from component "A" to component "B". To instantiate and integrate the portal component "B" in a component-"A"-request works fine (Same way as described above). But I don't know how to change the mode of nodes so that the next subsequent call will be processed by component "B"

Any ideas & Thanks for help

Annemarie

Former Member
0 Kudos

Hi, i tried it, the way you described it.

I have to JSPDynPage Components, List and Detail.

Both are described in the same portalapp.xml.

I have included the

mode property in the config part of the List-Component

<property name="mode" value="showDetail">

<porperty name="delegate" value="Detail"/>

</property>

The first component

<component name="List">

and the second

<component name="Detail">

I try to set the NodeMode in the event-method of my List iView but when setting the NodeMode

request.getNode().setNodeMode(new NodeMode("showDetail");

The portal always throws an exception

PortalRuntimeException: iView not found: Detail.default

I have deployed the .par and created an iView for each of the two components. The names of the iView are exactly the names of the components. The List component is placed on a page.

What is going wrong??

Anyone con explain??

Regards

Edmund

Former Member
0 Kudos

Hi,

since the problem has solved, can any body give me the complete code sample for this type event handling.

your help will be appreciatble.

Thanks & Regards,

MCM.

0 Kudos

i met the same problem as you. Do you have solution now?

Former Member
0 Kudos

Hi Michael,

you have to use the delegation feature of the PRT to delegate the request from comp A to comp B and vice versa.

In the portalapp.xml of component A you have to specify the following property in the component-config section of component A:

<!-- delegation for componentB mode -->

<property name="mode" value="B">

<property name="delegate" value=" ... comppnent name of B ..."/>

</property>

Then if you want to delegate from A to B, A has to set the NodeMode to the delegation mode defined in the portalapp.xml:

pRequest.getNode().setNodeMode( new NodeMode("B") );

Thus component B gets all the requests. If B want to delegate back to A, B has to set the nodeMode to 'default' again:

pRequest.getNode().setNodeMode( new NodeMode("default") );

Hope this helps.

Regards,

Stefan

Former Member
0 Kudos

hi, I hope I understand the question.

My solution for you is to have only one component that has two main jsp A and B. In this way you can share the context and the request will go to what ever jsp you want.

Regards Lucian.

Former Member
0 Kudos

It seems to be that what you are actually doing is to include the contents of B into A. Instead you should forward the request from A -> B, so that subsequent links go to the B component.

I can't remember exactly how you do it so you need to do some searchin for links to other component

Former Member
0 Kudos

Hi,

I've tried <jsp:forward, and IPortalComponentRequest.distpatchRequest. <jsp:forward> had no effect and the dispatch had the same effect as the response.include.

I have found very little in the documentation on this topic and in the forums. I saw there is a javascript solution EPCF which can handle events from portal components but I wanted to avoid client side scripting.

I could use javascript, to modify form actions and thus point to another portal compoent. but i want to stay within the prt api, which is also recommended.

Given that htmlb events are caught by subclasses of PageProcessorComponents's event handlers and that these are called from within the AbstractPortalComponents doContent. Is it to late to redirect a request at that point.

Should i be constructing a new INOde object of the Components i want to redirect to at init time ??? And then dispatch to the node ?

I'm keen to hear from anyone who has done this whilst staying within the htmlb/prt model.

cheers

Michael

Former Member
0 Kudos

You can create links from a jsp to other components (and then redirect using javascript). I don't remember the exact function call.

If you want a clean solution, I think you might manage to do some redirection in the doOnNodeReady method in the AbstractPortalComponent

Code to generate links to other components (blatantly stolen from another thread). You also need a service reference to the URLGenerator

IPortalUrlGenerator portalGen = null;

IUrlGeneratorService urlGen = (IUrlGeneratorService)request.getService(IUrlGeneratorService.KEY);

ISpecializedUrlGenerator specUrlGen2 = urlGen.getSpecializedUrlGenerator(IPortalUrlGenerator.KEY);

if (specUrlGen2 instanceof IPortalUrlGenerator) {

portalGen = (IPortalUrlGenerator) specUrlGen2;

}

Message was edited by: Dagfinn Parnas