I want to dynamically create a dropdown (HtmlSelectOneMenu) with all possible options. The option currently set should be preselected. To achieve this I created a value expression for my form:
String jsfValue = String.format("#{%s.item.%s}", getControllerBeanName(), key);
ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, String.class);
menu.setValueExpression("value", valueExpression);
The string #{%s.item.%s}
evaluates to #{playlistController.item.category}
and category
is the object of type Category
that I want to bind to my dropdown.
To use the SelectItemsConverter
from OmniFaces I changed the toString()
method of Category
to:
@Override
public String toString() {
return String.format("%s[id=%d]", getClass().getSimpleName(), getId());
}
My code for the form generation looks like this (Note: Category
extends BaseEntity
):
private UIComponent createDropdown(FormInput property) {
String key = property.getKey();
String beanName = key + "Controller";
GenFormBaseController controller = (GenFormBaseController) JSFUtils.getManagedBean(beanName);
List<BaseEntity> list = controller.getService().findAll();
List<SelectItem> selectItems = new ArrayList<>(list.size());
for (BaseEntity itemInList : list) {
selectItems.add(new SelectItem(itemInList, itemInList.getName()));
}
UISelectItems items = new UISelectItems();
items.setValue(selectItems.toArray());
HtmlSelectOneMenu menu = new HtmlSelectOneMenu();
menu.setConverter(new SelectItemsConverter());
menu.setId(key);
menu.getChildren().add(items);
String jsfValue = String.format("#{%s.item.%s}", getControllerBeanName(), key);
ValueExpression valueExpression = JSFUtils.createValueExpression(jsfValue, String.class);
menu.setValueExpression("value", valueExpression);
return menu;
}
If I set menu.setConverter(new SelectItemsConverter());
then the wrong item is preselected. But If I remove it, then the correct item is selected but when I try to save the form it fails because it has no converter for the dropdown.
Can anyone help me? I've published the code on GitHub.
The method createDropdown
can be found at the bottom of the linked code.