Hi I have a problem about dynamically displaying the value of a HtmlSelectOneMenu. Below is a small application that describes my problem.
I have a list of cars List<Car> carList = new ArrayList<Car>() in my backing bean.
Car is a abstract class and Toyota and Ford extends Car.
Now I need to display different message in the selectonemenu based on the class type. If it is Toyota then I would display something else. Maybe its clearer for the codes to tell the story.
Backing Bean:
@ManagedBean(name="myBean")
@SessionScoped
public class MyCarBackingBean implements PhaseListener {
private List<Car> carList = new ArrayList<Car>();
private HtmlSelectOneMenu hsom;
Car myCar;
@PostConstruct
public void init() {
carList.add(new Ford());
carList.add(new Toyota());
}
@Override
public void beforePhase(PhaseEvent event) {
//hsom becomes null here. Im pretty sure the setHsom was called before and the variable was set.
if(hsom != null) {
switch((Integer)hsom.getValue()){
case 1: hsom.setValue("This is a Ford car"); break;
case 2: hsom.setValue("This is a Toyota car");
}
}
//The rest of the world...
}
And i bind the selectonemenu to the component in my page:
<h:form>
<h:selectOneMenu binding="#{myBean.hsom}">
<f:selectItems value="#{myBean.carList}" var="car" itemValue="#{car.id}" itemLabel="#{car.id}" />
</h:selectOneMenu>
<h:commandButton value="Submit" action="#{myBean.mySubmit()}"/>
</h:form>
And finally the model classes:
public abstract class Car {
protected int id;
//Getters and Setters
}
public class Toyota extends Car {
public Toyota(){
this.id = 2; //in case of ford car, id is 1.
}
}
And I’m thinking using a phase listener to change the display, cos I read some posts saying that it is bad to change the getters and setters and put business logic in them. Nor do I want to wrap those cars in other objects and make use of itemLabel and itemValue.
But when I was debugging it I found that hsom is null when the execution reaches beforePhase but it is not null in the rest part of the code.
So my questions are : is it a good way to use a phase listener for this? And why is the component object null in beforePhase?
Add a different attribute (say
description) to your class. Implement it as you like, and refer to it in theselectItemstag. V.g.Alternatively, replace
myBean.carListwith a method that returns aList<SelectItem>, and create theselectItemsas you wish.As a rule of thumb, try to keep the .xhtml as “logic-free” as possible.