Do this requires use of the client behaviour system built into JSF2. This article will focus on performing this tasking using PrimeFaces widgets from version 3.0 which fully support client behaviour – prior to version 3.0 support was, I believe, limited.
I’ll dive straight in with a code snippet. This shows the basic way to create a panel and then add an ajax listener which will will notify a bean of the closure of the panel.
FacesContext fc = FacesContext.getCurrentInstance(); Application application = fc.getApplication(); ExpressionFactory ef = fc.getApplication().getExpressionFactory(); Panel panel = (Panel) application.createComponent(Panel.COMPONENT_TYPE); panel.setId( "Foo" ); panel.setHeader( "Header"); panel.setClosable(true); MethodExpression me = ef.createMethodExpression( fc.getELContext(), "#{myBean.handleClose}", String.class, new Class[0]); AjaxBehavior ajaxBehavior = new AjaxBehavior(); //ajaxBehavior.setListener( me ); ajaxBehavior.addAjaxBehaviorListener( new AjaxBehaviorListenerImpl( me ) ); panel.addClientBehavior( "close", ajaxBehavior);
Notice that you have to call addAjaxBehaviourListener rather than tempting addListener method. I’m not sure at this moment what addListener is supposed to do but if you supply your MethodExpression to it your even won’t get fired. Some people feel this is abug I’m not so sure having looked at the source
--------------------
Use ExpressionFactory#createMethodExpression()
.
public abstract MethodExpression createMethodExpression( ELContext context, java.lang.String expression, java.lang.Class<?> expectedReturnType, java.lang.Class<?>[] expectedParamTypes)
Here's a convenience method:
public static MethodExpression createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) {
FacesContext facesContext = FacesContext.getCurrentInstance();
return facesContext.getApplication().getExpressionFactory().createMethodExpression(
facesContext.getELContext(), expression, returnType, parameterTypes);
}
The following action method examples:
public void submit1()
public String submit2()
public void submit3(String argument)
public String submit4(String argument)
public void submit5(String argument1, Long argument2)
public String submit6(Long argument1, String argument2)
can then be created as follows:
createMethodExpression("#{bean.submit1}", null);
createMethodExpression("#{bean.submit2}", String.class);
createMethodExpression("#{bean.submit3('foo')}", null, String.class);
createMethodExpression("#{bean.submit4('foo')}", String.class, String.class);
createMethodExpression("#{bean.submit5('foo', 0)}", null, String.class, Long.class);
createMethodExpression("#{bean.submit6(0, 'foo')}", String.class, Long.class, String.class);
Note that the EL expression is exactly the same as you would use in the normal view file.