This is fairly simple using collections :)
JSF<h:form>
<h:selectManyMenu value="#{myBean.selectedItemsLeft}">
<f:selectItems value="#{myBean.selectItemsLeft}" />
</h:selectManyMenu>
<h:commandButton value="left to right" action="#{myBean.leftToRight}" />
<h:commandButton value="right to left" action="#{myBean.rightToLeft}" />
<h:selectManyMenu value="#{myBean.selectedItemsRight}">
<f:selectItems value="#{myBean.selectItemsRight}" />
</h:selectManyMenu>
</h:form>
MyBeanprivate List selectItemsLeft;
private List selectedItemsLeft;
private List selectItemsRight;
private List selectedItemsRight;
// with getters and setters
public void leftToRight() {
selectItemsLeft.removeAll(selectedItemsLeft);
selectItemsRight.addAll(selectedItemsLeft);
selectedItemsLeft.clear();
}
public void rightToLeft() {
selectItemsRight.removeAll(selectedItemsRight};
selectItemsLeft.addAll(selectedItemsRight};
selectedItemsRight.clear();
}
Hi BalusC
Thanks for your response.
The following code in Add Role method results in error
public String addRole() {
deviceRoles.addAll(selectedUserRoles);
return null;
}
ERROR:
javax.faces.FacesException: Collection referenced by UISelectItems with binding
'#{test.deviceRoles}' and Component-Path : {Component-Path : [Class:
org.ajax4jsf.framework.ajax.AjaxViewRoot,ViewId: /page.jsp][Class:
javax.faces.component.html.HtmlForm,Id: _id0][Class:
org.ajax4jsf.ajax.html.HtmlAjaxOutputPanel,Id: _id6][Class:
javax.faces.component.html.HtmlPanelGrid,Id: _id13][Class:
javax.faces.component.html.HtmlSelectManyListbox,Id: _id19][Class:
javax.faces.component.UISelectItems,Id: _id20]} <b>does not contain Objects of type
SelectItem
</b>
I fixed the error by hardcoding the values into Add Role method as shown below
public String addRole() {
deviceRoles.add(new SelectItem("10"," Admin"));
deviceRoles.add(new SelectItem("20"," Focal"));
deviceRoles.add(new SelectItem("30","Architect"));
return null;
}
So I guess the call to "selectedUserRoles" in deviceRoles.addAll(selectedUserRoles); should
return instances of SelectItem with Id and Value as arguments.
That means whenever users selects multiple values from user roles select box, the
setselectedUserRoles() method should recieve both Id and Value as instance of Select Item.
Hence i changed the declaration to
private List selectedUserRoles = new ArrayList<SelectItem>();
But not sure how to change the defination of setselectedUserRoles() method to recieve
instances of SelectItem with Id and Value as Arguments. Here is the defination
public void setSelectedUserRoles(List selectedUserRoles) {
this.selectedUserRoles = selectedUserRoles;
System.out.println("Setter this.selectedUserRoles "+ this.selectedUserRoles);//prints
only Id. I wanna print both Id and Value so
that i can pass bot Id and value to device roles
}
Any pointers/suggestions will be highly appreciated in this regard.
Here is the code snippet in backing bean :
--
TestBean.java (Backing Bean)
private List<Role> userRoles;
private List deviceRoles = new ArrayList<SelectItem>();
private List selectedUserRoles = new ArrayList<SelectItem>();
private List selectedDeviceRoles = new ArrayList<SelectItem>();
public List getSelectedUserRoles() {
System.out.println("Getter this.selectedUserRoles"+selectedUserRoles);
return selectedUserRoles;
}
public void setSelectedUserRoles(List selectedUserRoles) {
this.selectedUserRoles = selectedUserRoles;
System.out.println("Setter this.selectedUserRoles "+ this.selectedUserRoles);//prints
only Id. I wanna print both Id and Value so
that i can pass bot Id and value to device roles
}
public String addRole() {
deviceRoles.addAll(selectedUserRoles); //results in error "does not contain Objects
of type SelectItem"
return null;
}
Regards
Bansi
Excuse me. The code example was wrong and incomplete, but with the following generics you've got the point taken I think?
private List< SelectItem < T, String >> selectItemsLeft;
private List<T> selectedItemsLeft;
private List< SelectItem < T, String >> selectItemsRight;
private List<T> selectedItemsRight;
// with getters and setters
// and remove the spaces from generics .. the UBB/code parser of this forum just sucks ;)
public void leftToRight() {
// iterate through the lists and add/remove the selected values.
}
public void rightToLeft() {
// iterate through the lists and add/remove the selected values.
}
Hi BalusC
Thanks for generics. Yep i got the point taken.
Just wanna make sure .....
The method
public void leftToRight() { .....}
should have an argument like
public void leftToRight(selectedItemsLeft) { ......}
And what i am saying is the argument "selectedItemsLeft" shouldn't be of type List<T> . It should be of type List< SelectItem < T, String >>
The reason i say that is Whenever i select items from Left list boxand click on Add button it results in following error
"does not contain Objects of type SelectItem"
I guess what its complaining about is
- selectedItemsLeft, the argument to the method leftToRight() should be instances of SelectItem with Id and Value instead of List<T>
for example new SelectItem("10"," Admin")
Now what i am wondering is how do i change this argument to recieve instances of SelectItem
Please correct me if i am wrong
You are perfectly right.
- selectedItemsLeft is already set by the setter
- You have to iterate over the lists yourself to add/remove the items
I am iterating over the selected lists to see what exactly it has and found it to contain only Ids whereas i need both Ids and Values. So how do i change my selected lists to recieve both Ids and Values?
As i will be retrieving the values from Database i am not sure maintaining static instance of a Map with all possible keys and values will work for me
Regards
Bansi
What aboutprivate List selectItemsLeft;
private List selectedItemsLeft;
private List selectItemsRight = new ArrayList();
private List selectedItemsRight;
// + getters + setters
public void leftToRight() {
for (Iterator iter = selectItemsLeft.iterator(); iter.hasNext();) {
SelectItem selectItem = (SelectItem) iter.next();
if (selectedItemsLeft.contains(selectItem.getValue())) {
selectItemsRight.add(selectItem);
iter.remove();
}
}
selectedItemsLeft.clear();
}
public void rightToLeft() {
for (Iterator iter = selectItemsRight.iterator(); iter.hasNext();) {
SelectItem selectItem = (SelectItem) iter.next();
if (selectedItemsRight.contains(selectItem.getValue())) {
selectItemsLeft.add(selectItem);
iter.remove();
}
}
selectedItemsRight.clear();
}
// some getters and setters ..
public List getSelectItemsLeft() {
if (selectItemsLeft == null) {
selectItemsLeft = new ArrayList();
selectItemsLeft.add(new SelectItem("name1", "value1"));
selectItemsLeft.add(new SelectItem("name2", "value2"));
selectItemsLeft.add(new SelectItem("name3", "value3"));
selectItemsLeft.add(new SelectItem("name4", "value4"));
selectItemsLeft.add(new SelectItem("name5", "value5"));
}
return selectItemsLeft;
}
Assuming it is a session scoped bean.
Thanks it worked . But resulted in two side effects
1) A click on leftToRight button works fine only for the first time. Subsequent clicks will result in
- Adding selected value from the Left to Right (expected behaviour). But it also removes the older values from Right and adds it back to Left . Meticulously sacnned the code with debugging statements . Still not able to figure out the reason
2) A click on rightToLeft button with only selected values from right results in moving all the values from right to Left and also it clears the right list box
Again scanned the code with debugging statement & figured out
"setSelectedItemsRight" is not called in proper sequence
Any pointers/suggestions will be highly appreciated
Regards
Bansi
Hi BalusC
Thanks for helping.
I have following problem while setting the scope of backing bean in faces-config.xml
- If i set the backing bean scope to "request" in faces-config.xml then insertion happens fine at the persistence level (e.g. hibernateTemplate.save(Object obj)
- If i set the backing bean scope to "session" in faces-config.xml then insertion doesnt go thru at the persistence level . Wondering what could be the reason
The reason i switched to session scope is the JSF form has
- One drop down which automatically populates the remaining textfields on the form
-One h:selectManyListbox which populates all the possible user Roles
- Add /Remove h:commandButtons
- One h:selectManyListbox which gets populated with selected user roles on click of Add button. This will work only if i set the scope to session in faces-config.xml
Regards
Bansi
Hi BalusC,
I used the code that you have talked about in an example for using <h:selectManyListBox> at the following website/forum
http://balusc.xs4all.nl/frm/list_message/21777
But my selectedItemsLeft list is empty eventhough a selection has been made. The backing bean is in the session scope sas mentioned in the example.
What am I doing wrong?
Thank you