Our requirement is to implement af:selectManyShuttle with preselected values. New records in database table must be created according to selected values. If user change something in the selection, everything works fine. But if user agrees with default selection and does not want to do any changes and just submits a form, we have a problem – nothing is submitted.
af:selectManyShuttle is implemented with managed bean behind.
Component:
<af:selectManyShuttle value="#{pageFlowScope.MyBean.selectedValues}"
id="sms1"
leadingHeader="#{bundle.myHeader1}"
trailingHeader="#{bundle.myHeader2}">
<f:selectItems value="#{bindings.Id.items}" id="si3"/>
</af:selectManyShuttle>
Bean:
public class MyBean {
List selectedValues;
int shuttleCounter = 0;
public MyBean() {}
public void setSelectedValues(List selectedValues) {
// Do some processing for data persisting
}
public List getSelectedValues() {
if (this.selectedValues == null) {
this.selectedValues = new ArrayList();
//Some code to fill preselected values
} else if (this.shuttleCounter == 0) {
this.shuttleCounter++;
this.selectedValues.add(-1);
}
return this.selectedValues;
}
So why is this problem happening?
Select many shuttle on page load invokes getSeletedValues() to fill trailing list. Then when user edits form and press submit, getSelectedValues() is invoked again to check if something is changed. If there are changes in trailing list, component invokes setSelectedValues(List selectedValues) and everything is processed what is necessary. But if user doesn’t shuttle enything and leaves default pre-selected trailing list, component doesn’t see any changes ant it decides not to execute setSelectedValues(List selectedValues), because obviously there is no point to do that. But… here is no point only if we need to do update in some list. In our case we create pure new records and there is big point to execute setSelectedValues(List selectedValues) nevertheless the user has changed sometging or not.
What workaround could be?
Just to cheat component by returning fake changed selected list during the second getSelectedValues() invoke. In the sample I add “-1” index to force change. This index is not processed in setSelectedValues. af:selectManyShuttle just throws warning “Could not find value:-1 of type:java.lang.Integer among list of SelectItems” and process the rest as required.