Reputation: 93
I have a p:autoComplete
PF element to deal with a POJO-suggestions list for which I've created a Converter
class to map POJOs into Strings and vice versa.
<p:autoComplete value="#{bean.pojoTargetList}" completeMethod="#{bean.getPOJOFilteredList}" var="pojo" itemLabel="#{pojo.name}"
itemValue="#{pojo}" converter="pojoConverter" />
The thing is I know how to procceed to map from a POJO to a String (getAsString()
method) but not how to do to map from a String to a POJO (getAsObject()
method).
@FacesConverter("pojoConverter")
public class POJOConverter implements Converter {
@Override
public Object getAsObject(FacesContext arg0, UIComponent uiComponent, String value) {
// ?
return pojo;
}
@Override
public String getAsString(FacesContext arg0, UIComponent uiComponent, Object assetTag) {
String _return = null;
...
return _return;
}
Maybe I'm wrong but my understanding is that the uiComponent
param of the getAsObject()
method is a reference to the p:autoComplete
PF element. If so, I could have access to the POJO-suggestions list. Therefore, I could iterate on it and and find the POJO object matching the value
param.
I'd really appreciate if someone could explain how can I access the pojo suggesion list of the p:autocomplete
element from the getAsObject()
method.
UPDATE:
Maybe I'm wrong but my understanding is that the uiComponent
param of the getAsObject()
method is a reference to the p:autoComplete
PF element. If so, I could have access to bean.getPOJOFilteredList
. Therefore, I could iterate on bean.getPOJOFilteredList
and find the POJO object matching the value
param.
Upvotes: 1
Views: 529
Reputation: 51
You can have access to the suggestion list and iterate it, by getting the completeMethod from the component and invoke it like this:
MethodExpression method = ((AutoComplete) component).getCompleteMethod();
List<Object> items = (List) method.invoke(facesContext.getELContext(), null);
for(Object item : items)
if(item.equals(value))
return item;
Now in your completeMethod you can add
public List<Object> yourAutoCompleteMethod(String query){
if(query == null) return list;
else
//fetch your data//
return list;
}
so the converter will immediately get the list that you previously calculated. By this way you have access to the suggestion list, without any injections or other mapping. It is plug and play.
Upvotes: 1
Reputation: 7505
Yes, a Converter
needs access to the objects he is expected to return. An implementation may look like this:
@FacesConverter("userConverter")
public class UserConverter implements Converter {
@Inject
UserDirectory userDirectory;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String uid) {
return uid == null || uid.isEmpty() ? null : userDirectory.findByUid(uid);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object user) {
final String uid = user instanceof User ? ((User) user).getUid() : null;
return StringUtils.defaultIfEmpty(uid, "");
}
}
The auto-complete method must be implemented independently and should return a list of the particular objects based on some partial input, being case-insensitive, etc.:
public List<User> autoCompleteUser(String queryString) {
// implement custom retrieval / filter logic
return filteredUsers;
}
Upvotes: 0