I am using JSF 2.2 (Mojarra), PrimeFaces 4, Tomcat 7 I have two interdependent Autocomplete fields in a ui:repeat. When I select something in the first autocomplete, I need to set the value of the second and vice versa.
<ui:repeat var="anItem" value="#{aBean.itemList}" varStatus="status">
<p:inputText id="someId1" value="anItem.operation" required="true"/>
<p:autoComplete id="nature" dropdown="true" forceSelection="true" value="#{anItem.nature}" completeMethod="#{myController.completeNatureList}">
<p:ajax event="itemSelect" listener="#{myController.selectNature(status.index)}" process="@this" update="code"/>
</p:autoComplete>
<p:autoComplete id="code" dropdown="true" forceSelection="true" value="#{anItem.code}" completeMethod="#{myController.completeCodeList}">
<p:ajax event="itemSelect" listener="#{myController.selectCode(status.index)}" process="@this" update="nature"/>
</p:autoComplete>
</ui:repeat>
My beans
@ManagedBean(name = "aBean")
@ViewScoped
public class Bean implements Serializable {
List<Item> itemList;
// getter and setter
}
public class Item implements Serializable {
private String operation;
private String nature;
private String code;
// getter and setter
}
And my controller looks like this :
@ManagedBean(name = "myController")
@ViewScoped
public class Controller implements Serializable {
@ManagedProperty(value = "#{aBean}")
private Bean aBean;
@Override
public void selectNature(final int pIndex) {
LOGGER.debug("Nature selected");
// business logic
this.aBean.getItemList().get(pIndex).setCode("code from business logic");
}
@Override
public void selectCode(final int pIndex) {
LOGGER.debug("Code selected");
// business logic
this.aBean.getItemList().get(pIndex).setNature("nature from business logic");
}
}
The first time I select something in the first Autocomplete, it works fine. But if I then select something in the second Autocomplete, my first Autocomplete is not updated. And if I reselect something in the first Autocomplete, this does not work anymore. The logs tell me my controller is always called.
I tryed to update the whole form and it works every time, but I cannot afford that of course, because of all the required fields in my form.
<p:ajax event="itemSelect" listener="#{myController.selectNature(status.index)}" process="@this" update="@form"/>
So my model is correctly updated, the problems seems to be the update of an already processed field in the render phase.
I do not wish a workaround because I have plenty of similar cases. I would like to understand why JSF behave like this and what I did wrong, any idea why ?
EDIT
Looking at this post How to address a component inside a looping naming container, I tried with a c:foreach instead of a ui:repeat, and it works !
So now I would just like to understand why my old solution with ui:repeat only worked once.