Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSF 2 <f:selectItems> not recognizing itemLabel and itemValue attributes

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...
}
like image 733
holic87 Avatar asked Dec 29 '25 06:12

holic87


1 Answers

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}" />
like image 180
BalusC Avatar answered Dec 30 '25 22:12

BalusC



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!