Happy New Year! OmniFaces 1.7 has yesterday been released!
Again, this release had some unscheduled delay for various reasons. Among others, I migrated back from Curaçao to the Netherlands and Arjan Tijms moved into a new home, resulting in both having much less free time during the same period. This also explains why there are relatively small additions and changes in this release. The three most useful additions are the fixviewstate.js
, CacheControlFilter
and
.
Fix JSF view state after ajax-rendering content which contains another form
You'll probably recognize the Mojarra-related problem described in an earlier blog Communication in JSF 2.0 - Ajax rendering of content which contains another form. In short, when you ajax-render some component which in turn contains another form, then this form would lose its JSF view state hidden field which in turn causes that the 1st submit always misses hit and only the 2nd submit works. This problem was almost 4 years ago reported as JSF spec issue 790 and for a long time scheduled to be fixed for JSF 2.2, however for some unclear reason it has been postponed to JSF 2.3. Note: early MyFaces 2.0.x/2.1.x versions also exposed this problem, but they internally fixed it rather quickly irrespective of the spec issue being targeted at 2.2/2.3.
Even though this problem could be fixed by a custom jsf.ajax.addOnEvent
script, the script is relatively large and sensitive to minor browser-specific bugs and thus not really worth copypasting plain into every single new JSF project. We couldn't wait any longer for JSF 2.3, so it has been added to OmniFaces 1.7! Long story short, you can see it in action at the showcase. It's basically a matter of adding the following line inside the
(not head!) of your master template:
library="omnifaces" name="fixviewstate.js" target="head" />
Note for PrimeFaces users: this script also silently fixes a minor PrimeFaces-related bug in versions older than 3.5.23 and 4.0.7: its internal fix for this problem namely incorrectly appends the JSF view state hidden field to GET forms as well! The fixviewstate.js
removes the hidden field from those forms afterwards. By the way, speaking about PrimeFaces, the showcase application has for this release been upgraded from PrimeFaces 3.5 to 4.0. No single change was necessary in the UI side (XHTML/CSS/JS). Kudos! In the Java side (backing beans, etc) only the Constants#VERSION
was removed, but that's not really relevant for the average PrimeFaces based webapp.
Control cache-related response headers
One of the more common homegrown servlet filters is one which sets the Cache-Control
, Expires
and Pragma
headers related to browser caching. With the new CacheControlFilter
there's now finally one more "standard" OmniFaces solution to minimize repeatedly homegrown code in your JSF project. Its configuration is relatively simple, in order to disable caching on all dynamic JSF pages, just add the following to the project's web.xml
, assuming that your FacesServlet
is mapped with a
of facesServlet
:
noCache
org.omnifaces.filter.CacheControlFilter
noCache
facesServlet
If you want to cache resources matching an example URL pattern of /foo/*
for 2 days, then map it so, with an expires
initialization parameter which can take a value of a number with a "w", "d", "h", "m" or "s" suffix indicating respectively weeks, days, hours, minutes or seconds:
cache2days
org.omnifaces.filter.CacheControlFilter
expires
2d
cache2days
/foo/*
Note that you can easily specify multiple
entries in a single
. See also the showcase.
Validate multiple input fields in a single method
If no one of the existing multi field validators
,
,
,
,
,
,
or
is sufficient for your concrete functional requirement, then you have now the opportunity to easily implement your custom multi field validation method via the new
tag. Here's an example referencing a bean method:
id="myId" components="foo bar baz" validator="#{bean.someMethod}" />
for="myId" />
id="foo" />
id="bar" />
id="baz" />
Whereby the method has the following signature (method name is free to your choice):
public boolean someMethod(FacesContext context, List components, List