Invoking af:exportCollectionActionListener from Java

The af:exportCollectionListener tag is a client behavior tag in ADF Faces. Client behavior tags implement functionality that requires JavaScript on the client side if coded manually by application developer. In fact, client behavior tags wrap the JavaScript that is required for a solution and expose a JSF tag for declarative use instead. The af:exportCollectionListener exports the visible content of a collection, like exposed in an ADF Faces table, to Excel. The tag is dragged on top of a command item, like a toolbar button or a command button, and then configured with the table id for which rows should be exported, the name of the file to produce, whether you want to export all rows or just those that are selected, and an optional title string. For more information, see the tag documentation:

http://download.oracle.com/docs/cd/E17904_01/apirefs.1111/e12419/tagdoc/af_exportCollectionActionListener.html

When the command item that has the af:exportCollectionListener tag added is invoked by a user, the tag is executed as well and produces the desired output. However, applications usually are a lot more dynamic than to wait for a user to press a button. Instead developers may want to invoke the client behavior programmatically, which in case of a client behavior you can do using JavaScript

var button = AdfPage.PAGE.findComponentByAbsoluteId('pc1:ctb1');
if (button != null)
{
  AdfActionEvent.queue(button);
}  

The JavaScript code above looks an ADF Faces component up in a search from the page root. The component is identified by its absolute component Id ('pc1:ctb1' in the example as the button is in a toolbar facet of a panel collection, which is a naming container). If the component is found, the client event – AdfActionEvent – is queued for the button, which virtually presses it.

However, what if you don't want JavaScript in your application code? In this case, you can use Java to invoke JavaScript from a managed bean. The following code sample provides a method that is called from Java logic in your managed bean to composes the JavaScript String and to invoke it on the client:

import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;  
public void magicallyPressToolbarCommand(String id) {
  FacesContext fctx = FacesContext.getCurrentInstance();
  UIViewRoot uiViewRoot = fctx.getViewRoot();
  UIComponent comp = uiViewRoot.findComponent(id);
  //check if the component is a command component. For the 
  //exportCollectionListener this is important as we need to 
  //queue a client side action event
  if (comp != null && (comp instanceof UIXCommand)) {
    String clientId = comp.getClientId(fctx);
    StringBuffer scriptBuffer = new StringBuffer();
    scriptBuffer.append("var button = 
                       AdfPage.PAGE.findComponentByAbsoluteId('");
    scriptBuffer.append(clientId + "');");
    scriptBuffer.append("if (button != null){");
    scriptBuffer.append("AdfActionEvent.queue(button);}");
    writeJavaScriptToClient(scriptBuffer.toString());
  } 
  else {
    //ID probably not found. Log the issue
     System.out.println("Component with ID " + id + " not Found !!!");
    //TODO - use proper ADFLogger print message
  }
}
//universal helper method for invoking scripts on the client
private void writeJavaScriptToClient(String script) {
  FacesContext fctx = FacesContext.getCurrentInstance();
  //Trinidad classes
  ExtendedRenderKitService erks = null;
  erks = Service.getRenderKitService(fctx,
  ExtendedRenderKitService.class);
  erks.addScript(fctx, script);

}

What you need to pay extra attention to is the ID of the component ( a toolbar component in my example). If a component is within a naming container like PageTemplate, Table, PanelCollection, Region, etc. then the ID(s) of the surrounding naming containers must be added as a prefix to the component ID. The form is namingContainerId:componentId.

Disadvantage of using JavaScript in Java: The script is harder to debug on the client.

One more challenge!

Okay, now that I showed how to invoke a command item on a client using JavaScript from Java, what if you don't want to have a button showing in the UI? In this case, it should be the application logic only that invokes the af:exportCollectionAtionListener. In this case you still add a command item to the page but set its Visible property to false. This way the command item is hidden in the user interface, but the functionality is still available for the application to use.

Note: Don't however try the same setting the "Rendered" property to false. If a component is not rendered then it cannot be found and invoked on the client.

Comments:

Post a Comment:
Comments are closed for this entry.
About

The Oracle JDeveloper forum ranks in the Top 5 of the most active forums on the Oracle Technology Network (OTN).



The OTN Harvest blog is a summary of selected topics posted on the OTN Oracle JDeveloper forum.



It is an effort to turn knowledge exchange into an interesting read for developers who enjoy little nuggets of wisdom





Frank Nimphius

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today