Uncategorized

JSF vs. PrimeFaces vs. BootsFaces Search Expressions

It’s a bit inconvenient and error-prone to define an ID for each input field, each label and each message of a JSF view. You can make your like easier using the advanced search expressions. Used wisely, advanced search expressions enable you to move input fields on the screen or between JSF views without having to update zillions of ids. In fact, search expressions are possibly the most compelling reason to use PrimeFaces or – since version 0.8.0 – BootsFaces. Their search expression engines go far beyond the JSF standard.

Why are there different search expression engines?

Traditionally, JSF relies heavily on ids. Standard JSF 2.x adds a few generic search expression that allow you to get rid of the ids in many cases. The PrimeFaces team – and Thomas Andraschko in particular – took the idea to another level. They implemented a variety of new search expressions such as @next and @previous. Unfortunately, these search expressions can only be used with PrimeFaces widgets. There’s an open ticket offering to implement the PrimeFaces search expressions in the Mojarra framework. Last time I looked the ticket was still dormant, laid aside due to performance considerations.

When I joined the BootsFaces team, I had the idea to use the same search expression engine for BootsFaces, too. We’ve started negotiations, but for some reason the negotiations never took off. I wouldn’t say the PrimeFace team refused the idea. We just forgot to pursue the idea, and that was that. So, when I started to implement the BootsFaces AJAX API, I was in a hurry and I needed a more powerful search expression engine. So I decided to implement it myself1. Mind you: standardization may be a virtue. But competition is a virtue, too. So I ended up with a search expression engine that’s largely compatible with PrimeFaces, but goes beyond it in parts. On the other hand, I didn’t implement every PrimeFaces search expression. At least one search expression, widget(), uses a PrimeFaces feature that’s not available in BootsFaces.

So much for history. The rest of this article is a hands-on article showing you how to use search expressions in JSF, PrimeFaces and BootsFaces.

Search Expressions

Let’s start with the basics.

The traditional way to define an render, execute, update or process attribute is to simply use the id:

<p:commandButton update="growlID" />

Thing get difficult when you start to nest JSF components. If the parent element bears an id, you have to use a qualified path to define the child id:

<p:commandButton update="myFormID:growlID" />

This way you can address each component within the same form. To find an element outside the form, you have to precede it with a colon:

<p:commandButton update=":footerID:messagesID" />

Standard JSF 2.x defines a few shortcuts to get rid the id. Elements the can be address by such a shortcut don’t need to be given an id. The standard shortcuts are:

  • @none
  • @this (for instance, the current input field)
  • @form
  • @all (the entire JSF view, including the header)

Note that it’s a chore to implement @all. Therefore, it’s ill supported by many JSF frameworks, such as BootsFaces. Even the PrimeFaces team were reluctant to implement @all for a long time.

Advanced Search Expressions Primer

Let’s pick two advanced search expressions to illustrate the idea:

  • @parent denotes the parent of the current widget in the JSF component tree.
  • @next denotes the next component in the JSF component tree.
  • Analogously, @previous denotes the predecessor of the current component in the JSF tree.

@next and @previous are particularly useful to define labels and messages of an input field:

<prime:outputLabel value="first name" for="@next" />
<prime:inputText value="#{firstName}" />
<prime:message for="@previous" />

Chaining search expressions

You can chain advanced search expressions and / or traditional search expressions freely:

<prime:inputText value="#{firstName}" />
<prime:outputLabel value="first name" for="@previous" />
<prime:message for="@previous:@previous" />

The expression @previous:@previous finds the input field, which is two components apart of the message component. Another example which may be useful is @parent:messagesID, which looks for a sibling of the current component bearing the id messagesID. You can also use more complex expressions like @form:@next:messagesID. However, at some point the advanced search expressions start to loose their expressiveness. Better look for more simple alternatives.

Advanced Search Expressions Cheat Sheet

To cut a long story short, let’s assemble a cheat sheet:

Search expression JSF 2.2 PrimeFaces 5.2 BootsFaces 0.8.0
@none no component no component no component
@this the current component the current component the current component
@form the form surrounding the current compoent the form surrounding the current compoent the form surrounding the current compoent
@all the entire JSF view the entire JSF view tbd
@namingcontainer n/a Closest ancestor naming container of current component. tdb
@parent n/a parent of the current component parent of the current component
@composite n/a Closest composite component ancestor. n/a
@child(n) n/a nth child (not recommended) nth child (not recommended – very vulnerable to changes of the JSF page)
@row(n) n/a tbd
@previous n/a tbd
@next n/a successor of the current component successor of the current component
widgetVar(name) n/a component with the give widget variable n/a
@findId(id) n/a n/a finds an id in the tree, but restricted to the top-most level
*:id n/a n/a alternative writing to @findId(id)
@findIdRecursive(id) n/a n/a finds an id somewhere in the current tree
**:id n/a n/a alternative writing to findIdRecursive(id)
@findPartialId(id) n/a n/a find a partial ID in the top-most level of the current tree
*id n/a n/a finds the ids ending with “id” in the top-most level of the current tree
id* n/a n/a finds the ids starting with “id” in the top-most level of the current tree
*id* n/a n/a finds the ids containing “id” in the top-most level of the current tree
@findPartialIdRecursive(id) n/a n/a find the partial id somewhere in the tree
**:*id n/a n/a finds the ids ending with “id” somewhere in the current tree
**:id* n/a n/a finds the ids starting with “id” somewhere in the current tree
**:*id* n/a n/a finds the ids containing “id” somewhere in the current tree
@widget(name) n/a component with given widgetVar n/a

Wrapping it up

BootsFaces adds some Unix-like search expressions to find JSF component. Other than that, it largely strives for compatibility to PrimeFaces. Both frameworks provide far more powerful search expressions than standard JSF. And that’s a pity: as to my experience, advanced search expressions make programming JSF applications a lot more reliable, simple and even faster.


  1. Yes, I know: developers implementing re-inventing the wheel are every architect’s nightmare. Luckily I’m the architect in this case, so I can make my own rules.

4 thoughts on “JSF vs. PrimeFaces vs. BootsFaces Search Expressions

  1. In our project we implemented custom ID resolver solving problem with hierarchical ID. Example – “:formA:inputA” is referenced as “@jsfid(inputA)”. It is qute nice and we use it when referenced component is in another form. But it leads to fact that referenced IDs must be unique on the page.

  2. We overrided resolveComponent method in custom expression resolver class that is extended from org.primefaces.expression.SearchExpressionResolver. resolveComponent() method easily traverses components tree and searches for component ID. Resolver is registered in

    contextListener.contextInitialized(...) 
    

    using

    SearchExpressionResolverFactory.registerResolver("jsfid", new OurCustomExprResover()).
    

    Thats all work of one of my colleague, thank PeterS!

Leave a Reply

Your email address will not be published.