we are still in a JSF 1.2 to 2.0 migration scenario and we are now facing a problem related to c:set or ui:param variables used inside an EL expression.
Here are the facts. There is a button as composite component:
<cc:interface name="button" shortDescription="A button.">
...
<cc:attribute
name="disabled"
required="false"
default="false"
shortDescription="The disabled flag." />
...
</cc:interface>
<cc:implementation>
<ice:commandButton
...
disabled="#{cc.attrs.disabled}"
... />
</cc:implementation>
Now we are trying to use this button component inside a toolbar. The disabled state of the button is determined inside the toolbar using a c:set or a ui:param (we already tried both ways).
<c:set var="isButtonEnabled" value="#{backingBean.buttonEnabled}" />
or
<ui:param name="isButtonEnabled" value="#{backingBean.buttonEnabled}" />
#{isButtonEnabled}
<ctrl:button
...
disabled="#{!isButtonEnabled}"
... />
So here is our problem. If we simple print out the value of "isButtonEnabled" in the toolbar, it is always correct. So the backing bean is ok. But when we try to pass this value to the composite component, it is not working. "Disabled" is always evaluated to false.
Sure we could pass the method expression directly (#{!backingBean.isButtonEnabled}) and this will work fine. But in our scenario the determination of the enabled-flag is much more complicated and I just tried to keep the example as simple as possible. Aditionally this flag is used for multiple buttons inside the toolbar, so we wanted to keep the code maintainable by using a c:set or ui:param. Is this the wrong way to handle this? What do you recommend?
Thanks in advance.
SlimShady
Your problem is the way value binding is done in JSF. The prefered way is to retrieve the EL Expression an attribute was populated with by invoking
getValueExpression("attributeName")
. Then this EL Expression can be used to get or set the value in the backing bean. As your not passing#{!isButtonEnabled}
but#{cc.attrs.disabled}
toice:commandButton
the binding fails.I solved this for the
p:selectOneMenu
component of Primefaces by writing a wrappingUIComponent
which defines a propertywrappedValue
and passed that property to thep:selectOneMenu
. In the getter and setter of that property I then usedgetValueExpression
to retieve the real EL Expression for the attribute.The component can now be used the following way: