RSS 2.0
Sign In
# Wednesday, October 7, 2009

Our experience with facelets shows that when you're designing a composition components you often want to add a level of customization. E.g. generate element with or without id, or define class/style if value is specified.

Consider for simplicity that you want to encapsulate a check box and pass several attributes to it. The first version that you will probably think of is something like this:

<html xmlns=""
        id - an optional id;
        value - a data binding;
        class - an optional element class;
        style - an optional element inline style;
        onclick - an optional script event handler for onclick event;
        onchange - an optional script event handler for onchange event.

Be sure, this is not what you have expected.  Output will contain all mentioned attributes, even those, which weren't passed into a component (they will have empty values). More than that, if you will omit "id", you will get an error like: "emtpy string is not valid id".

The reason is in the EL! Attributes used in this example are of type String, thus result of evaluation of value expression is coersed to String. Values of attributes that weren't passed in are evaluated to null. EL returns "" while coersing null to String. The interesting thing is that, if EL were not changing null then those omitted attributes would not appear in the output.

The second attept would probably be:

<h:selectBooleanCheckbox value="#{value}">
  <c:if test="#{!empty id}">
    <f:attribute name="id" value="#{id}"/>
  <c:if test="#{!empty onclick}">
    <f:attribute name="onclick" value="#{onclick}"/>
  <c:if test="#{!empty onchange}">
    <f:attribute name="onchange" value="#{onchange}"/>
  <c:if test="#{!empty class}">
    <f:attribute name="class" value="#{class}"/>
  <c:if test="#{!empty style}">
    <f:attribute name="style" value="#{style}"/>

Be sure, this won't work either (it may work but not as you would expect). Instruction c:if is evaluated on the stage of the building of a component tree, and not on the rendering stage.

To workaround the problem you should prevent null to "" conversion in the EL. That's, in fact, rather trivial to achieve: value expression should evaluate to an object different from String, whose toString() method returns a required value.

The final component may look like this:


where ex:object() is a function defined like this:

public static Object object(final Object value)
  return new Object()
    public String toString()
      return value == null ? null : value.toString();

A bit later: not everything works as we expected. Such approach doesn't work with the validator attribute, whereas it works with converter attribute. The difference between them is that the first attribute should be MethodExpression value, when the second one is ValueExpression value. Again, we suffer from ugly JSF implementation of UOutput component.

Wednesday, October 7, 2009 9:16:10 AM UTC  #    Comments [0] -
JSF and Facelets | Tips and tricks
All comments require the approval of the site owner before being displayed.
Home page

Comment (Some html is allowed: a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

[Captcha]Enter the code shown (prevents robots):

Live Comment Preview
<June 2024>
Total Posts: 387
This Year: 3
This Month: 0
This Week: 0
Comments: 1289
Locations of visitors to this page
The opinions expressed herein are our own personal opinions and do not represent our employer's view in anyway.

© 2024, Nesterovsky bros
All Content © 2024, Nesterovsky bros
DasBlog theme 'Business' created by Christoph De Baene (delarou)