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.
>
>

Reply via email to