My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

sâmbătă, 27 iunie 2015

[OmniFaces utilities 2.0] Create an ajax behavior which should invoke an ajax listener method expression based on the given EL expression


[OmniFaces utilities] The createAjaxBehavior() method creates an ajax behavior which should invoke an ajax listener method expression based on the given EL expression. The target method must take an AjaxBehaviorEvent as argument. Note that this is essentially the programmatic equivalent of <f:ajax>. So if you intented to create for example a <p:ajax> programmatically, then don't use this method. Check also the UIComponentBase#addClientBehavior(String, ClientBehavior) whereby the string argument represents the client event name, such as action, valueChange, click, blur, etc.

Method:
Usage:

Let's suppose that we have the following simple form:

<h:form>
 ...
 <h:commandButton value="Save"/>
</h:form> 

Further, we want to programmatically add an AJAX behavior (like <f:ajax/>) to the above button, and for this we can write a tag handler that exploits the Components#createAjaxBehavior(). Below is listed only the apply() method (notice the pointed listener, #{commandBean.save}):

@Override
public void apply(FaceletContext ctx, UIComponent parent) throws IOException {

 // avoid the following code to be executed multiple time in the same request
 if (!ComponentHandler.isNew(parent)) { 
     return;
 }

 // obviously, if the parent is not a ClientBehaviorHolder then is not capable to deal with an AJAX behavior
 if (!(parent instanceof ClientBehaviorHolder)) {
     return;
 }

 AjaxBehavior ajaxBehavior = Components.createAjaxBehavior("#{commandBean.save}");
 ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) parent;
 clientBehaviorHolder.addClientBehavior("action", ajaxBehavior);       
}

Or, in order to avoid the risk of adding twice the same AJAX behavior:

AjaxBehavior ajaxBehavior = Components.createAjaxBehavior("#{commandBean.save}");
ClientBehaviorHolder clientBehaviorHolder = (ClientBehaviorHolder) parent;
List<ClientBehavior> behaviors = clientBehaviorHolder.getClientBehaviors().get("action");
// Guard against adding ourselves twice
if (behaviors == null || !behaviors.contains(ajaxBehavior)) {
    clientBehaviorHolder.addClientBehavior("action", ajaxBehavior);
}

Further, the form will become:

<h:form>
 <h:outputScript name="jsf.js" library="javax.faces" target="head"/>           
 <h:commandButton value="Save"> 
  <t:simpleAjax/>
 </h:commandButton>
</h:form>

Notice that we have explicitly added the jsf.js resource. By default, when JSF finds an AJAX behavior in the current view it will "install" this resource automatically (e.g. in Mojarra, via com.sun.faces.facelets.tag.jsf.core.AjaxHandler#installAjaxResourceIfNecessary()). But, notice that this is true from AJAX behavior explicitly defined in view, not programmatically. Depending on context, the jsf.js can be added via @ResourceDependency (not the case here, but when it is use: @ResourceDependency(library="javax.faces", name="jsf.js", target="head")), or via <h:outputScript>). Of course, you can have a helper method also (maybe inspired from Mojarra source code).

Finally, the listener (#{commandBean.save}) is defined in CommandBean, as:

public void save(AjaxBehaviorEvent evt) {
 LOG.log(Level.INFO, "---------------------Saving---------------------- / {0}", evt);
}

Note If you need to go deeper and understand how Components#createAjaxBehavior()is implemented, then you can check the com.sun.faces.facelets.tag.jsf.core.AjaxHandler methods, especially, AjaxHandler#applyAttachedObject()and AjaxHandler#createAjaxBehavior().

The complete code of this example is on GitHub.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors