I have multiple selectInputText controls inside a datatable, something like this:
<ice:dataTable id="attributesList" value="#{myForm.myAttributes}" var="entry" cellpadding="0" rows="9999" columnClasses="myColumn,myColumn">
<ice:column>
<!-- auto-complete -->
<ice:panelGroup>
<ice:selectInputText rows="15" width="120" maxlength="255" value="#{entry.attribute.stringValue}" valueChangeListener="#{myFieldAutocomplete.updateList}" immediate="true">
<f:selectItems value="#{myFieldAutocomplete.list}" />
<f:attribute name="fieldName" value="#{entry.name}" />
</ice:selectInputText>
</ice:panelGroup>
</ice:column>
</ice:dataTable>
My backing bean code is this:
public class myFieldAutocomplete {
// default value, empty string
private String currentFieldValue = "";
// list of possible matches.
private List<SelectItem> matchesSIList = new ArrayList<SelectItem>();
public void updateList(ValueChangeEvent event) {
currentFieldValue = "";
// get a new list of matches.
setMatches(event);
if (event.getComponent() instanceof SelectInputText) {
SelectInputText autoComplete = (SelectInputText) event.getComponent();
if (autoComplete.getSelectedItem() != null) {
currentFieldValue = (String) autoComplete.getSelectedItem().getValue();
}
else {
String tempValue = getMatch(autoComplete.getValue().toString());
if(tempValue != null) {
currentFieldValue = tempValue;
}
}
}
}
public String getCurrentFieldValue() {
return currentFieldValue;
}
public List<SelectItem> getList() {
return matchesSIList;
}
private String getMatch(String value) {
String result = null;
if (matchesSIList != null) {
String str;
Iterator<SelectItem> itr = matchesSIList.iterator();
while (itr.hasNext()) {
SelectItem si = (SelectItem) itr.next();
str = (String) si.getValue();
if (str.startsWith(value)) {
result = str;
break;
}
}
}
return result;
}
public void setMatches(ValueChangeEvent event) {
List<String> newMatchesStrList = new ArrayList<String>();
if (event.getComponent() instanceof SelectInputText) {
SelectInputText autoComplete = (SelectInputText) event.getComponent();
myClassDAO myDao = (myClassDAO) Context.getInstance().getBean(myClassDAO.class);
String fieldName = (String) autoComplete.getAttributes().get("fieldName");
newMatchesStrList = myDao.findTemplateFieldValues((String)autoComplete.getValue(), fieldName);
}
// assign new matchList
if (this.matchesSIList != null) {
this.matchesSIList.clear();
}
Iterator<String> itr = newMatchesStrList.iterator();
while(itr.hasNext()) {
String str = (String) itr.next();
matchesSIList.add(new SelectItem(str, str));
}
}
}
The bean is in request scope (although I also tried with session scope). I am using ICEfaces community edition 1.8.2.
The problem is, these auto-complete controls are created dynamically based on certain attributes of each entry in the datatable. So, you can have, for example 2 or more such auto-complete controls in the same panelGroup. When this is the case, when you start typing something the first control, it seems to be triggering the event for all sibling auto-complete controls, and in the end returns the list for the last in order. In general, I noticed erratic behavior caused by the fact that the event is triggered for all auto-complete controls at once, and values/lists get confused.
What am I doing wrong?
Thanks in advance!