I am learning how to use events with JSF. For some reason, the program is not changing the value in the text field when I change the value of the dropdown menu. The page loads and shows "Germany", but does not change the text field to "DE". Any suggestions?
Index.xhtml:
<?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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<f:view>
<h:form>
<h:selectOneMenu value="#{Bean.selectedItem}" valueChangeListener="#{Bean.changeEvent}" onchange="submit()" >
<f:selectItems value="#{Bean.itemsList}" />
</h:selectOneMenu>
<br />
<h:inputText value="#{Bean.selectedItem}" />
</h:form>
</f:view>
</h:body>
MyBean.java
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import java.util.ArrayList;
import javax.faces.model.SelectItem;
import javax.faces.event.ValueChangeEvent;
@ManagedBean (name = "Bean")
@RequestScoped
public class MyBean {
private static ArrayList menuItems;
private String selectedItem = "EN";
static {
menuItems = new ArrayList();
menuItems.add(new SelectItem("EN", "English"));
menuItems.add(new SelectItem("DE", "Germany"));
}
public ArrayList getItemsList() {
return this.menuItems;
}
public void setSelectedItem(String item) {
this.selectedItem = item;
}
public String getSelectedItem() {
return selectedItem;
}
public void changeEvent(ValueChangeEvent e) {
selectedItem = e.getNewValue().toString();
}
}
You're basically abusing the valueChangeListener
as an actionListener
. The value change listener is intented to have access to both the old and new value, right in between when the new input value is been submitted and the model value is been updated, so that you can for example add a log entry about the value change. You are apparently not interested in the old value. You're not interested in the value change event at all. You're only interested in the new model value. So you shouldn't be using the value change listener at all.
Normally, you'd like to do this job in an action listener method. You can use <f:ajax>
to define an ajax action listener:
<h:selectOneMenu value="#{Bean.selectedItem}">
<f:selectItems value="#{Bean.itemsList}" />
<f:ajax execute="@this" listener="#{Bean.changeEvent}" render="input" />
</h:selectOneMenu>
<h:inputText id="input" value="#{Bean.selectedItem}" />
with
public void changeEvent() {
selectedItem = selectedItem;
}
But since you've bound the input to the same property as the dropdown, the whole listener is superfluous. Just the following should do it for you:
<h:selectOneMenu value="#{Bean.selectedItem}">
<f:selectItems value="#{Bean.itemsList}" />
<f:ajax execute="@this" render="input" />
</h:selectOneMenu>
<h:inputText id="input" value="#{Bean.selectedItem}" />
The problem which you're seeing is because the onchange="submit()"
essentially submits the whole form, including all other input fields. As JSF processes input fields in sequence and you've bound the both fields to the same property, the value of <h:inputText>
will override the value of <h:selectOneMenu>
. As per my comment on the question, you would not have this problem when you made it a <h:inputText readonly="true">
or a <h:outputText>
(so that it won't submit its value to the server).
Change this to output text component and see if it works
<h:inputText value="#{Bean.selectedItem}" />
to
<h:outputText value="#{Bean.selectedItem}" />
Regards!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With