Archive for Facelets

Composite JSF Components

Writing a versatile input/output component for JSF, I realized two things:

  1. Composition works great. It is almost trivial to delegate encoding and decoding to existing components like the JSF core input tags via composition. Facelets templates offer this functionality in a declarative way without coding (or compiling), and I wouldn’t want to use JSF without them at all, but it’s nice that composition is rather easy in core JSF anyway.
  2. You don’t want to pull SelectMany values from ExternalContext#getRequestParameterMap(), but use ExternalContext#getRequestParameterValuesMap() instead.
  3. Doing a “render-time” iterator component similar to Facelets’ ui:repeat is insanely hard to do right. Really. Rendering the child components multiple times with different data is easy, but to let them perform correctly on every stage of the lifecycle is near to impossible without some intimate knowledge of JSF. I’d really like to read a book on these kinds of advanced JSF topics (and not on designing another calendar component), but I’ve yet to find one.

Leave a Comment

JSF and Ajax: ajax4jsf

Assuming that the component model of JSF is pretty well suited for Ajax applications, I found it surprisingly hard to find an Ajax framework that

  • has native support for JSF and the JSF lifecycle (unlike generic frameworks like AjaxAnywhere),
  • requires no custom Javascript coding for basic event/update mechanisms, and that
  • supports existing components unaware of Ajax.

There is a proof-of-concept implementation of a very JSF-centric approach proposed by Jacob Hokoom that fully utilizes the JSF component tree in the jsf-extensions project. Very promising, but it seems to be in a very early stage and requires JSF RI 1.2.

An existing alternative is Ajax4jsf, a rather mature and capable Ajax filter created and maintained by the Exadel people. Usage is fool-proof: using the a4j tag library, you either attach Ajax behavior to Javascript events (e.g. onchange) of existing input elements, or you add command buttons that emit Ajax calls when clicked, instead of reloading the whole page. When an Ajax event occurs, the form surrounding the element is submitted, making server-side handling identical to that of a common post-back. Ajax4jsf tags accept a list of component IDs to be re-rendered when the Ajax call was processed, automagically updating independent regions of the page. You don’t even have to identify those regions manually, for example, if a datatable should be updated – pass its ID to a4j and it will be updated when the server response arrives.

My only gripe so far is performance – by default, every request is routed through a Tidy filter, even for non-Ajax pages. This can be disabled by setting the forceparser init parameter to false (in the web.xml filter definition), which will only tidy up Ajax responses.

Oh, and if you’re using Facelets: read the docs ;). Remove the Facelets view handler from your faces-config.xml and set the org.ajax4jsf.VIEW_HANDLERS context parameter in the web.xml instead.

Besides possible performance concerns, I believe ajax4jsf’s interface is pretty much perfect for ajaxifying JSF applications without special needs – that is, wiring client-side events to JSF beans and rendering partial updates of a page. I’m all for simple, straight-forward solutions that just work – which is also the reason I was slightly disappointed of Pro JSF and Ajax with its clumsy (but surely more flexible) mabon. I guess I just don’t want to write more client-side Javascript than absolutely necessary for a pleasing user experience.

Comments (5)

Passing parameters to links in Facelets

I’m a JSF/Facelets newbie – so far there’s been a lot of cursing, but also some moments when I had the impression of “something done right”.

In JSF, command links are used to wire buttons to actions in backing beans. Unfortunately, you cannot pass parameters directly to the action method – but you can set parameters in your backing bean before calling the action. To set a parameter, add a f:param to the command link body – e.g.

<f:param name="myParameter" value="#{myValue}"/>

In the backing bean, the passed value can be retrieved from the faces context (similar to HttpServletRequest#getParameter for servlets). It works, but it’s inconvenient and errorprone, and requires conversion for all but string parameters.

Fortunately, there are alternatives. There’s the non-standard Tomahawk updateActionListener that directly works on bean properties. For example, you could just write

<t:updateActionListener 
   property="#{myBean.myProperty}" value="#{someValue}"/>

and forget about it. Unfortunately, Facelets doesn’t include the updateActionListener out of the box. But in JSF 1.2 there’s something even better – the setPropertyActionLister. It works exactly like the Tomahawk listener, but it’s standard and hey – it’s already been backported to Facelets 1.1:

<f:setPropertyActionListener 
   target="#{myBean.myProperty}" value="#{someValue}"/>

So far it’s worked great and it is definitely better than manually setting parameters via f:param.

Comments (14)