Programatically Adding Ajax Actions to UIComponents

One of the projects I’m currently working on requires me to build a component tree dynamically. To complicate matters the components also require ajax functionality – in this case they are panels that need to be closed and notify a listener.

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");

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 a bug I’m not so sure having looked at the source.