问题
I read on SO some QA about the same component, but I feel I'm missing something, because I am one step behind. I can't even make the page open when using the primefaces autocomplete component in it. The snippet for it is:
<p:autoComplete value="#{indirizzoCtrl.selectedCodiceNazione}"
completeMethod="#{indirizzoCtrl.completeNazione}"
var="nazione" itemLabel="#{nazione.nome}"
itemValue="#{nazione.codiceNazione}" />
Nazione is a Pojo class where CodiceNazione
and Nome are
two String field (with getter and setter for sure). completeNazione
is a method on the ManagedBean that returns List<Nazione>
.
Looking at BalusC explanation here, it seems to me that i don't need any converter involved, because both itemValue and value attributes are mapped to string property.
Anyway, when I just open the page containing this autocomplete snippet, it crashes with this error:
javax.el.PropertyNotFoundException: /Cliente/Indirizzo.xhtml @23,56 itemValue="#{nazione.codiceNazione}": itemValue="#{nazione.codiceNazione}": Property 'codiceNazione' not found on type java.lang.String
Why this is happening? I really can't get it. The method completeNazione hasn't even called yet, so it shouldn't know any Nazione
yet.
What's wrong with it?
Edited: Following the suggestion, I tried to add a converter, but I still get the same error. Here's my converter:
public class NazioneConverter implements Converter {
final static Logger log = Logger.getLogger(NazioneConverter.class);
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value.trim().equals("")) {
return null;
} else {
try {
IndirizzoRepository ir = new IndirizzoRepository();
List<Nazione> nazioni = ir.getNazioneByName(value);
if (nazioni.size()==1) return nazioni.get(0);
else throw new Exception();
} catch (Exception e) {
String msg = "Errore di conversione";
log.error(msg, e);
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, "Non è una nazione conosciuta"));
}
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Nazione) value).getNome());
}
}
}
now the component in the view looks like:
<p:autoComplete value="#{indirizzoCtrl.indirizzo.nazione.codiceNazione}"
completeMethod="#{indirizzoCtrl.completeNazione}"
var="nazione" itemLabel="#{nazione.nome}" converter="#{nazioneConverter}"
itemValue="#{nazione.codiceNazione}" forceSelection="true" />
But still don't working. The converter is not even invoked: I registered it in my faces-config.xml file.
I also tried itemValue="#{nazione}" as in the primefaces showcase but the problem became the ItemLabel
attribute, mapped to nazione.nome
.
What am I doing wrong?
回答1:
This worked for me:
//Converter
@FacesConverter(value="MarcaConverter")
public class MarcaConverter implements Converter{
MarcaDAO marcaDAO;
public Object getAsObject(FacesContext contet, UIComponent component, String value) {
if(value==null || value.equals(""))
return null;
try{
int id = Integer.parseInt(value);
return marcaDAO.findMarcaById(id);
}catch (Exception e) {
e.printStackTrace();
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Marca no válida", ""));
}
}
public String getAsString(FacesContext contet, UIComponent component, Object value) {
if(value==null || value.equals(""))
return null;
return String.valueOf(((Marca)value).getCodigoMarca());
}
}
//--------------------------------------
//Bean
@ManagedBean
@ViewScoped
public class MyBeans implements Serializable{
private Marca marca;
...
public Marca getMarca(){
return marca;
}
public void setMarca(Marca m){
marca=m;
}
...
public List<Marca> obtenerMarcasVehiculos(String s) {
List<Marca> marcas,smarcas=new ArrayList<Marca>();
try{
marcas= marcaDAO.findAllMarcas();
if(s.trim().equals("")) return marcas;
for(Marca m:marcas)
if (m.getNombreMarca().toString().contains(s) || m.getNombreMarca().toLowerCase().contains(s.toLowerCase())) {
smarcas.add(m);
}
return smarcas;
}catch(Exception e){
//JsfUtil.showFacesMsg(e,"Error al obtener las marcas de vehículos","",FacesMessage.SEVERITY_WARN);
e.printStackTrace();
JsfUtil.lanzarException(e);
return null;
}
}
//-----------------------------------------
//*.xhtml page
...
<p:autoComplete
id="cbxMarca" value="#{myBean.marca}" size="40"
converter="MarcaConverter"
completeMethod="#{myBean.obtenerMarcasVehiculos}"
var="m" itemLabel="#{m.nombreMarca}" itemValue="#{m}"
forceSelection="true" dropdown="true"
required="true" scrollHeight="200">
</p:autoComplete>
...
//-----------------------------------------
//Class Marca
public class Marca implements Serializable{
private static final long serialVersionUID = 1L;
private Integer codigoMarca;
private String nombreMarca;
...
回答2:
Have you read the user guide? http://www.primefaces.org/documentation.html
I must say I have never used the autocomplete with pojo but from what I've read in the user guide, Çağatay Çivici says there:
Note that when working with pojos, you need to plug-in your own converter.
Here you can find out that a converter (PlayerConverter
) is implemented even if player.name
and of the other props are Strings.
I admit this is interesting and I'll do some research but I don't have the necessary time right now...
回答3:
Change
converter="#{nazioneConverter}"
to converter="nazioneConverter"
in autocomplete
回答4:
Change the itemValue
from itemValue="#{nazione.codiceNazione}"
to itemValue="#{nazione}"
in autoComplete.
来源:https://stackoverflow.com/questions/8560073/primefaces-autocomplete-with-pojo