ich verwende von PrimeFaces das AutoComplete control. Der Benutzer gibt einen Buchstaben ein und es werden auto. alle gespeicherten Kategorienamen die mit dem Buchstaben anfangen angezeigt, was auch funktioniert.
Wählt der Benutzer aus den vorgeschlagenen Kategorienamen einen aus, muss das ausgewählte “item” in das passende Category Objekt Konvertiert werden. Das entspricht dem value="#{CreateCategoryBean.newCategory.parent}"
Nun habe ich das problem, dass der Converter jedesmal mal bei KeyUP ausgeführt wird, aber nicht wenn man ein vorgeschlagenes item auswählt.
Habt ihr vielleicht eine Idee was ich ändern muss? Also beim KeyUp Event soll der Converter nicht ausgeführt werden, nur wenn man ein item auswählt.
Wieso eine Liste aus Strings? Wieso nutzt du nicht “var”, “itemlabel” und “itemValue”?
Dann hast du direkt das Objekt was auch convertiert werden kann. Mit <p:ajax event="itemSelect" listener="#{autoCompleteBean.handleSelect}"/>
kannst du dann auf das SelectEvent reagieren, sollte in der Bean irgendwie so aussehen:
public void handleSelect(SelectEvent event) {
//Caste es zu dem was es wirklich ist .....
}
Der Converter gibt auch das richtige Objekt zurück, wenn man in die autoComplete TextBox den vollen Namen einer Category eingibt. Wählt man jedoch aus den vorgeschlagenen Categories eine aus, springt der Converter nicht an, weshalb auch nicht CreateCategoryBean.newCategory.parent gesetzt wird.
Wenn ich wie im PrimeFaces Beispiel <f:validator validatorId=„Get.Validator.CategoryExistsValidator“ /> durch <p:autoComplete converter=„CategoryString“ > ersetze erhalte ich die Meldung Expression Error: Named Object: CategoryString not found. (Wenn ich CategoryStringConverter nehme kommt auch diese Meldung)
Das Category Objekt hat übrigens die Eigenschaften Name (String) Parent (Category).
Mein Converter sieht so aus:
@FacesConverter("Get.Converter.CategoryStringConverter")
public class CategoryStringConverter implements Converter {
public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
if (submittedValue.trim().equals("")) {
return null;
} else {
if (getCategoryEM() != null) {
for (Category category : getCategoryEM().findAll()) {
if (category.getName().equals(submittedValue)) {
return category;
}
}
} else {
throw new ConverterException(new Exception("getCategoryEM() is null"));
}
return null;
}
}
public String getAsString(FacesContext facesContext, UIComponent component, Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Category) value).getName());
}
}
public CategoryFacadeLocal getCategoryEM() {
return Utility.lookup(CategoryFacade.class);
}
Ich habe zusätzlich ein Feld players in der Klasse AutoCompleteBean anlegen müssen. Jetzt erhalte ich noch die Meldung Expression Error: Named Object: player not found. und ich glaube das liegt am
var="p" itemLabel="#{p.name}" itemValue="#{p}" converter="player" forceSelection="true"> ``` converter.
Wie kann ich das Problem aus der Welt schaffen?
also habs jetzt mal ohne CDI gemacht, aber so ungefair sollte es aussehen:
Die AutoCompleteBean:
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
/**
*
* @author martin
*/
@ManagedBean
@SessionScoped
public class AutoCompleteBean implements Serializable {
private Player selectedPlayer1;
private Player selectedPlayer2;
private List<Player> players;
@PostConstruct
public void init() {
players = PlayerConverter.playerDB;
}
public Player getSelectedPlayer1() {
return selectedPlayer1;
}
public void setSelectedPlayer1(Player selectedPlayer1) {
this.selectedPlayer1 = selectedPlayer1;
}
public Player getSelectedPlayer2() {
return selectedPlayer2;
}
public void setSelectedPlayer2(Player selectedPlayer2) {
this.selectedPlayer2 = selectedPlayer2;
}
public List<Player> completePlayer(String query) {
List<Player> suggestions = new ArrayList<Player>();
for (Player p : players) {
if (p.getName().startsWith(query)) {
suggestions.add(p);
}
}
return suggestions;
}
}
Und dann mal kurz erklären:
Foto habe ich rausgenommen, da du ja noch keine hast. Die Converter deklariere ich immer gerne als ManagedBeans, da diese später dann noch anderen Controller injecten können. @PostConstruct wird aufgerufen, wenn die Bean erstellt wird.