Package com.sapportals.portal.prt.service.epcftoolbox

Provides interfaces to simplify the implementation of client-side eventing for portal components.

See:
          Description

Interface Summary
IClientEventReceiver The interface that represents a receiver object for working with the EPCF toolbox.
IClientEventSender The interface that represents a sender object for working with the EPCF toolbox.
IEpcfToolbox The interface for the EPCF toolbox service, which provides helper classes that enable you to generate the JavaScript code necessary for sharing data between portal components using the client framework.
IScriptGenerator The interface that represents objects that generate script code.
 

Package com.sapportals.portal.prt.service.epcftoolbox Description

Provides interfaces to simplify the implementation of client-side eventing for portal components.

The API enables a sender to easily create the JavaScript for raising an event, and for storing parameters into a client data bag. The API enables a receiver to easily create the JavaScript for subscribing to the sender's event and for retrieving the sender's client data bag for that event.

As the content developer builds a component in Java on the server side without a deep knowledge of JavaScript (typically using HTMLB classes), the developer can use this API to autmatically generate the necessary JavaScript code.

Use case

Assume there are two portal components on the same portal page. The first called �sender� enables you to select some value(s). The second component called  �receiver� then displays some data dependent on the current values of the sender whenever a new selection in sender has been done. The receiver component must make a server request to get the updated data.

Basic Workflow

The following is a typical workflow that In order to implemenet this scenario, The In a typical way the dependent data in receiver are taken from a component system or database. In order to avoid the rendering of the whole page again, we can consider the approach in following steps:

No:Step
1)The user selects a new value in the sender component.
2)Sender stores his data in a client data bag.
3) Sender raises a new event via client-side eventing.
4)Receiver, which has subscribed to this event, is informed about this incoming event.
5)Receiver takes all necessary data from the client data bag.
6)Receiver starts his own reload, caused by scripting on the client. The data from the client are transferred in the HTTP request to the backend.
7)Receiver processes his doContent() method on the backend. He takes the values transferred in the HTTP request, decodes them and uses them to assemble updated content.
8)The HTTP response is then displayed in the browser to replace outdated content.

The sender needs JavaScript code that handles steps 2 and 3. The typical JavaScript coding stub looks like the following example. Either it can be a part of a JavaScript function (function handler) or these calls can be included directly as handler properties in an HTML tag (i.e., <BUTTON onclick="�">)

Sender JavaScript Sample

EPCM.storeClientData(�myurn�,<key>,<value>);
EPCM.raiseEvent(�myurn�,�onSelect�);

The receiver needs JavaScript code that handles the steps 4, 5 and 6.  The following is a typical example:

Receiver JavaScript Sample

function  receiveMyEvent(){
    myReceivedData = EPCM.loadClientData(�myurn�,<key>);
 
    // enhances a query string with the coded event data
    // which will be send to backend.
    location.search = <myReceivedDataAsQueryString>
}
 
// sucbscribe a receiver handler on the sender�s event
subscribeEvent(�myurn�,�onSelect�,receiveMyEvent)
 

Both these JavaScript code samples should be generated by proper Java classes, which can easily be instantiated using a dedicated portal service.

Common usage of the package

1) Include the service reference

When implementing a sender or receiver using the EPCF toolbox service, you must first include the corresponding service reference in the component�s profile.

ServicesReference=epcftoolbox

2) Include the proper packages in your component

import com.sapportals.portal.prt.runtime.PortalRuntime;
import com.sapportals.portal.prt.service.epcftoolbox.IEpcfToolbox;
import com.sapportals.portal.prt.service.epcftoolbox.IScriptGenerator;
import com.sapportals.portal.prt.service.epcftoolbox.IClientEventSender;
import com.sapportals.portal.prt.service.epcftoolbox.IClientEventReceiver;

3) Instantiate the service and the sender or receiver classes using the following calls. Get a service instance in the component�s doContent() methods.

IEpcfToolbox myServ = (IEpcfToolbox) PortalRuntime.getRuntimeResources().getService(IEpcfToolbox.KEY);

4) Implement the sender Java code

 
      // Instantiate the sender object
      IClientEventSender  mySender =  myServ.getClientEventSender(request,"XURN","XEVENT");
 
      // store all parameter in the sender Object
      mySender.setRawParameter("PAR1","document.xform.x1.value");
      mySender.setRawParameter("PAR2","document.xform.x2.value");
      mySender.setParameter("PAR3","NoEvent");
      mySender.setParameter("PAR4","0815");
 
      // you can then overwrite some parameters
      response.write("<FORM name=\"xform\">\n");
      response.write("<TABLE>\n");
      response.write("<TR><TD>PAR1:</TD><TD>");
      response.write("<INPUT type=INPUT name=x1 value=\"123456\">\n");
      response.write("</TD></TR>\n");
      response.write("<TR><TD>PAR2:</TD><TD>");
      response.write("<INPUT type=INPUT name=x2 value=\"ABCDEF\">\n");
      response.write("</TD></TR>\n");
      response.write("<TR><TD>PAR3:</TD><TD>");
 
      mySender.setParameter("PAR3","Event1");
      response.write("<INPUT type=BUTTON onclick=\""+ mySender.getScript() +"\" value=\"SendEvent1\">\n");
 
      mySender.setParameter("PAR3","Event2");
      response.write("<INPUT type=BUTTON onclick=\""+ mySender.getScript() +"\" value=\"SendEvent2\">\n");
 
      mySender.setParameter("PAR3","Event3");
      response.write("<INPUT type=BUTTON onclick=\""+ mySender.getScript() +"\" value=\"SendEvent3\">\n");
 
      response.write("</TD></TR></TABLE>\n");
      response.write("</FORM>\n");
      response.write("<HR>");
    }
 

In this sample, there are four event parameters -- PAR1, PAR2, PAR3 and PAR4 -- that should be transferred to the receiver component. The values are taken either from a JavaScript variable or a DOM reference (PAR1, PAR2), or they are used as fix values (PAR3, PAR4). The getScript()   method returns inline JavaScript, which can be integrated in the response. When using HTMLB, you have to pass this generated inline JavaScript on the proper objects (e.g., Form or Button).

5) Implement the receiver Java code

      // Instantiate one receiver
      IClientEventReceiver  myReceiver  =  myServ.getClientEventReceiver(request,"XURN","XEVENT");
 
      // Let the necessary script blocks generate in the response
      // of the ordinary component content
      response.write(myReceiver.getWrappedScript() );
 
      // Now the response content on the backend can be generated depending on
      // the parameters transmitted in the request from the frontend to backend.
      if (myReceiver.isReceived() ){
         // If the request originates from the frontend/backend data transmission,
         // the isReceived() method returns true. In such case the event parameters
         // can be obtained by getParameter() calls
         response.write("<H3>Event&Data in the current request</H3>");
         response.write("<TABLE>\n");
         response.write("<TR><TD>PAR1</TD><TD>"+myReceiver.getParameter("PAR1") +"</TD>\n");
         response.write("<TR><TD>PAR2</TD><TD>"+myReceiver.getParameter("PAR2") +"</TD>\n");
         response.write("<TR><TD>PAR3</TD><TD>"+myReceiver.getParameter("PAR3") +"</TD>\n");
         response.write("<TR><TD>PAR4</TD><TD>"+myReceiver.getParameter("PAR4") +"</TD>\n");
         response.write("</TABLE>\n");
      } else {
         // If the request doesn't originate from the data transmission,
         // someting else can, i.e. displaing of default screen ...
         response.write("<H3>No Event&Data in the current request</H3>");
      }

In this sample, the method getWrappedScript() returns the JavaScript block (similar to the receiver example under Basic Workflow), wrapped in the usual script and comment tags.

When the response contains the event data (isReceived() method returns true), the data transmitted to the backend can be retrieved using the method getParameter().

Additional features

Filtering of Events

In some scenarios the sender and receiver component can be the same. This raises the problem of whether such component should react to its own events or not.  The method SetEventFilter() allows you explicitly define this behavior using the following constants:

IClientEventReceiver.EVENT_FILTER_ALL  
IClientEventReceiver.EVENT_FILTER_FOREIGN 
IClientEventReceiver.EVENT_FILTER_OWN

If not defined explicitly, the receiver accepts only incoming events from other components (IClientEventReceiver. EVENT_FILTER_FOREIGN), but not from itself. 

Usage:

myReceiver.setEventFilter(IClientEventReceiver.EVENT_FILTER_ALL);

Displaying of message when reloading of content takes a lot of time 

The method setWaitingMessage() allows you to enable the displaying of a message, which is then visible during the reload of the component (Steps 6, 7 and 8 in the Basic Workflow).

Important Notes:

The message must be localized in the component itself; the service only passes it through.

Only the text using the current stylesheet is displayed via DHTML methods. There is no sand-glass waiting picture!

Usage

myReceiver.setWaitingMessage("Loading the content ...");

Known Restrictions

Both �sender� and �receiver � components must be configured as iViews with bypassing of iView server.  Otherwise, the component tries do display the content recursively in the same frame.

Both components must be on the same portal page rendered in IFRAMEs (isolation mode = URL).

Because the event data are passed in the HTTP request in the query string, which is limited in size (2KB), always use the minimum number of parameters needed. Typically, you should pass only the keys (such as, material number) in the event, but not the depending values (e.g., material description).

All event data (urn, event name, parameter keys and values) are included in the generated JavaScript code. In order to avoid JavaScript syntax errors, the event data may not contain the JavaScript string delimiters (single or double quote) or special characters (such as, \n). The following checks are built into the package:



Copyright 2011 SAP AG Complete Copyright Notice