26 Jan 2014

ADF Faces. Immediate custom client events.

In this post I am going to focus on ADF Faces Javascript API method to fire a custom event from the client side. For example:

   function cliListener(actionEvent) {
     AdfCustomEvent.queue(actionEvent.getSource(), "servListener",
                        null, true);
    }
 
We can use af:clientListener tag in order to attach the cliListener function to a command button and get the function invoked whenever the button is clicked.  On the server side we can catch the event and invoke a managed bean method:

     <af:commandButton text="TestButton" id="cb1" action="goEdit">   
      <af:clientListener type="action" method="cliListener" />
      <af:serverListener type="servListener"
                         method="#{TheBean.serverListener}"/>
    </af:commandButton> 

The question is - what lifecycle phase is this event going to be delivered to and what phase is the managed bean method going to fire at? Sometimes it is very important because it can change the application's behavior significantly. 

Let's have a look at the specification of the AdfCustomEvent.queue method:

/**
 * @param {AdfUIComponent} Component to queue the custom event on
 * @param {String} the type of the event
 * @param {Object} a set of parameters to include on the event.  Reserved
 *    parameter names include "type" and "immediate".
 * @param (boolean) whether the custom event is "immediate" - which will
 *  cause it to be delivered during Apply Request Values on the server,
 *  or not immediate, in which case it will be delivered during
 *  Invoke Application. 
 */
AdfCustomEvent.queue = function(component, type, params, immediate) { ... }

I am going to focus on the immediate parameter. When its value is true, the client event is going to be delivered at the Apply Request Values phase. So, it is going to fire before command button's action and action listener methods which are going to fire at the Invoke Application phase. And if the value of the immediate parameter is false, then the client event will fire at the Invoke Application phase after command button's action and action listener methods.

Let's consider an example of a very simple task flow:
There are two view activities: BrowseView and EditView. Each of them has a PageDef file. BrowseView contains the TestButton which is described above. This button fires goEdit action, so when users click it they will go to the EditView activity. Besides that, the button click also invokes the cliListener JS function, that sends servListener custom event to the server. This event is going to be caught  and a managed bean method is going to be invoked:
  
 public void serverListener(ClientEvent clientEvent) {
  BindingContext bc = BindingContext.getCurrent();
  DCBindingContainer dcb = (DCBindingContainer) bc.getCurrentBindingsEntry();
  //Do something with dcb
  System.out.println("dcb="+dcb.getName());
}

If we set the value of the immediate parameter to true in the JS code
   function cliListener(actionEvent) {
     AdfCustomEvent.queue(actionEvent.getSource(), "servListener",
                        null, true);
    }
 
then the serverListener method will be invoked at the Apply Request Values phase before going to the EditView. The name of the current binding container will be like this:

..._pageDefs_BrowseViewPageDef_...


But if the immediate parameter is false, then the serverListener method will be invoked after command button's action, and the name of the current binding container will be like this:

..._pageDefs_EditViewPageDef_...

  
sample application for this post requires JDeveloper R2.

Note! That all above in this post is good for R2.

In R1 the behavior is slightly different. If the command component's action causes a navigation to another view activity (like in our case) and the client event is queued with immediate=false, then the managed bean method, which is defined in the server listener, will never be invoked. But if you stay on the same view activity, then the managed bean method will be executed at the Invoke Application phase.
In case of immediate=true, the managed bean method,  defined in the server listener, will be executed anyway at the Apply Request Values phase.
   
   
That's it!

2 comments:

  1. I had tried it but nothing is printed when setting the immediate to false

    ReplyDelete
  2. Yes Mahmoud, in R1 the managed bean method will not be executed in this example.
    Thank you for your feedback.

    ReplyDelete

Post Comment