Primefaces autocomplete with POJO and String value [duplicate]

ぐ巨炮叔叔 提交于 2019-12-03 22:20:12
Marco Bettiol

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

  1. itemValue must evaluate to a String to avoid ClassCasts.
  2. itemValue is used as html value directly (as if it was produced from the Converter#getAsString) and set to "#{backingBean.myStringValue}" once selected.
  3. "#{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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!