I like to know how can i implement mutliple selections in ice:selectOneMenu. I have list of toys which is loaded at initilization of backing bean and in UI i have one table of toys where each row of toy has one column of selectOneMenu i.e toy functions. My problem is to show selected toy function in each row of toy. So far i am able to show selected function in selectOneMenu with following code but i do not know how can i implement different selections on different rows i mean i have only one property “selectedToyFunction” which is mapped to each row. I need to implement something like java.util.Map<ToyId,ToyFunction>. But i dont know how and where to handle such implementation.
JSPX
<ice:dataTable border="0" value="#{myBean.toys}" var="toy" scrollable="false" resizable="false">
<ice:column id="toyDetailRedirect" styleClass="smallColumn">
<ice:selectOneMenu styleClass="inputCombo" partialSubmit="true" valueChangeListener="#{myBean.redirectToToyFunctionDetail}" value="#{myBean.selectedToyFunction}">
<f:attribute name="toy" value="#{toy.id}" />
<f:selectItems value="#{myBean.toyFunctions}" />
</ice:selectOneMenu>
<f:facet name="header">
<ice:outputText value="Details" />
</f:facet>
</ice:column>
<ice:dataTable>
BackingBean
public class MyBean
{
//--- Services ---
private ToyService toyService;
//---- UI -----
private String selectedToyFunction;
private List<SelectItem> toyFunctions = new ArrayList<SelectItem>();
//--- properties
private List<Toy> toys = new ArrayList<Toy>();
private static final String DEFAULT_SELECTION ="--- Select ---";
private static final String FUNCTION_A ="A";
private static final String FUNCTION_B ="B";
private static final String FUNCTION_C ="C";
// ---- Logging ----
private final Logger logger = Logger.getLogger(MyBean.class);
public MyBean()
{
super();
}
@PostConstruct
public void loadToysAndPopulateToysFunctions( )
{
// loadToys
try
{
this.toys = this.toysService.findAllToys();
}
catch (Exception e)
{
this.logger.warn(e.getMessage());
this.logger.debug(e);
}
if ((this.toys == null) || this.toys.isEmpty())
{
/* Out if not toy has been found */
logger.debug("No Toy has been found !");
return;
}
// Populate default toy functions
this.populateToyFunctions();
}
private void populateToyFunctions( )
{
if ((this.toyFunctions == null) || this.toyFunctions.isEmpty())
{
this.toyFunctions = new ArrayList<SelectItem>();
this.toyFunctions.add(new SelectItem(DEFAULT_SELECTION));
this.toyFunctions.add(new SelectItem(FUNCTION_A));
this.toyFunctions.add(new SelectItem(FUNCTION_B));
this.toyFunctions.add(new SelectItem(FUNCTION_C));
}
//Default selection
this.selectedToyFunction = DEFAULT_SELECTION;
}
public void redirectToToyFunctionDetail(ValueChangeEvent e)
{
FacesContext.getCurrentInstance()
.getExternalContext()
.redirect("/Store/Details.jspx?id=" +e.getNewValue().toString());
}
// ---- Getters & Setters -----
public List<Toy> getToys( )
{
return this.toys;
}
public void setToys(List<Toy> toys)
{
this.toys = toys;
}
public List<SelectItem> getToyFunctions( )
{
return this.toyFunctions;
}
public void setToyFunctions(List<SelectItem> toyFunctions)
{
this.toyFunctions = toyFunctions;
}
public void setSelectedToyFunction(String selectedToyFunction)
{
this.selectedToyFunction = selectedToyFunction;
}
public String getSelectedToyFunction()
{
return this.selectedToyFunction;
}
}
You have 2 options:
Just bind the value to the currently iterated
Toyobject:And give the
Toyclass the appropriate property, if not done yet:This is the natural approach.
Bind the value to a common
Mapbean property as you suggested yourself:Make sure that you’ve prepared the
HashMapbeforehand:This is only the ugly approach. You probably need to manually copy/move all changes from/into the real
Toyobjects before preparing/persisting.