Adding items using h:selectManyMenu

I am looking for sample code to add/remove items from one h:selectManyMenu to other h:selectManyMenu using Add/Remove buttons. Using this component i would like to add user rolesThanks for your time in advanceRegardsBansi
[249 byte] By [mail2bansia] at [2007-11-26 14:58:21]
# 1

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();

}

BalusCa at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

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

mail2bansia at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

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.

}

BalusCa at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

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

mail2bansia at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
The argument is not needed. The selectedItemsLeft is already set by the setter. You have to iterate over the lists yourself to add/remove the items. It might be a good practice to keep a static instance of a Map which holds all possible keys and values.
BalusCa at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

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

mail2bansia at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

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.

BalusCa at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

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

mail2bansia at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9
Your bean is still set to request scope. Change it to session scope, like I stated at the end of my last reply here above =)If wou want to use the request scope anyway, then there are code changes needed. E.g. putting the selectItems in a sessionmap or make them static.
BalusCa at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10
Thank you so much. It works like magic. The Duke dollars are your now :)-
mail2bansia at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11

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

mail2bansia at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 12

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

TomaHawk-Newbiea at 2007-7-8 8:47:11 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...