Hi, do you have an h:message/s component in your page to see if there is a validation error. Moreover, maybe the great information about the immediate attribute in this page can help you:
http://wiki.apache.org/myfaces/How_The_Immediate_Attribute_Works Cheers, Bruno On 28/08/2007, tfuda <[EMAIL PROTECTED]> wrote: > > Hello, > > I'm using MyFaces 1.1. I'm trying to update controls on a page when the user > changes the selection in a dropdown list. I can't quite seem to get it to > work as expected. Changes in the dropdown list do not seem to be firing the > value change event. When my dropdown list is populated with simple strings, > things seem to work just fine. I tried to simplify the problem by reducing > it down to just a single control on the page. For example, I have the > following JSP: > > <h:selectOneMenu id="colorsDDL" value="#{TestBean.colorValue}" > immediate="true" valueChangeListener="#{TestBean.processColorChange}" > onchange="this.form.submit();"> > <f:selectItems id="colorItems" value="#{TestBean.colorItems}" > /> > </h:selectOneMenu> > > My TestBean is a session scoped bean and the code is straightforward: > > import java.util.Date; > > import javax.faces.application.FacesMessage; > import javax.faces.component.UIComponent; > import javax.faces.component.UIInput; > import javax.faces.context.FacesContext; > import javax.faces.event.ValueChangeEvent; > import javax.faces.model.SelectItem; > import javax.faces.validator.ValidatorException; > > public class TestBean { > > public TestBean() { } > > private String colorValue = "Red"; > > public String getColorValue() { > return colorValue; > } > > public void setColorValue(String value) { > this.colorValue = value; > } > > private SelectItem[] colorItems = null; > > public SelectItem[] getColorItems() { > if (colorItems == null) { > colorItems = new SelectItem[3]; > colorItems[0] = new SelectItem("Red"); > colorItems[1] = new SelectItem("Green"); > colorItems[2] = new SelectItem("Blue"); > } > return colorItems; > } > > public void setColorItems(SelectItem[] items) { > this.colorItems = items; > } > > public void processColorChange(ValueChangeEvent evt) { > System.out.println("Event source: " + ((UIInput) > evt.getSource()).getId()); > System.out.println("Old value: " + evt.getOldValue()); > System.out.println("New Value: " + evt.getNewValue()); > } > } > > In this case, everything seems to work fine. The processColorChange method > is invoked when the dropdown list is changed, and the TestBean.setColorValue > method is invoked to update the model with the new value. > > Now comes the problem. I change my JSP as follows: > > <h:selectOneMenu id="employeeDDL" value="#{TestBean.employeeValue}" > immediate="true" valueChangeListener="#{TestBean.processEmployeeChange}" > onchange="this.form.submit();" converter="EmployeeConverter" > validator="#{TestBean.validateEmployee}"> > <f:selectItems id="employeeItems" > value="#{TestBean.employeeItems}" /> > </h:selectOneMenu> > > Note, that I am now using a converter and a validator. This is because my > dropdown list is being populated with object instances of the Employee > class, which looks like the following: > > public class Employee implements Serializable { > > String name=null; > Integer id=null; > Date dateOfHire=null; > > /** Creates a new instance of Employee */ > public Employee() { > } > > public Employee(String _name, Integer _id, Date _dateOfHire) { > this.name=_name; > this.id=_id; > this.dateOfHire=_dateOfHire; > } > > public String getName() { > return name; > } > > public void setName(String _name) { > this.name=_name; > } > > public Integer getId() { > return id; > } > > public void setId(Integer _id) { > this.id=_id; > } > > public Date getDateOfHire() { > return dateOfHire; > } > > public void setDateOfHire(Date _dateOfHire) { > this.dateOfHire=_dateOfHire; > } > > public String toString() { > return new String(name + ";" + id + ";" + dateOfHire); > } > } > > > I have written a Converter that looks like the following: > > import java.util.Date; > import javax.faces.component.UIComponent; > import javax.faces.context.FacesContext; > import javax.faces.convert.Converter; > > public class EmployeeConverter implements Converter { > > /** Creates a new instance of EmployeeConverter */ > public EmployeeConverter() { > } > > public String getAsString(FacesContext context, UIComponent component, > Object value) { > String empString = null; > if (value != null) { > empString = value.toString(); > } > return empString; > } > > public Object getAsObject(FacesContext context, UIComponent component, > String value) { > Employee empObject = null; > String[] fields = value.split(";"); > empObject = new Employee(); > empObject.setName(fields[0]); > empObject.setId(new Integer(fields[1])); > empObject.setDateOfHire(new Date(fields[2])); > return empObject; > } > } > > > > I have also written a validation method that basically does nothing other > than return, as long as the value passed to the validate method is an > instance of Employee. > > I've modified my TestBean code as follows: > > > > import java.util.Date; > > import javax.faces.application.FacesMessage; > import javax.faces.component.UIComponent; > import javax.faces.component.UIInput; > import javax.faces.context.FacesContext; > import javax.faces.event.ValueChangeEvent; > import javax.faces.model.SelectItem; > import javax.faces.validator.ValidatorException; > > public class TestBean { > > public TestBean() { } > > private Employee[] employees = new Employee[] { > new Employee("Andrew Anderson", new Integer("12345"), > new Date()), > new Employee("Bob Barker", new Integer("23456"), new > Date()), > new Employee("Clive Conners", new Integer("34567"), > new Date()) > }; > > private String employeeValue = employees[0].toString(); > > public String getEmployeeValue() { > return employeeValue; > } > > public void setEmployeeValue(String value) { > employeeValue = value; > } > > private SelectItem[] employeeItems = new SelectItem[] { > new SelectItem(employees[0], employees[0].getName()), > new SelectItem(employees[1], employees[1].getName()), > new SelectItem(employees[2], employees[2].getName()) > }; > > public SelectItem[] getEmployeeItems() { > return employeeItems; > } > > public void setEmployeeItems(SelectItem[] items) { > this.employeeItems = items; > } > > public void processEmployeeChange(ValueChangeEvent evt) { > System.out.println("Event source: " + ((UIInput) > evt.getSource()).getId()); > System.out.println("Old value: " + evt.getOldValue()); > System.out.println("New Value: " + evt.getNewValue()); > } > > > public void validateEmployee(FacesContext context, UIComponent > component, > Object value) > throws ValidatorException { > System.out.println("validate called "); > if (value instanceof Employee) > return; > else > throw new ValidatorException( > new FacesMessage("Validation failed. > Value is not an instance of > Employee.")); > } > } > > > I can see that the getAsString method in my EmployeeConverter is being > called when my page is rendered, I can also see that the getAsObject method > of my EmployeeConverter, and my validateEmployee method are being invoked > when a new value is selected within the dropdown. The object passed in to > the validateEmployee method is in fact an instance of the Employee class and > has the correct values (i.e., they match the selection from the dropdown), > however, the processEmployeeChange method is NOT being invoked, nor is the > setEmployeeValue method of my TestBean, so my model is not getting updated > with the new value either. I'm not sure if I'm doing something fundamentally > wrong here, or if I've stumbled across a bug or "feature". Please help. TIA. > > TF > -- > View this message in context: > http://www.nabble.com/JSF-Newbie-needs-help-with-selectOneMenu-and-valueChangeListener-tf4341404.html#a12366849 > Sent from the MyFaces - Users mailing list archive at Nabble.com. > >

