I tried to organize the question in such a way it is easy to read... thus to answer . Of course, through any question you may need for better understanding of the problem.
--------------------------------------------
CONTEXT :
I am successfully dynamically creating AutoComplete components with this code :
Code: Select all
// iNmbConditions is an 'int'
// cCondPanel is a 'UIComponent' panel
// utils.createMethodExpression(String expression, Class<?> returnType, Class<?>... parameterTypes) is a method successfully creating ValueMethods
// Creating the AutoComplete component
AutoComplete cAutoComplete = new AutoComplete();
// Setting general attributes
cAutoComplete.setId("critValue_" + iNmbConditions);
cAutoComplete.setMultiple(true);
cAutoComplete.setDropdown(true);
cAutoComplete.setScrollHeight(250);
cAutoComplete.setForceSelection(true);
// Setting the VALUE and CompleteMethod
cAutoComplete.setValueExpression("value", utils.createValueExpressionOnClass("#{dtColumnsQuery.critValuesMulti}",List.class));
cAutoComplete.setCompleteMethod(utils.createMethodExpression("#{dtColumnsQuery.completeValue}", null, String.class));
// Attaching the AutoComplete component to the panel
cCondPanel.getChildren().add(cAutoComplete);
Code: Select all
public List<String> completeValue(String query, AjaxBehaviorEvent e) {
List<String> results = new ArrayList<String>();
// aColumnName should be dynamically initialized with a LIST,
// with index selected as same as the ID of the AutoComplete which called this method
String aColumnName = "FIRST_NAME";
// SQL built on the ColumnName,
// TODO should be stored in a LIST, and not re-fired each time (see next TODO)
String aSQL = "SELECT DISTINCT " + aColumnName + " FROM " + selectedView;
String aValCondition = "";
aValCondition = aColumnName + " like '%" + query + "%'";
String aValOrderBy = aColumnName;
ArrayList<HashMap<String, Object>> aRows = ConnectionPool.getRowsFromSelectQuery(aSQL, aValCondition, false, "", aValOrderBy);
// Building suggestion list from the rows,
// TODO there should be 2 Rows set,
// origRows : original with all Rows, which should be kept
// filteredRows : only the Rows which are left after matching 'contains' of written query from the user
if (aRows != null) {
for (int j = 0; j < (aRows.size() - 1); j++) {
// System.out.println(j);
if (aRows.get(j).get(aColumnName) != null) {
results.add(Objects.toString(aRows.get(j).get(aColumnName).toString(), ""));
}
}
}
// Returning suggestions
return results;
}
--------------------------------------------
WISH :
As is written in CompleteMethod first comment, the aim is to use the same CompleteMethod for EVERY Autocomplete component... So to be able to differentiate the calling component inside the CompleteMethod !
Here is what both, the building of the ValueMethod & the CompleteMethod should look like :
1. Building ValueMethod :
Code: Select all
// old --> cAutoComplete.setCompleteMethod(utils.createMethodExpression("#{dtColumnsQuery.completeValue}", null, String.class));
cAutoComplete.setCompleteMethod(utils.createMethodExpression("#{dtColumnsQuery.completeValue}", null, String.class, AjaxBehaviorEvent.class));
Code: Select all
// old --> public List<String> completeValue(String query){...
public List<String> completeValue(String query, AjaxBehaviorEvent e){...
--------------------------------------------SEVERE: javax.el.MethodNotFoundException: Method not found: com.data.datatable.ColumnsQuery@40a64a3d.completeValue(java.lang.String, javax.faces.event.AjaxBehaviorEvent)
INVESTIGATIONS :
I looked in AutoComplete source code and found out that the CompleteMethod was fired with only one parameter... the query entered :
Code: Select all
public void broadcast(javax.faces.event.FacesEvent event) throws javax.faces.event.AbortProcessingException {
super.broadcast(event);
FacesContext facesContext = getFacesContext();
MethodExpression me = getCompleteMethod();
if(me != null && event instanceof org.primefaces.event.AutoCompleteEvent) {
suggestions = (List) me.invoke(facesContext.getELContext(), new Object[] {[b]((org.primefaces.event.AutoCompleteEvent) event).getQuery()[/b]});
if(suggestions == null) {
suggestions = new ArrayList();
}
facesContext.renderResponse();
}
}
QUESTION :
Am I wrong and there is a way to directly find the contextual AutoComplete component which has fired the CompleteMethod ?
(With or without changing the signature of the method it's self...)
--------------------------------------------
WORKAROUND :
I, of course, could use a 'onFocus' event and set a variable with which AutoComplete was entered... but this is a workaround I will use for now, not a proper solution.
Of course, ------------> Thank you in advance for any help !!!!