itemValue
property in p:autocomplete
can be used as a lightweight replacement of converters in just simple scenarios when you do not perform any update/refresh of the p:autocomple widget (which basically means you cannot perform update="@form"
or similar)
So basically there are 3 cases:
Pojo + Converter
Setting the attributue var
to some expression is mandatory to enable the "pojo mode" in PrimeFaces.
<p:autoComplete
value="#{backingBean.myPojo}"
completeMethod="#{backingBean.autocomplete}
var="pojo" itemLabel="#{pojo.label}"
itemValue="#{pojo}" converter="pojoConverter">
</p:autoComplete>
In this scenario var="pojo"
is an instance of class A. value="#backingBean.myPojo}"
is a variable of type A. itemValue="#{pojo}"
is evaluated when you ask for the suggestion list, the result is passed to the converter via getAsString
which produces the value to encode in html (eg.:v1
).
When you select an element from the list (eg.:v1
) it is passed back to the converter into getAsObject
which gives you in return an object of type A to set in the backing bean. The converter as usual has full responsibility in translating from Pojo to HTML value and vice versa.
public interface Converter {
// @return *K* the value to be used in html
// @param obj is provided by the expression (itemValue="#{pojo}")
public String getAsString(FacesContext context, UIComponent component, Object obj);
// build the pojo identified by String *K*
// @param value *K*
public Object getAsObject(FacesContext context, UIComponent component, String value);
}
Pojo + String
In this case you have a pojo with a String field to extract and to use in the backing bean.
<p:autoComplete value="#{backingBean.myStringValue}"
completeMethod="#{backingBean.autocomplete}
var="pojo" itemLabel="#{pojo.label}"
itemValue="#{pojo.stringKey}">
</p:autoComplete>
The flow is the same but
- itemValue must evaluate to a String to avoid ClassCasts.
- itemValue is used as html value directly (as if it was produced from the
Converter#getAsString
) and set to "#{backingBean.myStringValue}"
once selected.
"#{backingBean.myStringValue}"
must be a string of course.
Everything works fine until you try to perform refresh the p:autoComplete
widget (for example update="@form"). Primefaces re-evaluates the itemLabel
(because, for some reason, it does not store the itemLabel in the ViewState) using the value from the backing bean which is a String. Therefore you get the error. Actually there is no solution to this problem but to provide an implementation as in case 1).
Plain String Values
Not covered here.