I have the following dropdown in a Facelets page:
<h:selectOneMenu value="#{contactBean.selectedContact}" converter="#{contactConverter}">
<f:selectItems value="#{contactsHolder.contacts}" var="contact"
itemLabel="#{contact.firstName}" itemValue="#{contact}" />
</h:selectOneMenu>
The problem is, no matter what I put in for itemLabel (JSF EL expression or just plain text), it doesn't display. Any idea what I'm doing wrong?
Here's ContactConverter:
@ManagedBean(name = "contactConverter")
@RequestScoped
public class ContactConverter implements Converter, Serializable {
@ManagedProperty(value = "#{contactsHolder}")
private ContactsHolder contactsHolder;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return contactsHolder.getContacts().get(value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
return ((Contact) value).getContactID();
}
//getter & setters...
}
And ContactsHolder:
@ManagedBean
@SessionScoped
public class ContactsHolder implements Serializable {
private Map<String, Contact> contacts;
@PostConstruct
public void init() {
contacts = new LinkedHashMap<String, Contact>();
//get Contacts data and populate map...
}
//getters & setters...
}
You're feeding a Map<String, Contact> to <f:selectItems value>. Each item in var attribute will be a Map.Entry<String, Contact> which has only getKey() and getValue() methods returning the String map key and Contact map value respectively. The Map.Entry class indeed doesn't have a getFirstName() method.
Fix it accordingly:
<f:selectItems value="#{contactsHolder.contacts}" var="contact"
itemLabel="#{contact.value.firstName}" itemValue="#{contact.value}" />
Or, if you target a Servlet 3.0 / EL 2.2 capable container which allows invoking non-getter methods, so that you can use Map#values() to get a Collection<Contact>:
<f:selectItems value="#{contactsHolder.contacts.values()}" var="contact"
itemLabel="#{contact.firstName}" itemValue="#{contact}" />
Or, make the #{contactsHolder.contacts} a List<Contact> instead so that your initial view code will work:
<f:selectItems value="#{contactsHolder.contacts}" var="contact"
itemLabel="#{contact.firstName}" itemValue="#{contact}" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With