I am creating web application using JSF 2.0 where I am assigning users to view projects. For that I have two list. First list that have users who are not assigned that proje
To the point, your concrete problem is caused by the mistake that you filled listbox items using JavaScript/jQuery instead of JSF. This way JSF is never been made aware of the new items added by JavaScript. You need to fill the listbox items using JSF instead of JavaScript/jQuery.
When you submit a form with an UISelectOne
/UISelectMany
component, then JSF will always compare the submitted value to the list of available items from <f:selectItem(s)>
. If the submitted value is not contained in the list of available items, then you will get exactly this Validation Error: Value is not valid
error. This is part of builtin safeguard against tampered/attacked requests. The client should not be able to submit a item which the server has not specified.
Changing the available items in JavaScript/jQuery side does not automagically also change the available items in JSF <f:selectItems>
side as well. You really need to change the available items in JSF side. You can easily use the JSF 2.x ajax powers for this. Here's a concrete kickoff example:
<h:form>
<h:panelGrid columns="3">
<h:selectManyListbox id="left" value="#{bean.leftSelected}">
<f:selectItems value="#{bean.leftAvailable}" />
<f:ajax event="dblclick" render="left right" listener="#{bean.leftToRight}" />
</h:selectManyListbox>
<h:panelGroup>
<h:commandButton value="left to right">
<f:ajax execute="left" render="left right" listener="#{bean.leftToRight}" />
</h:commandButton>
<br/>
<h:commandButton value="right to left">
<f:ajax execute="right" render="left right" listener="#{bean.rightToLeft}" />
</h:commandButton>
</h:panelGroup>
<h:selectManyListbox id="right" value="#{bean.rightSelected}">
<f:selectItems value="#{bean.rightAvailable}" />
<f:ajax event="dblclick" render="left right" listener="#{bean.rightToLeft}" />
</h:selectManyListbox>
</h:panelGrid>
</h:form>
with
@ManagedBean
@ViewScoped
public class Bean {
private List<String> leftSelected;
private List<String> leftAvailable;
private List<String> rightSelected;
private List<String> rightAvailable;
@PostConstruct
public void init() {
leftAvailable = new ArrayList<String>(Arrays.asList("one", "two", "three", "four", "five"));
rightAvailable = new ArrayList<String>();
}
public void leftToRight() {
leftAvailable.removeAll(leftSelected);
rightAvailable.addAll(leftSelected);
leftSelected = null;
}
public void rightToLeft() {
rightAvailable.removeAll(rightSelected);
leftAvailable.addAll(rightSelected);
rightSelected = null;
}
// Add/generate getters+setters. Note: the "available" lists doesn't need setters.
}
That's all. No JS/jQuery mess necessary. When using custom non-string objects don't forget to provide a proper converter and equals()
method.