Hallo,
in einem Form gibt es eine ComboBox. Wenn das Form sofort abgesendet wird, funktioniert alles wie erwartet. Wird jedoch vorher ein anderer Wert in der ComboBox ausgewählt und dann erst submitted, dann wird ständig ein ValueChangeEvent ausgelöst. Eigentlich sollte ein ValueChangeEvent nur bei einer Änderung des Wertes in der ComboBox gefeuert werden, nicht jedoch bei einem Absenden des Forms. Zuerst dachte ich, die equals-Methode der ProjectEntity ist falsch doch das scheint nicht der Fall zu sein. Sie wurde auch von der IDE erzeugt. Ersetzt man ProjectEntity durch einen String, dann klappt es. Ich finde einfach den Fehler nicht.
Im Anhang das vollständige Beispiel als Maven-Modul. Bauen mit "mvn clean install". Das ear-File kann direkt z.B. auf einem Wildfly deployed werden.
Ähm, habe übrigens gesucht, wie man seine Beiträge optimal formatieren kann, aber bis auf diesen Editor nichts gefunden. Ich kenne nur das Code-Element. Wo finde ich mehr?
in einem Form gibt es eine ComboBox. Wenn das Form sofort abgesendet wird, funktioniert alles wie erwartet. Wird jedoch vorher ein anderer Wert in der ComboBox ausgewählt und dann erst submitted, dann wird ständig ein ValueChangeEvent ausgelöst. Eigentlich sollte ein ValueChangeEvent nur bei einer Änderung des Wertes in der ComboBox gefeuert werden, nicht jedoch bei einem Absenden des Forms. Zuerst dachte ich, die equals-Methode der ProjectEntity ist falsch doch das scheint nicht der Fall zu sein. Sie wurde auch von der IDE erzeugt. Ersetzt man ProjectEntity durch einen String, dann klappt es. Ich finde einfach den Fehler nicht.
Im Anhang das vollständige Beispiel als Maven-Modul. Bauen mit "mvn clean install". Das ear-File kann direkt z.B. auf einem Wildfly deployed werden.
Ähm, habe übrigens gesucht, wie man seine Beiträge optimal formatieren kann, aber bis auf diesen Editor nichts gefunden. Ich kenne nur das Code-Element. Wo finde ich mehr?
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel value="Projekt"
for="projectSelector"/>
<h:selectOneMenu id="projectSelector"
value="#{timeBean.model.projectSelected}"
converter="projectConverter"
onchange="submit()"
valueChangeListener="#{timeBean.projectChanged}"
immediate="true"
required="true">
<f:selectItems value="#{timeBean.model.allProjects}"
var="singleProject"
itemValue="#{singleProject}"
itemLabel="#{singleProject.name}"/>
</h:selectOneMenu>
<h:message for="projectSelector"/>
</h:panelGrid>
<h:panelGrid columns="1">
<h:commandButton value="Absenden"
action="#{timeBean.myAction}"
ajax="false"/>
<h:outputLabel value="#{timeBean.model.resultValue}" rendered="#{not empty timeBean.model.resultValue}"/>
</h:panelGrid>
</h:form>
</h:body>
</html>
Code:
public class ProjectEntity {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(final Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
final ProjectEntity that = (ProjectEntity) o;
System.out.println("equals comparing this " + this.getId() + " to that " + that.getId());
return id != null ? id.equals(that.id) : that.id == null;
}
@Override
public int hashCode() {
return id != null ? id.hashCode() : 0;
}
@Override
public String toString() {
return "ProjectEntity{" + "id=" + id + ", name='" + name + "'}";
}
}
Code:
public class TimeModel {
private ProjectEntity projectSelected;
private List<ProjectEntity> allProjects;
private String resultValue = "presetValue";
... getters und setters ...
}
Code:
@Named
@ViewScoped
public class TimeBean implements Serializable {
@Inject
private ValueProvider valueProvider;
@Inject
private Logger log;
private TimeModel model;
@PostConstruct
public void init() {
model = new TimeModel();
final List<ProjectEntity> allProjects = valueProvider.getAllProjects();
model.setAllProjects(allProjects);
model.setProjectSelected(allProjects.get(0));
}
public String myAction() {
log.info("myAction called");
model.setResultValue("action was called");
return null;
}
public void projectChanged(final ValueChangeEvent event) {
final ProjectEntity projectSelected = (ProjectEntity) event.getNewValue();
log.info("value changed from " + model.getProjectSelected().getId() + " to " + projectSelected.getId());
model.setProjectSelected(projectSelected);
final FacesContext context = FacesContext.getCurrentInstance();
context.renderResponse();
}
public TimeModel getModel() {
return model;
}
public void setModel(TimeModel model) {
this.model = model;
}
}
Code:
@FacesConverter(value = "projectConverter")
public class ProjectConverter implements Converter {
@Inject
private ValueProvider valueProvider;
@Override
public Object getAsObject(final FacesContext facesContext, final UIComponent uiComponent, final String projectName) throws ConverterException {
if (StringUtils.isEmpty(projectName)) {
return null;
}
final List<ProjectEntity> projects = valueProvider.getAllProjects();
for (ProjectEntity project : projects) {
if (StringUtils.equals(projectName, project.getName())) {
return project;
}
}
throw new ConverterException("1");
}
@Override
public String getAsString(final FacesContext facesContext, final UIComponent uiComponent, final Object value) throws ConverterException {
if (value == null) {
return null;
}
if (value instanceof ProjectEntity) {
return ((ProjectEntity) value).getName();
}
throw new ConverterException("2");
}
}