0

I'm trying to create a selectOneMenu using primefaces 5.2, the list items are loaded from a database, and their type is an Object which contains other attributes, I wanted to copy the primefaces showcase method (the Advanced one), but the selected value is never assigned, here is my code:

 <h:form id="f">
                    <p:selectOneMenu id="advanced" value="#{expertiseController.selectedExpertise}" converter="expertiseConverter">
                        <f:selectItems value="#{expertiseController.expertises}" var="exp" itemLabel="#{exp.id}" itemValue="#{exp}" />
                        <p:ajax update="test" />
                    </p:selectOneMenu>

                    <p:outputLabel id="test" value="#{expertiseController.selectedExpertise.id}"/>
                </h:form>

the bean:

@Named(value = "expertiseController")
@ViewScoped
public class ExpertiseController implements Serializable {

    private Expertise selectedExpertise = new Expertise();
    private List<Expertise> expertises = Expertise.getAllExpertiseTypes();
....
getters ..

the Converter:

FacesConverter("expertiseConverter")
public class ExpertiseConverter implements Converter {

    public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
        if(value != null && value.trim().length() > 0) {
            try {
                return Expertise.getById(value);
            } catch(Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        else {
            return null;
        }
    }

    public String getAsString(FacesContext fc, UIComponent uic, Object object) {
        if(object != null) {
            return String.valueOf(((Expertise) object).getId());
        }
        else {
            return null;
        }
    }   
}   

but the outputLabel is never set, and the setter method of the selectedExpertise is never fired. Now this only happenes when i set the itemValue to #{exp}, but when i set it like to #{exp.id} (and change the selectOneMenu value ofcourse) everything works. I even checked the converter values, they are both fine. And the problem is when i try the primefaces example it works well! when i change it to my Object and converter it dosnt!

What am i missing or doing wrong here?

UPDATE: I just figured out that you have to return in the converter the same object from the list, here s what i did, I injected the ExpertiseController in the ExpertiseConverter, then i loop through the list of the ExpertiseController and returned the same object (same address i guess or something), here is the code:

import com.medisecretaire.controller.ExpertiseController;
import com.medisecretaire.model.Expertise;
import java.io.Serializable;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;

@FacesConverter("expertiseConverter")
public class ExpertiseConverter implements Converter, Serializable {

    @Inject
    private ExpertiseController controller;


    public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
        System.out.println(controller.getExpertises());
        if(value != null && value.trim().length() > 0) {
            try {
                for (Expertise expertise : controller.getExpertises()) {
                    if(expertise.getId().equalsIgnoreCase(value)){
                        return expertise;
                    }
                }

                return null;
            } catch(Exception e) {
                return null;
            }
        }
        else {
            return null;
        }
    }

    public String getAsString(FacesContext fc, UIComponent uic, Object object) {
        if(object != null) {
            return String.valueOf(((Expertise) object).getId());
        }
        else {
            return null;
        }
    }   
}       

But is there a better way to do it? i didnt like the "injecting" part ... or is it normal?

UPDATE 2: when i add filter="true" it does not work anymore .. this is confusing ...

UPDATE 3: I knew there was a better way! so i grabbed the UIComponent extracted the SelectOneMenu iterated over its children and found the UISelectItems, from there i found the same objects stored in a list, here is the code:

public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
        List list = null;

        SelectOneMenu menu = (SelectOneMenu) uic;
        for (UIComponent comp : menu.getChildren()) {
            if (comp instanceof UISelectItems) {
                UISelectItems item = (UISelectItems) comp;
                if (item.getValue() instanceof List) {
                    list = (List) item.getValue();
                }
            }
        }
        //Do something with the list

and ever with the filer attribute it works now.

Ouerghi Yassine
  • 1,835
  • 7
  • 43
  • 72
  • Where are you using the 'advanced' part? And I doubt a converter like you created is needed, since the 'advanced example' does not either. I'd revisit my code – Kukeltje Apr 16 '15 at 05:57
  • did you open the primefaces showcase for the SelectOneMenu component? the 4th example the put (labeled "Advanced"), the one with the themes .. uses converter – Ouerghi Yassine Apr 16 '15 at 06:39
  • Yes, I did, but did **you** have a good look? It uses a **simple** converter and it uses columns to display things. You don't have the latter, so you do not use any advanced stuff – Kukeltje Apr 16 '15 at 06:45
  • I just meant by "Advanced" the reference of the exact example ... and i used (like in the primefaces example) the `itemValue` attribute with an Object attached to it (not just a simple String or an int) – Ouerghi Yassine Apr 16 '15 at 06:52
  • Good luck then with your workaround… (your example is a 'simple' one with just a converter. Should work with a plain jsf one to…) – Kukeltje Apr 16 '15 at 06:56

0 Answers0